From e9211f8fd55a7507f9c11089c379cdadf706df0a Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Fri, 2 Nov 2001 15:28:20 +0000 Subject: [PATCH] Moved TileUtil to cast.util, added CastUtil to provide an easy way to get a random character descriptor for use until we have fancified storage of character descriptions. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@587 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../com/threerings/cast/CharacterManager.java | 7 +- .../tools/xml/XMLComponentRepository.java | 3 +- .../com/threerings/cast/util/CastUtil.java | 49 +++++ .../com/threerings/cast/util/TileUtil.java | 179 ++++++++++++++++++ .../miso/viewer/ViewerSceneViewPanel.java | 44 +---- 5 files changed, 240 insertions(+), 42 deletions(-) create mode 100644 src/java/com/threerings/cast/util/CastUtil.java create mode 100644 src/java/com/threerings/cast/util/TileUtil.java diff --git a/src/java/com/threerings/cast/CharacterManager.java b/src/java/com/threerings/cast/CharacterManager.java index 026fc5964..59fba17df 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.8 2001/11/02 01:10:28 shaper Exp $ +// $Id: CharacterManager.java,v 1.9 2001/11/02 15:28:20 shaper Exp $ package com.threerings.cast; @@ -7,11 +7,12 @@ import java.util.*; import com.samskivert.util.CollectionUtil; -import com.threerings.cast.Log; - import com.threerings.media.sprite.MultiFrameImage; import com.threerings.media.sprite.Sprite; +import com.threerings.cast.Log; +import com.threerings.cast.util.TileUtil; + /** * The character manager provides facilities for constructing sprites * that are used to represent characters in a scene. diff --git a/src/java/com/threerings/cast/tools/xml/XMLComponentRepository.java b/src/java/com/threerings/cast/tools/xml/XMLComponentRepository.java index fe8c67c01..72b69978b 100644 --- a/src/java/com/threerings/cast/tools/xml/XMLComponentRepository.java +++ b/src/java/com/threerings/cast/tools/xml/XMLComponentRepository.java @@ -1,5 +1,5 @@ // -// $Id: XMLComponentRepository.java,v 1.4 2001/11/02 02:52:16 shaper Exp $ +// $Id: XMLComponentRepository.java,v 1.5 2001/11/02 15:28:20 shaper Exp $ package com.threerings.miso.scene.xml; @@ -12,6 +12,7 @@ import com.samskivert.util.HashIntMap; import com.samskivert.util.Tuple; import com.threerings.cast.*; +import com.threerings.cast.util.TileUtil; import com.threerings.media.ImageManager; import com.threerings.media.tile.TileManager; diff --git a/src/java/com/threerings/cast/util/CastUtil.java b/src/java/com/threerings/cast/util/CastUtil.java new file mode 100644 index 000000000..e4b498463 --- /dev/null +++ b/src/java/com/threerings/cast/util/CastUtil.java @@ -0,0 +1,49 @@ +// +// $Id: CastUtil.java,v 1.1 2001/11/02 15:28:20 shaper Exp $ + +package com.threerings.cast.util; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.samskivert.util.CollectionUtil; + +import com.threerings.media.util.RandomUtil; + +import com.threerings.cast.*; + +/** + * Miscellaneous cast utility routines. + */ +public class CastUtil +{ + /** + * Returns a new character descriptor populated with a random set + * of components. + */ + public static CharacterDescriptor + getRandomDescriptor (CharacterManager charmgr) + { + // get all available classes + ArrayList classes = new ArrayList(); + CollectionUtil.addAll(classes, charmgr.enumerateComponentClasses()); + + // select the components + int size = classes.size(); + int components[] = new int[size]; + for (int ii = 0; ii < size; ii++) { + ComponentClass cclass = (ComponentClass)classes.get(ii); + + // get the components available for this class + ArrayList choices = new ArrayList(); + Iterator iter = charmgr.enumerateComponentsByClass(cclass.clid); + CollectionUtil.addAll(choices, iter); + + // choose a random component + int idx = RandomUtil.getInt(choices.size()); + components[cclass.clid] = ((Integer)choices.get(idx)).intValue(); + } + + return new CharacterDescriptor(components); + } +} diff --git a/src/java/com/threerings/cast/util/TileUtil.java b/src/java/com/threerings/cast/util/TileUtil.java new file mode 100644 index 000000000..3bd08dfb4 --- /dev/null +++ b/src/java/com/threerings/cast/util/TileUtil.java @@ -0,0 +1,179 @@ +// +// $Id: TileUtil.java,v 1.1 2001/11/02 15:28:20 shaper Exp $ + +package com.threerings.cast.util; + +import java.awt.Image; +import java.awt.image.BufferedImage; + +import com.threerings.media.sprite.*; +import com.threerings.media.tile.*; + +import com.threerings.cast.Log; +import com.threerings.cast.*; + +/** + * Miscellaneous tile-related utility functions. + */ +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. + */ + public static void compositeFrames ( + MultiFrameImage[][] dest, MultiFrameImage[][] src) + { + for (int ii = 0; ii < dest.length; ii++) { + for (int orient = 0; orient < Sprite.NUM_DIRECTIONS; orient++) { + // create blank destination frames if needed + if (dest[ii][orient] == null) { + dest[ii][orient] = createBlankFrames(src[ii][orient]); + } + + // slap the images together + compositeFrames(dest[ii][orient], src[ii][orient]); + } + } + } + + /** + * Returns a new {@link MultiFrameImage} that has empty images in + * all frames. The number of frames in the resulting multi frame + * image is the same as the frame count for src. + */ + public static MultiFrameImage createBlankFrames (MultiFrameImage src) + { + // TODO: for now, just use the first frame from the source to + // get the width and height for all of the blank frames. fix + // this hack soon. + Image img = src.getFrame(0); + int wid = img.getWidth(null), hei = img.getHeight(null); + return new BlankFrameImage(wid, hei, src.getFrameCount()); + } + + /** + * Returns a two-dimensional array of multi frame images + * containing the frames of animation used to render the sprite + * while standing or walking in each of the directions it may + * face. + */ + public static MultiFrameImage[][] getComponentFrames ( + String imagedir, CharacterComponent c) + { + ActionSequence seqs[] = c.getActionSequences(); + MultiFrameImage frames[][] = + new MultiFrameImage[seqs.length][Sprite.NUM_DIRECTIONS]; + + try { + for (int ii = 0; ii < seqs.length; ii++) { + ActionSequence as = seqs[ii]; + + // get the tile set containing the component tiles for + // this action sequence + String file = getImageFile(imagedir, as, c); + TileSet tset = null; + + try { + tset = as.tileset.clone(file); + } catch (CloneNotSupportedException e) { + Log.warning("Failed to clone tile set " + + "[tset=" + as.tileset + "]."); + return null; + } + + // get the number of frames of animation + int frameCount = tset.getNumTiles() / Sprite.NUM_DIRECTIONS; + + for (int dir = 0; dir < Sprite.NUM_DIRECTIONS; dir++) { + // retrieve all images for the sequence and direction + Image imgs[] = new Image[frameCount]; + for (int jj = 0; jj < frameCount; jj++) { + int idx = (dir * frameCount) + jj; + imgs[jj] = tset.getTile(idx).img; + } + + // create the multi frame image + frames[ii][dir] = new MultiFrameImageImpl(imgs); + } + } + + } catch (TileException te) { + Log.warning("Exception retrieving character images " + + "[te=" + te + "]."); + return null; + } + + return frames; + } + + /** + * Returns the file path for the given action sequence and component. + */ + protected static String getImageFile ( + String imagedir, ActionSequence as, CharacterComponent c) + { + return imagedir + as.fileid + "_" + c.getFileId() + IMAGE_SUFFIX; + } + + /** + * Renders each of the given src frames into the + * corresponding frames of dest. + */ + protected static void compositeFrames ( + MultiFrameImage dest, MultiFrameImage src) + { + int dsize = dest.getFrameCount(), ssize = src.getFrameCount(); + if (dsize != ssize) { + Log.warning( + "Can't composite images with differing frame counts " + + "[dest=" + dsize + ", src=" + ssize + "]."); + return; + } + + for (int ii = 0; ii < dsize; ii++) { + Image dimg = dest.getFrame(ii); + Image simg = src.getFrame(ii); + dimg.getGraphics().drawImage(simg, 0, 0, null); + } + } + + /** + * An implementation of the {@link MultiFrameImage} interface that + * initializes itself to contain a specified number of blank + * frames of the requested dimensions. + */ + protected static class BlankFrameImage implements MultiFrameImage + { + /** + * Constructs a blank frame image. + */ + public BlankFrameImage (int width, int height, int frameCount) + { + _imgs = new Image[frameCount]; + for (int ii = 0; ii < frameCount; ii++) { + _imgs[ii] = new BufferedImage( + width, height, BufferedImage.TYPE_INT_ARGB); + } + } + + // documentation inherited + public int getFrameCount () + { + return _imgs.length; + } + + // documentation inherited + public Image getFrame (int index) + { + return _imgs[index]; + } + + /** The frame images. */ + protected Image _imgs[]; + } + + /** The image file name suffix appended to component image file names. */ + protected static final String IMAGE_SUFFIX = ".png"; +} diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java b/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java index 75d81c0a5..b127a1592 100644 --- a/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java +++ b/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java @@ -1,19 +1,18 @@ // -// $Id: ViewerSceneViewPanel.java,v 1.28 2001/11/02 03:09:10 shaper Exp $ +// $Id: ViewerSceneViewPanel.java,v 1.29 2001/11/02 15:28:20 shaper Exp $ package com.threerings.miso.viewer; import java.awt.*; import java.awt.event.*; import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; import javax.swing.JPanel; -import com.samskivert.util.CollectionUtil; import com.samskivert.util.Config; -import com.threerings.cast.*; +import com.threerings.cast.CharacterDescriptor; +import com.threerings.cast.CharacterManager; +import com.threerings.cast.util.CastUtil; import com.threerings.media.ImageManager; import com.threerings.media.sprite.*; @@ -52,8 +51,8 @@ public class ViewerSceneViewPanel extends SceneViewPanel ctx.getConfig(), ctx.getImageManager()); // create the character descriptors - _descUser = createCharacterDescriptor(charmgr); - _descDecoy = createCharacterDescriptor(charmgr); + _descUser = CastUtil.getRandomDescriptor(charmgr); + _descDecoy = CastUtil.getRandomDescriptor(charmgr); // create the manipulable sprite _sprite = createSprite(spritemgr, charmgr, _descUser); @@ -186,37 +185,6 @@ public class ViewerSceneViewPanel extends SceneViewPanel } while (!createPath(s, x, y)); } - /** - * Returns a new {@link CharacterDescriptor} suitable for use in - * creating character sprites via {@link - * CharacterManager#getCharacter}. - */ - protected CharacterDescriptor - createCharacterDescriptor (CharacterManager charmgr) - { - // get all available classes - ArrayList classes = new ArrayList(); - CollectionUtil.addAll(classes, charmgr.enumerateComponentClasses()); - - // select the components - int size = classes.size(); - int components[] = new int[size]; - for (int ii = 0; ii < size; ii++) { - ComponentClass cclass = (ComponentClass)classes.get(ii); - - // get the components available for this class - ArrayList choices = new ArrayList(); - Iterator iter = charmgr.enumerateComponentsByClass(cclass.clid); - CollectionUtil.addAll(choices, iter); - - // choose a random component - int idx = RandomUtil.getInt(choices.size()); - components[cclass.clid] = ((Integer)choices.get(idx)).intValue(); - } - - return new CharacterDescriptor(components); - } - // documentation inherited public void handleEvent (SpriteEvent event) {