diff --git a/src/java/com/threerings/cast/CharacterDescriptor.java b/src/java/com/threerings/cast/CharacterDescriptor.java index de3ab0d1f..2ed38836f 100644 --- a/src/java/com/threerings/cast/CharacterDescriptor.java +++ b/src/java/com/threerings/cast/CharacterDescriptor.java @@ -1,5 +1,5 @@ // -// $Id: CharacterDescriptor.java,v 1.4 2001/11/27 08:09:34 mdb Exp $ +// $Id: CharacterDescriptor.java,v 1.5 2002/03/08 07:50:32 mdb Exp $ package com.threerings.cast; @@ -13,11 +13,19 @@ import com.samskivert.util.StringUtil; public class CharacterDescriptor { /** - * Constructs the character descriptor. + * Constructs a character descriptor. + * + * @param components the component ids of the individual components + * that make up this character. + * @param zations the colorizations to apply to each of the character + * component images when compositing actions (an array of + * colorizations for each component). This can be null if image + * recolorization is not desired. */ - public CharacterDescriptor (int[] components) + public CharacterDescriptor (int[] components, Colorization[][] zations) { _components = components; + _zations = zations; } /** @@ -29,6 +37,16 @@ public class CharacterDescriptor return _components; } + /** + * Returns an array of colorization arrays to be applied to the + * components when compositing action images (one array per + * component). + */ + public Colorization[][] getColorizations () + { + return _zations; + } + /** * Compute a sensible hashcode for this object. */ @@ -46,12 +64,34 @@ public class CharacterDescriptor */ public boolean equals (Object other) { - if (other instanceof CharacterDescriptor) { - return Arrays.equals(_components, - ((CharacterDescriptor)other)._components); - } else { + if (!(other instanceof CharacterDescriptor)) { return false; } + + // both the component ids and the colorizations must be equal + CharacterDescriptor odesc = (CharacterDescriptor)other; + if (!Arrays.equals(_components, odesc._components)) { + return false; + } + + // if neither has colorizations, we're clear + Colorization[][] zations = odesc._zations; + if (zations == null && _zations == null) { + return true; + } + + // otherwise, all of the colorizations must be equal as well + int zlength = _zations.length; + if (zlength != zations.length) { + return false; + } + for (int i = 0; i < zlength; i++) { + if (!Arrays.equals(_zations[i], zations[i])) { + return false; + } + } + + return true; } /** @@ -59,9 +99,13 @@ public class CharacterDescriptor */ public String toString () { - return "[cids=" + StringUtil.toString(_components) + "]"; + return "[cids=" + StringUtil.toString(_components) + + ", colors=" + StringUtil.toString(_zations) + "]"; } /** The component identifiers comprising the character. */ protected int[] _components; + + /** The colorizations to apply when compositing this character. */ + protected Colorization[][] _zations; } diff --git a/src/java/com/threerings/cast/CharacterManager.java b/src/java/com/threerings/cast/CharacterManager.java index c4a152506..649946b3a 100644 --- a/src/java/com/threerings/cast/CharacterManager.java +++ b/src/java/com/threerings/cast/CharacterManager.java @@ -1,5 +1,5 @@ // -// $Id: CharacterManager.java,v 1.14 2002/02/10 00:05:36 shaper Exp $ +// $Id: CharacterManager.java,v 1.15 2002/03/08 07:50:32 mdb Exp $ package com.threerings.cast; @@ -178,25 +178,53 @@ public class CharacterManager { MultiFrameImage[] frames = new MultiFrameImage[Sprite.DIRECTION_COUNT]; - // obtain the necessary components int[] cids = descrip.getComponentIds(); int ccount = cids.length; - CharacterComponent[] components = new CharacterComponent[ccount]; + Colorization[][] zations = descrip.getColorizations(); + + // obtain the necessary components + ColorizedComponent[] components = new ColorizedComponent[ccount]; for (int i = 0; i < ccount; i++) { - components[i] = _crepo.getComponent(cids[i]); + ColorizedComponent cc = new ColorizedComponent(); + cc.component = _crepo.getComponent(cids[i]); + if (zations != null) { + cc.zations = zations[i]; + } + components[i] = cc; } // sort them into the proper rendering order - Arrays.sort(components, ComponentClass.RENDER_COMP); + Arrays.sort(components); - // now composite the component frames, one atop the next + // now composite the component frames, one atop the next; using + // the colorizations if we have them for (int i = 0; i < ccount; i++) { - TileUtil.compositeFrames(frames, components[i].getFrames(action)); + ColorizedComponent cc = components[i]; + TileUtil.compositeFrames( + frames, cc.component.getFrames(action), cc.zations); } return frames; } + /** Used when compositing component frame images. */ + protected static final class ColorizedComponent implements Comparable + { + /** The component to be colorized. */ + public CharacterComponent component; + + /** The colorizations to apply. */ + public Colorization[] zations; + + /** Sorts by render order. */ + public int compareTo (Object o) + { + ColorizedComponent co = (ColorizedComponent)o; + return (component.componentClass.renderPriority - + co.component.componentClass.renderPriority); + } + } + /** The component repository. */ protected ComponentRepository _crepo; diff --git a/src/java/com/threerings/cast/builder/SpritePanel.java b/src/java/com/threerings/cast/builder/SpritePanel.java index f3383804f..d04f12c5f 100644 --- a/src/java/com/threerings/cast/builder/SpritePanel.java +++ b/src/java/com/threerings/cast/builder/SpritePanel.java @@ -1,5 +1,5 @@ // -// $Id: SpritePanel.java,v 1.10 2002/01/11 16:17:33 shaper Exp $ +// $Id: SpritePanel.java,v 1.11 2002/03/08 07:50:32 mdb Exp $ package com.threerings.cast.builder; @@ -89,7 +89,7 @@ public class SpritePanel protected void generateSprite () { int components[] = _model.getSelectedComponents(); - CharacterDescriptor desc = new CharacterDescriptor(components); + CharacterDescriptor desc = new CharacterDescriptor(components, null); CharacterSprite sprite = _charmgr.getCharacter(desc); setSprite(sprite); } diff --git a/src/java/com/threerings/cast/util/TileUtil.java b/src/java/com/threerings/cast/util/TileUtil.java index 8bd3c7229..f6b862878 100644 --- a/src/java/com/threerings/cast/util/TileUtil.java +++ b/src/java/com/threerings/cast/util/TileUtil.java @@ -1,15 +1,17 @@ // -// $Id: TileUtil.java,v 1.8 2002/02/24 02:20:43 mdb Exp $ +// $Id: TileUtil.java,v 1.9 2002/03/08 07:50:32 mdb Exp $ package com.threerings.cast.util; import java.awt.Image; +import java.awt.image.BufferedImage; import com.threerings.media.sprite.MultiFrameImage; import com.threerings.media.sprite.Sprite; import com.threerings.media.util.ImageUtil; import com.threerings.cast.Log; +import com.threerings.cast.Colorization; /** * Miscellaneous tile-related utility functions. @@ -19,13 +21,16 @@ public class TileUtil /** * Renders each of the given src component frames into * the corresponding frames of dest, allocating blank - * image frames for dest if none yet exist. + * image frames for dest if none yet exist. If + * zations is not null, the provided list of + * colorizations will be applied as well. * * @throws IllegalArgumentException if the frame count of the source * and destination images don't match. */ public static void compositeFrames ( - MultiFrameImage[] dest, MultiFrameImage[] src) + MultiFrameImage[] dest, MultiFrameImage[] src, + Colorization[] zations) { for (int orient = 0; orient < Sprite.DIRECTION_COUNT; orient++) { MultiFrameImage sframes = src[orient]; @@ -48,7 +53,18 @@ public class TileUtil // slap the images together for (int ii = 0; ii < dsize; ii++) { Image dimg = dframes.getFrame(ii); - Image simg = sframes.getFrame(ii); + BufferedImage simg = (BufferedImage)sframes.getFrame(ii); + + // recolor the source image + if (zations != null) { + for (int i = 0; i < zations.length; i++) { + Colorization cz = zations[i]; + simg = ImageUtil.recolorImage( + simg, cz.rootColor, cz.range, cz.offsets); + } + } + + // now splat the recolored image onto the target dimg.getGraphics().drawImage(simg, 0, 0, null); } } diff --git a/src/java/com/threerings/media/image/Colorization.java b/src/java/com/threerings/media/image/Colorization.java new file mode 100644 index 000000000..62473e05a --- /dev/null +++ b/src/java/com/threerings/media/image/Colorization.java @@ -0,0 +1,58 @@ +// +// $Id: Colorization.java,v 1.1 2002/03/08 07:50:32 mdb Exp $ + +package com.threerings.cast; + +import java.awt.Color; + +/** + * Used to support colorization of character component images. + */ +public class Colorization +{ + /** Every colorization must have a unique name that can be used to + * compare a particular colorization record with another. */ + public String name; + + /** The root color for the colorization. */ + public Color rootColor; + + /** The range around the root color that will be colorized (in + * delta-hue, delta-saturation, delta-value. */ + public float[] range; + + /** The adjustments to make to hue, saturation and value. */ + public float[] offsets; + + /** + * Constructs a colorization record with the specified name. + */ + public Colorization (String name, Color rootColor, + float[] range, float[] offsets) + { + this.name = name; + this.rootColor = rootColor; + this.range = range; + this.offsets = offsets; + } + + /** + * Compares this colorization to another based on name. + */ + public boolean equals (Object other) + { + if (other instanceof Colorization) { + return ((Colorization)other).name.equals(name); + } else { + return false; + } + } + + /** + * Returns a string representation of this colorization. + */ + public String toString () + { + return name; + } +}