Revamped to support new media architecture. Added tunability to in-memory
action cache. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2118 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,17 +1,19 @@
|
|||||||
//
|
//
|
||||||
// $Id: CharacterManager.java,v 1.29 2003/01/08 04:09:02 mdb Exp $
|
// $Id: CharacterManager.java,v 1.30 2003/01/13 22:53:04 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cast;
|
package com.threerings.cast;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import com.samskivert.util.ConfigUtil;
|
||||||
import com.samskivert.util.LRUHashMap;
|
import com.samskivert.util.LRUHashMap;
|
||||||
import com.samskivert.util.StringUtil;
|
import com.samskivert.util.StringUtil;
|
||||||
import com.samskivert.util.Throttle;
|
import com.samskivert.util.Throttle;
|
||||||
import com.samskivert.util.Tuple;
|
import com.samskivert.util.Tuple;
|
||||||
|
|
||||||
import com.threerings.media.image.Colorization;
|
import com.threerings.media.image.Colorization;
|
||||||
|
import com.threerings.media.image.ImageManager;
|
||||||
import com.threerings.util.DirectionCodes;
|
import com.threerings.util.DirectionCodes;
|
||||||
|
|
||||||
import com.threerings.cast.CompositedActionFrames.ComponentFrames;
|
import com.threerings.cast.CompositedActionFrames.ComponentFrames;
|
||||||
@@ -28,9 +30,10 @@ public class CharacterManager
|
|||||||
/**
|
/**
|
||||||
* Constructs the character manager.
|
* Constructs the character manager.
|
||||||
*/
|
*/
|
||||||
public CharacterManager (ComponentRepository crepo)
|
public CharacterManager (ImageManager imgr, ComponentRepository crepo)
|
||||||
{
|
{
|
||||||
// keep this around
|
// keep these around
|
||||||
|
_imgr = imgr;
|
||||||
_crepo = crepo;
|
_crepo = crepo;
|
||||||
|
|
||||||
// populate our actions table
|
// populate our actions table
|
||||||
@@ -40,8 +43,12 @@ public class CharacterManager
|
|||||||
_actions.put(action.name, action);
|
_actions.put(action.name, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// create our in-memory action cache
|
||||||
_frames.setTracking(true);
|
int acsize = ConfigUtil.getSystemProperty(
|
||||||
|
"narya.cast.action_cache_size", DEFAULT_ACTION_CACHE_SIZE);
|
||||||
|
Log.debug("Creating action cache [size=" + acsize + "].");
|
||||||
|
_frames = new LRUHashMap(acsize);
|
||||||
|
_frames.setTracking(true); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -247,9 +254,12 @@ public class CharacterManager
|
|||||||
|
|
||||||
// use those to create an entity that will lazily composite things
|
// use those to create an entity that will lazily composite things
|
||||||
// together as they are needed
|
// together as they are needed
|
||||||
return new CompositedActionFrames(action, sources);
|
return new CompositedActionFrames(_imgr, action, sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The image manager with whom we interact. */
|
||||||
|
protected ImageManager _imgr;
|
||||||
|
|
||||||
/** The component repository. */
|
/** The component repository. */
|
||||||
protected ComponentRepository _crepo;
|
protected ComponentRepository _crepo;
|
||||||
|
|
||||||
@@ -257,7 +267,7 @@ public class CharacterManager
|
|||||||
protected HashMap _actions = new HashMap();
|
protected HashMap _actions = new HashMap();
|
||||||
|
|
||||||
/** A cache of composited animation frames. */
|
/** A cache of composited animation frames. */
|
||||||
protected LRUHashMap _frames = new LRUHashMap(ACTION_CACHE_SIZE);
|
protected LRUHashMap _frames;
|
||||||
|
|
||||||
/** The character class to be created. */
|
/** The character class to be created. */
|
||||||
protected Class _charClass = CharacterSprite.class;
|
protected Class _charClass = CharacterSprite.class;
|
||||||
@@ -270,5 +280,5 @@ public class CharacterManager
|
|||||||
|
|
||||||
/** The number of actions to cache before we start clearing them
|
/** The number of actions to cache before we start clearing them
|
||||||
* out. */
|
* out. */
|
||||||
protected static final int ACTION_CACHE_SIZE = 30;
|
protected static final int DEFAULT_ACTION_CACHE_SIZE = 30;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: CharacterSprite.java,v 1.38 2002/12/04 02:45:08 shaper Exp $
|
// $Id: CharacterSprite.java,v 1.39 2003/01/13 22:53:04 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cast;
|
package com.threerings.cast;
|
||||||
|
|
||||||
@@ -47,14 +47,18 @@ public class CharacterSprite extends ImageSprite
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconfigures this sprite to use the specified character descriptor.
|
* Reconfigures this sprite to use the specified character descriptor.
|
||||||
|
*
|
||||||
|
* @param lazy if true, wait to recomposite our action sequence until
|
||||||
|
* our next tick, otherwise we recomposite immediately.
|
||||||
*/
|
*/
|
||||||
public void setCharacterDescriptor (CharacterDescriptor descrip)
|
public void setCharacterDescriptor (CharacterDescriptor descrip,
|
||||||
|
boolean lazy)
|
||||||
{
|
{
|
||||||
// keep the new descriptor
|
// keep the new descriptor
|
||||||
_descrip = descrip;
|
_descrip = descrip;
|
||||||
|
|
||||||
// reset our action which will reload our frames
|
// reset our action which will reload our frames
|
||||||
setActionSequence(_action);
|
setActionSequence(_action, lazy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,8 +102,11 @@ public class CharacterSprite extends ImageSprite
|
|||||||
/**
|
/**
|
||||||
* Sets the action sequence used when rendering the character, from
|
* Sets the action sequence used when rendering the character, from
|
||||||
* the set of available sequences.
|
* the set of available sequences.
|
||||||
|
*
|
||||||
|
* @param lazy if true, wait to recomposite our action sequence until
|
||||||
|
* our next tick, otherwise we recomposite immediately.
|
||||||
*/
|
*/
|
||||||
public void setActionSequence (String action)
|
public void setActionSequence (String action, boolean lazy)
|
||||||
{
|
{
|
||||||
// keep track of our current action in case someone swaps out our
|
// keep track of our current action in case someone swaps out our
|
||||||
// character description
|
// character description
|
||||||
@@ -117,9 +124,14 @@ public class CharacterSprite extends ImageSprite
|
|||||||
// obtain our animation frames for this action sequence
|
// obtain our animation frames for this action sequence
|
||||||
_aframes = _charmgr.getActionFrames(_descrip, action);
|
_aframes = _charmgr.getActionFrames(_descrip, action);
|
||||||
|
|
||||||
|
// grab our frames, or not
|
||||||
|
_frames = null;
|
||||||
|
if (!lazy) {
|
||||||
|
compositeActionFrames();
|
||||||
|
}
|
||||||
|
|
||||||
// update the sprite render attributes
|
// update the sprite render attributes
|
||||||
setFrameRate(actseq.framesPerSecond);
|
setFrameRate(actseq.framesPerSecond);
|
||||||
setFrames(_aframes.getFrames(_orient));
|
|
||||||
|
|
||||||
} catch (NoSuchComponentException nsce) {
|
} catch (NoSuchComponentException nsce) {
|
||||||
Log.warning("Character sprite references non-existent " +
|
Log.warning("Character sprite references non-existent " +
|
||||||
@@ -130,23 +142,23 @@ public class CharacterSprite extends ImageSprite
|
|||||||
// documentation inherited
|
// documentation inherited
|
||||||
public void setOrientation (int orient)
|
public void setOrientation (int orient)
|
||||||
{
|
{
|
||||||
super.setOrientation(orient);
|
setOrientation(orient, false);
|
||||||
|
|
||||||
// update the sprite frames to reflect the direction
|
|
||||||
if (_aframes != null) {
|
|
||||||
setFrames(_aframes.getFrames(orient));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// // documentation inherited
|
/**
|
||||||
// public void paint (Graphics2D gfx)
|
* Sets our orientation without recompositing our action sequence.
|
||||||
// {
|
*
|
||||||
// // DEBUG: draw our origin
|
* @param lazy if true, wait to recomposite our action sequence until
|
||||||
// gfx.setColor(java.awt.Color.white);
|
* our next tick, otherwise we recomposite immediately.
|
||||||
// gfx.drawOval(_x - 3, _y - 3, 6, 6);
|
*/
|
||||||
|
public void setOrientation (int orient, boolean lazy)
|
||||||
// super.paint(gfx);
|
{
|
||||||
// }
|
super.setOrientation(orient);
|
||||||
|
_frames = null;
|
||||||
|
if (!lazy) {
|
||||||
|
compositeActionFrames();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public boolean hitTest (int x, int y)
|
public boolean hitTest (int x, int y)
|
||||||
@@ -156,6 +168,15 @@ public class CharacterSprite extends ImageSprite
|
|||||||
_frames.hitTest(_frameIdx, x - _ibounds.x, y - _ibounds.y));
|
_frames.hitTest(_frameIdx, x - _ibounds.x, y - _ibounds.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void tick (long tickStamp)
|
||||||
|
{
|
||||||
|
super.tick(tickStamp);
|
||||||
|
|
||||||
|
// attempt to composite our action frames if necessary
|
||||||
|
compositeActionFrames();
|
||||||
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public void paint (Graphics2D gfx)
|
public void paint (Graphics2D gfx)
|
||||||
{
|
{
|
||||||
@@ -171,6 +192,18 @@ public class CharacterSprite extends ImageSprite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains our composited action frames and configures the sprite with
|
||||||
|
* their frames. This is called lazily after we have been instructed
|
||||||
|
* to use a new action.
|
||||||
|
*/
|
||||||
|
protected void compositeActionFrames ()
|
||||||
|
{
|
||||||
|
if (_frames == null) {
|
||||||
|
setFrames(_aframes.getFrames(_orient));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to paint any decorations that should appear behind the
|
* Called to paint any decorations that should appear behind the
|
||||||
* character sprite image.
|
* character sprite image.
|
||||||
@@ -253,7 +286,7 @@ public class CharacterSprite extends ImageSprite
|
|||||||
super.pathBeginning();
|
super.pathBeginning();
|
||||||
|
|
||||||
// enable walking animation
|
// enable walking animation
|
||||||
setActionSequence(getFollowingPathAction());
|
setActionSequence(getFollowingPathAction(), false);
|
||||||
setAnimationMode(TIME_BASED);
|
setAnimationMode(TIME_BASED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +310,7 @@ public class CharacterSprite extends ImageSprite
|
|||||||
// come to a halt looking settled and at peace
|
// come to a halt looking settled and at peace
|
||||||
String rest = getRestingAction();
|
String rest = getRestingAction();
|
||||||
if (rest != null) {
|
if (rest != null) {
|
||||||
setActionSequence(rest);
|
setActionSequence(rest, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
//
|
//
|
||||||
// $Id: CompositedActionFrames.java,v 1.11 2003/01/08 04:09:02 mdb Exp $
|
// $Id: CompositedActionFrames.java,v 1.12 2003/01/13 22:53:04 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cast;
|
package com.threerings.cast;
|
||||||
|
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -12,7 +13,9 @@ import java.util.Comparator;
|
|||||||
import com.samskivert.util.StringUtil;
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
import com.threerings.media.image.Colorization;
|
import com.threerings.media.image.Colorization;
|
||||||
import com.threerings.media.image.ImageUtil;
|
import com.threerings.media.image.ImageManager;
|
||||||
|
import com.threerings.media.image.Mirage;
|
||||||
|
import com.threerings.media.image.VolatileMirage;
|
||||||
import com.threerings.media.util.MultiFrameImage;
|
import com.threerings.media.util.MultiFrameImage;
|
||||||
|
|
||||||
import com.threerings.cast.CharacterComponent;
|
import com.threerings.cast.CharacterComponent;
|
||||||
@@ -23,7 +26,7 @@ import com.threerings.util.DirectionCodes;
|
|||||||
* to lazily create composited character frames when they are requested.
|
* to lazily create composited character frames when they are requested.
|
||||||
*/
|
*/
|
||||||
public class CompositedActionFrames
|
public class CompositedActionFrames
|
||||||
implements ActionFrames, DirectionCodes, Comparator
|
implements ActionFrames, DirectionCodes
|
||||||
{
|
{
|
||||||
/** Used to associate a {@link CharacterComponent} with its {@link
|
/** Used to associate a {@link CharacterComponent} with its {@link
|
||||||
* ActionFrames} for a particular action. */
|
* ActionFrames} for a particular action. */
|
||||||
@@ -43,7 +46,8 @@ public class CompositedActionFrames
|
|||||||
* source frames and colorization configuration. The actual component
|
* source frames and colorization configuration. The actual component
|
||||||
* frame images will not be composited until they are requested.
|
* frame images will not be composited until they are requested.
|
||||||
*/
|
*/
|
||||||
public CompositedActionFrames (String action, ComponentFrames[] sources)
|
public CompositedActionFrames (ImageManager imgr, String action,
|
||||||
|
ComponentFrames[] sources)
|
||||||
{
|
{
|
||||||
// sanity check
|
// sanity check
|
||||||
if (sources == null || sources.length == 0) {
|
if (sources == null || sources.length == 0) {
|
||||||
@@ -51,6 +55,7 @@ public class CompositedActionFrames
|
|||||||
"frames! [sources=" + StringUtil.toString(sources) + "].";
|
"frames! [sources=" + StringUtil.toString(sources) + "].";
|
||||||
throw new RuntimeException(errmsg);
|
throw new RuntimeException(errmsg);
|
||||||
}
|
}
|
||||||
|
_imgr = imgr;
|
||||||
_sources = sources;
|
_sources = sources;
|
||||||
_action = action;
|
_action = action;
|
||||||
|
|
||||||
@@ -59,8 +64,7 @@ public class CompositedActionFrames
|
|||||||
// the counts from the first source and orientation
|
// the counts from the first source and orientation
|
||||||
_orientCount = _sources[0].frames.getOrientationCount();
|
_orientCount = _sources[0].frames.getOrientationCount();
|
||||||
_frameCount = _sources[0].frames.getFrames(NORTH).getFrameCount();
|
_frameCount = _sources[0].frames.getFrames(NORTH).getFrameCount();
|
||||||
_images = new Image[_orientCount][_frameCount];
|
_images = new CompositedMirage[_orientCount][_frameCount];
|
||||||
_bounds = new Rectangle[_orientCount][_frameCount];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
@@ -81,29 +85,29 @@ public class CompositedActionFrames
|
|||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public int getWidth (int index) {
|
public int getWidth (int index) {
|
||||||
// composite the frame if necessary
|
// composite the frame if necessary
|
||||||
if (_bounds[orient][index] == null) {
|
if (_images[orient][index] == null) {
|
||||||
getFrame(orient, index);
|
getFrame(orient, index);
|
||||||
}
|
}
|
||||||
return _bounds[orient][index].width;
|
return _images[orient][index].getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public int getHeight (int index) {
|
public int getHeight (int index) {
|
||||||
// composite the frame if necessary
|
// composite the frame if necessary
|
||||||
if (_bounds[orient][index] == null) {
|
if (_images[orient][index] == null) {
|
||||||
getFrame(orient, index);
|
getFrame(orient, index);
|
||||||
}
|
}
|
||||||
return _bounds[orient][index].height;
|
return _images[orient][index].getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public void paintFrame (Graphics g, int index, int x, int y) {
|
public void paintFrame (Graphics2D g, int index, int x, int y) {
|
||||||
g.drawImage(getFrame(orient, index), x, y, null);
|
getFrame(orient, index).paint(g, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public boolean hitTest (int index, int x, int y) {
|
public boolean hitTest (int index, int x, int y) {
|
||||||
return ImageUtil.hitTest(getFrame(orient, index), x, y);
|
return getFrame(orient, index).hitTest(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
@@ -116,13 +120,13 @@ public class CompositedActionFrames
|
|||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public int getXOrigin (int orient, int frameIdx)
|
public int getXOrigin (int orient, int frameIdx)
|
||||||
{
|
{
|
||||||
return _bounds[orient][frameIdx].x;
|
return _images[orient][frameIdx].getXOrigin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public int getYOrigin (int orient, int frameIdx)
|
public int getYOrigin (int orient, int frameIdx)
|
||||||
{
|
{
|
||||||
return _bounds[orient][frameIdx].y;
|
return _images[orient][frameIdx].getYOrigin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
@@ -137,120 +141,135 @@ public class CompositedActionFrames
|
|||||||
long size = 0;
|
long size = 0;
|
||||||
for (int orient = 0; orient < _orientCount; orient++) {
|
for (int orient = 0; orient < _orientCount; orient++) {
|
||||||
for (int ii = 0; ii < _images[orient].length; ii++) {
|
for (int ii = 0; ii < _images[orient].length; ii++) {
|
||||||
Image image = _images[orient][ii];
|
Mirage mirage = _images[orient][ii];
|
||||||
if (image != null) {
|
if (mirage == null) {
|
||||||
size += ImageUtil.getEstimatedMemoryUsage(image);
|
continue;
|
||||||
}
|
}
|
||||||
|
// TODO: do the right thing here
|
||||||
|
size += (mirage.getWidth() * mirage.getHeight() * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
|
||||||
public int compare (Object o1, Object o2)
|
|
||||||
{
|
|
||||||
ComponentFrames cf1 = (ComponentFrames)o1, cf2 = (ComponentFrames)o2;
|
|
||||||
return (cf1.ccomp.componentClass.getRenderPriority(_action, _sorient) -
|
|
||||||
cf2.ccomp.componentClass.getRenderPriority(_action, _sorient));
|
|
||||||
}
|
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
protected Image getFrame (int orient, int index)
|
protected Mirage getFrame (int orient, int index)
|
||||||
{
|
{
|
||||||
// create the arrays for this orientation if we haven't yet
|
|
||||||
if (_images[orient] == null) {
|
|
||||||
_images[orient] = new Image[_frameCount];
|
|
||||||
_bounds[orient] = new Rectangle[_frameCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the frame if we don't already have it
|
// create the frame if we don't already have it
|
||||||
if (_images[orient][index] == null) {
|
if (_images[orient][index] == null) {
|
||||||
// Log.info("Compositing [orient=" + orient +
|
// Log.info("Compositing [action=" + _action + ", orient=" + orient +
|
||||||
// ", index=" + index + "].");
|
// ", index=" + index + "].");
|
||||||
_images[orient][index] = compositeFrames(orient, index);
|
_images[orient][index] = new CompositedMirage(_imgr, orient, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _images[orient][index];
|
return _images[orient][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders and returns the <code>index</code>th image from each of the
|
* Used to create our mirage using the source action frame images.
|
||||||
* supplied source multi-frame images to a newly created buffered
|
|
||||||
* image. This is used to render a single frame of a composited
|
|
||||||
* character action, and accordingly, the source image array should be
|
|
||||||
* already sorted into the proper rendering order.
|
|
||||||
*/
|
*/
|
||||||
protected Image compositeFrames (int orient, int index)
|
protected class CompositedMirage extends VolatileMirage
|
||||||
|
implements Comparator
|
||||||
{
|
{
|
||||||
int scount = _sources.length;
|
public CompositedMirage (ImageManager imgr, int orient, int index)
|
||||||
// long start = System.currentTimeMillis();
|
{
|
||||||
|
super(imgr, new Rectangle(0, 0, 0, 0));
|
||||||
|
|
||||||
// // DEBUG
|
// keep these for later
|
||||||
// int width = 0, height = 0;
|
_orient = orient;
|
||||||
|
_index = index;
|
||||||
|
|
||||||
// sort the sources appropriately for this orientation
|
// first we need to determine the bounds of the rectangle that
|
||||||
_sorient = orient;
|
// will enclose all of our various components
|
||||||
Arrays.sort(_sources, this);
|
Rectangle tbounds = new Rectangle();
|
||||||
|
int scount = _sources.length;
|
||||||
|
for (int ii = 0; ii < scount; ii++) {
|
||||||
|
TrimmedMultiFrameImage source =
|
||||||
|
_sources[ii].frames.getFrames(orient);
|
||||||
|
source.getTrimmedBounds(index, tbounds);
|
||||||
|
|
||||||
// first we need to determine the bounds of the rectangle that
|
// the first one defines our initial bounds
|
||||||
// will enclose all of our various components
|
if (_bounds.width == 0 && _bounds.height == 0) {
|
||||||
Rectangle tbounds = new Rectangle();
|
_bounds.setBounds(tbounds);
|
||||||
Rectangle bounds = _bounds[orient][index] = new Rectangle(0, 0, 0, 0);
|
} else {
|
||||||
for (int ii = 0; ii < scount; ii++) {
|
_bounds.add(tbounds);
|
||||||
TrimmedMultiFrameImage source =
|
}
|
||||||
_sources[ii].frames.getFrames(orient);
|
|
||||||
source.getTrimmedBounds(index, tbounds);
|
|
||||||
// the first one defines our initial bounds
|
|
||||||
if (bounds.width == 0 && bounds.height == 0) {
|
|
||||||
bounds.setBounds(tbounds);
|
|
||||||
} else {
|
|
||||||
bounds.add(tbounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// // DEBUG
|
// compute our new origin
|
||||||
// for (int ff = 0; ff < _frameCount; ff++) {
|
_origin.x = (_sources[0].frames.getXOrigin(orient, index) -
|
||||||
// width = Math.max(width, source.getWidth(ff));
|
_bounds.x);
|
||||||
// height = Math.max(height, source.getHeight(ff));
|
_origin.y = (_sources[0].frames.getYOrigin(orient, index) -
|
||||||
// }
|
_bounds.y);
|
||||||
|
// Log.info("New origin [x=" + _origin.x + ", y=" + _origin.y + "].");
|
||||||
|
|
||||||
|
// render our volatile image for the first time
|
||||||
|
createVolatileImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the image now that we know how big it should be
|
public int getXOrigin ()
|
||||||
Image dest = ImageUtil.createImage(bounds.width, bounds.height);
|
{
|
||||||
Graphics g = dest.getGraphics();
|
return _origin.x;
|
||||||
|
|
||||||
// now render each of the components into a composited frame
|
|
||||||
for (int ii = 0; ii < scount; ii++) {
|
|
||||||
TrimmedMultiFrameImage source =
|
|
||||||
_sources[ii].frames.getFrames(orient);
|
|
||||||
source.getTrimmedBounds(index, tbounds);
|
|
||||||
|
|
||||||
// render this frame for this particular action for this
|
|
||||||
// component into the target image
|
|
||||||
source.paintFrame(g, index, -bounds.x, -bounds.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up after ourselves
|
public int getYOrigin ()
|
||||||
if (g != null) {
|
{
|
||||||
g.dispose();
|
return _origin.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log.info("Composited [orient=" + orient + ", index=" + index +
|
// documentation inherited from interface
|
||||||
// ", tbounds=" + StringUtil.toString(bounds) +
|
public int compare (Object o1, Object o2)
|
||||||
// ", width=" + width + ", height=" + height + "].");
|
{
|
||||||
|
ComponentFrames cf1 = (ComponentFrames)o1,
|
||||||
|
cf2 = (ComponentFrames)o2;
|
||||||
|
return (cf1.ccomp.componentClass.getRenderPriority(
|
||||||
|
_action, _sorient) -
|
||||||
|
cf2.ccomp.componentClass.getRenderPriority(
|
||||||
|
_action, _sorient));
|
||||||
|
}
|
||||||
|
|
||||||
// keep track of our new origin
|
// documentation inherited
|
||||||
bounds.x = (_sources[0].frames.getXOrigin(orient, index) - bounds.x);
|
protected void refreshVolatileImage ()
|
||||||
bounds.y = (_sources[0].frames.getYOrigin(orient, index) - bounds.y);
|
{
|
||||||
|
// long start = System.currentTimeMillis();
|
||||||
|
|
||||||
// Log.info("New origin [x=" + bounds.x + ", y=" + bounds.y + "].");
|
// sort the sources appropriately for this orientation
|
||||||
|
_sorient = _orient;
|
||||||
|
Arrays.sort(_sources, this);
|
||||||
|
|
||||||
// long now = System.currentTimeMillis();
|
// now render each of the components into a composited frame
|
||||||
// Log.info("Composited " + sources.length + " frames in " +
|
int scount = _sources.length;
|
||||||
// (now-start) + " millis.");
|
Graphics2D g = (Graphics2D)_image.getGraphics();
|
||||||
|
try {
|
||||||
|
for (int ii = 0; ii < scount; ii++) {
|
||||||
|
TrimmedMultiFrameImage source =
|
||||||
|
_sources[ii].frames.getFrames(_orient);
|
||||||
|
source.paintFrame(g, _index, -_bounds.x, -_bounds.y);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// clean up after ourselves
|
||||||
|
if (g != null) {
|
||||||
|
g.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dest;
|
// Log.info("Composited [orient=" + _orient + ", index=" + _index +
|
||||||
|
// ", tbounds=" + StringUtil.toString(_bounds) + "].");
|
||||||
|
|
||||||
|
// long now = System.currentTimeMillis();
|
||||||
|
// Log.info("Composited " + scount + " frames in " +
|
||||||
|
// (now-start) + " millis.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int _orient;
|
||||||
|
protected int _index;
|
||||||
|
protected Point _origin = new Point();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The image manager from whom we can obtain prepared volatile images
|
||||||
|
* onto which to render our composited actions. */
|
||||||
|
protected ImageManager _imgr;
|
||||||
|
|
||||||
/** The action for which we're compositing frames. */
|
/** The action for which we're compositing frames. */
|
||||||
protected String _action;
|
protected String _action;
|
||||||
|
|
||||||
@@ -267,8 +286,5 @@ public class CompositedActionFrames
|
|||||||
protected ComponentFrames[] _sources;
|
protected ComponentFrames[] _sources;
|
||||||
|
|
||||||
/** The frame images. */
|
/** The frame images. */
|
||||||
protected Image[][] _images;
|
protected CompositedMirage[][] _images;
|
||||||
|
|
||||||
/** Used to track our trimmed frame bounds. */
|
|
||||||
protected Rectangle[][] _bounds;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SpritePanel.java,v 1.14 2002/06/19 23:24:04 mdb Exp $
|
// $Id: SpritePanel.java,v 1.15 2003/01/13 22:53:04 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cast.builder;
|
package com.threerings.cast.builder;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ public class SpritePanel extends JPanel
|
|||||||
*/
|
*/
|
||||||
protected void setSprite (CharacterSprite sprite)
|
protected void setSprite (CharacterSprite sprite)
|
||||||
{
|
{
|
||||||
sprite.setActionSequence(StandardActions.STANDING);
|
sprite.setActionSequence(StandardActions.STANDING, false);
|
||||||
sprite.setOrientation(WEST);
|
sprite.setOrientation(WEST);
|
||||||
_sprite = sprite;
|
_sprite = sprite;
|
||||||
centerSprite();
|
centerSprite();
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//
|
//
|
||||||
// $Id: BundleUtil.java,v 1.3 2002/09/17 21:05:35 mdb Exp $
|
// $Id: BundleUtil.java,v 1.4 2003/01/13 22:53:04 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cast.bundle;
|
package com.threerings.cast.bundle;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InvalidClassException;
|
import java.io.InvalidClassException;
|
||||||
@@ -42,9 +43,10 @@ public class BundleUtil
|
|||||||
* Attempts to load an object from the supplied resource bundle with
|
* Attempts to load an object from the supplied resource bundle with
|
||||||
* the specified path.
|
* the specified path.
|
||||||
*
|
*
|
||||||
* @return the unserialized object in question or null if no
|
* @return the unserialized object in question.
|
||||||
* serialized object data was available at the specified path.
|
|
||||||
*
|
*
|
||||||
|
* @exception FileNotFoundException thrown if no object exists with
|
||||||
|
* the specified path.
|
||||||
* @exception IOException thrown if an I/O error occurs while reading
|
* @exception IOException thrown if an I/O error occurs while reading
|
||||||
* the object from the bundle.
|
* the object from the bundle.
|
||||||
*/
|
*/
|
||||||
@@ -54,7 +56,7 @@ public class BundleUtil
|
|||||||
try {
|
try {
|
||||||
InputStream bin = bundle.getResource(path);
|
InputStream bin = bundle.getResource(path);
|
||||||
if (bin == null) {
|
if (bin == null) {
|
||||||
return null;
|
throw new FileNotFoundException(path);
|
||||||
}
|
}
|
||||||
return new ObjectInputStream(bin).readObject();
|
return new ObjectInputStream(bin).readObject();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
//
|
//
|
||||||
// $Id: BundledComponentRepository.java,v 1.22 2003/01/08 04:09:02 mdb Exp $
|
// $Id: BundledComponentRepository.java,v 1.23 2003/01/13 22:53:04 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cast.bundle;
|
package com.threerings.cast.bundle;
|
||||||
|
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
@@ -17,6 +17,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import javax.imageio.stream.FileImageInputStream;
|
||||||
|
import javax.imageio.stream.ImageInputStream;
|
||||||
|
|
||||||
import com.samskivert.io.NestableIOException;
|
import com.samskivert.io.NestableIOException;
|
||||||
import com.samskivert.util.HashIntMap;
|
import com.samskivert.util.HashIntMap;
|
||||||
import com.samskivert.util.IntIntMap;
|
import com.samskivert.util.IntIntMap;
|
||||||
@@ -29,10 +32,12 @@ import com.threerings.resource.ResourceBundle;
|
|||||||
import com.threerings.resource.ResourceManager;
|
import com.threerings.resource.ResourceManager;
|
||||||
|
|
||||||
import com.threerings.media.image.Colorization;
|
import com.threerings.media.image.Colorization;
|
||||||
|
import com.threerings.media.image.ImageDataProvider;
|
||||||
import com.threerings.media.image.ImageManager;
|
import com.threerings.media.image.ImageManager;
|
||||||
import com.threerings.media.image.ImageUtil;
|
import com.threerings.media.image.ImageUtil;
|
||||||
|
import com.threerings.media.image.Mirage;
|
||||||
|
|
||||||
import com.threerings.media.tile.ImageProvider;
|
import com.threerings.media.tile.IMImageProvider;
|
||||||
import com.threerings.media.tile.NoSuchTileException;
|
import com.threerings.media.tile.NoSuchTileException;
|
||||||
import com.threerings.media.tile.Tile;
|
import com.threerings.media.tile.Tile;
|
||||||
import com.threerings.media.tile.TileSet;
|
import com.threerings.media.tile.TileSet;
|
||||||
@@ -104,14 +109,17 @@ public class BundledComponentRepository
|
|||||||
|
|
||||||
// now go back and load up all of the component information
|
// now go back and load up all of the component information
|
||||||
for (int i = 0; i < rbundles.length; i++) {
|
for (int i = 0; i < rbundles.length; i++) {
|
||||||
HashIntMap comps = (HashIntMap)BundleUtil.loadObject(
|
HashIntMap comps = null;
|
||||||
rbundles[i], BundleUtil.COMPONENTS_PATH);
|
try {
|
||||||
if (comps == null) {
|
comps = (HashIntMap)BundleUtil.loadObject(
|
||||||
|
rbundles[i], BundleUtil.COMPONENTS_PATH);
|
||||||
|
} catch (FileNotFoundException fnfe) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a frame provider for this bundle
|
// create a frame provider for this bundle
|
||||||
FrameProvider fprov = new ResourceBundleProvider(rbundles[i]);
|
FrameProvider fprov =
|
||||||
|
new ResourceBundleProvider(_imgr, rbundles[i]);
|
||||||
|
|
||||||
// now create character component instances for each component
|
// now create character component instances for each component
|
||||||
// in the serialized table
|
// in the serialized table
|
||||||
@@ -241,38 +249,30 @@ public class BundledComponentRepository
|
|||||||
* Instances of these provide images to our component action tilesets
|
* Instances of these provide images to our component action tilesets
|
||||||
* and frames to our components.
|
* and frames to our components.
|
||||||
*/
|
*/
|
||||||
protected class ResourceBundleProvider
|
protected class ResourceBundleProvider extends IMImageProvider
|
||||||
implements ImageProvider, FrameProvider
|
implements ImageDataProvider, FrameProvider
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructs an instance that will obtain image data from the
|
* Constructs an instance that will obtain image data from the
|
||||||
* specified resource bundle.
|
* specified resource bundle.
|
||||||
*/
|
*/
|
||||||
public ResourceBundleProvider (ResourceBundle bundle)
|
public ResourceBundleProvider (ImageManager imgr, ResourceBundle bundle)
|
||||||
{
|
{
|
||||||
|
super(imgr, (String)null);
|
||||||
|
_dprov = this;
|
||||||
_bundle = bundle;
|
_bundle = bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited from interface
|
||||||
public Image loadImage (String path)
|
public String getIdent ()
|
||||||
throws IOException
|
|
||||||
{
|
{
|
||||||
// obtain the image data from our resource bundle
|
return "bcr:" + _bundle.getSource();
|
||||||
InputStream imgin = null;
|
}
|
||||||
try {
|
|
||||||
imgin = _bundle.getResource(path);
|
|
||||||
if (imgin == null) {
|
|
||||||
String errmsg = "No such image in resource bundle " +
|
|
||||||
"[bundle=" + _bundle + ", path=" + path + "].";
|
|
||||||
throw new FileNotFoundException(errmsg);
|
|
||||||
}
|
|
||||||
return _imgr.loadImage(imgin);
|
|
||||||
|
|
||||||
} finally {
|
// documentation inherited from interface
|
||||||
if (imgin != null) {
|
public ImageInputStream loadImageData (String path) throws IOException
|
||||||
imgin.close();
|
{
|
||||||
}
|
return new FileImageInputStream(_bundle.getResourceFile(path));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
@@ -295,8 +295,9 @@ public class BundledComponentRepository
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
TileSet aset = null;
|
TileSet aset = null;
|
||||||
aset = (TileSet)BundleUtil.loadObject(_bundle, path);
|
try {
|
||||||
if (aset == null) {
|
aset = (TileSet)BundleUtil.loadObject(_bundle, path);
|
||||||
|
} catch (FileNotFoundException fnfe) {
|
||||||
Log.debug("Falling back to default [path=" + path + "].");
|
Log.debug("Falling back to default [path=" + path + "].");
|
||||||
// try loading the default tileset
|
// try loading the default tileset
|
||||||
path = root + ActionSequence.DEFAULT_SEQUENCE +
|
path = root + ActionSequence.DEFAULT_SEQUENCE +
|
||||||
@@ -375,7 +376,7 @@ public class BundledComponentRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public void paintFrame (Graphics g, int index, int x, int y)
|
public void paintFrame (Graphics2D g, int index, int x, int y)
|
||||||
{
|
{
|
||||||
Tile tile = getTile(orient, index);
|
Tile tile = getTile(orient, index);
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
@@ -395,8 +396,7 @@ public class BundledComponentRepository
|
|||||||
{
|
{
|
||||||
Tile tile = getTile(orient, index);
|
Tile tile = getTile(orient, index);
|
||||||
if (tile instanceof TrimmedTile) {
|
if (tile instanceof TrimmedTile) {
|
||||||
TrimmedTile ttile = (TrimmedTile)tile;
|
((TrimmedTile)tile).getTrimmedBounds(bounds);
|
||||||
bounds.setBounds(ttile.getTrimmedBounds());
|
|
||||||
} else {
|
} else {
|
||||||
bounds.setBounds(
|
bounds.setBounds(
|
||||||
0, 0, tile.getWidth(), tile.getHeight());
|
0, 0, tile.getWidth(), tile.getHeight());
|
||||||
@@ -420,8 +420,7 @@ public class BundledComponentRepository
|
|||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public ActionFrames cloneColorized (Colorization[] zations)
|
public ActionFrames cloneColorized (Colorization[] zations)
|
||||||
{
|
{
|
||||||
return new TileSetFrameImage(
|
return new TileSetFrameImage(_set.clone(zations), _actseq);
|
||||||
_set.cloneColorized(zations), _actseq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
//
|
//
|
||||||
// $Id: ComponentBundlerTask.java,v 1.17 2003/01/07 00:59:21 mdb Exp $
|
// $Id: ComponentBundlerTask.java,v 1.18 2003/01/13 22:53:04 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.cast.bundle.tools;
|
package com.threerings.cast.bundle.tools;
|
||||||
|
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
@@ -42,6 +44,7 @@ import org.apache.tools.ant.Task;
|
|||||||
import org.apache.tools.ant.types.FileSet;
|
import org.apache.tools.ant.types.FileSet;
|
||||||
|
|
||||||
import com.threerings.media.tile.ImageProvider;
|
import com.threerings.media.tile.ImageProvider;
|
||||||
|
import com.threerings.media.tile.SimpleCachingImageProvider;
|
||||||
import com.threerings.media.tile.TileSet;
|
import com.threerings.media.tile.TileSet;
|
||||||
import com.threerings.media.tile.TrimmedTileSet;
|
import com.threerings.media.tile.TrimmedTileSet;
|
||||||
import com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet;
|
import com.threerings.media.tile.tools.xml.SwissArmyTileSetRuleSet;
|
||||||
@@ -139,6 +142,14 @@ public class ComponentBundlerTask extends Task
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create an image provider for loading our component images
|
||||||
|
ImageProvider improv = new SimpleCachingImageProvider() {
|
||||||
|
protected BufferedImage loadImage (String path)
|
||||||
|
throws IOException {
|
||||||
|
return ImageIO.read(new File(path));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
System.out.println("Generating " + _target.getPath() + "...");
|
System.out.println("Generating " + _target.getPath() + "...");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -189,12 +200,7 @@ public class ComponentBundlerTask extends Task
|
|||||||
// tileset and stuff the new trimmed image into the
|
// tileset and stuff the new trimmed image into the
|
||||||
// jar file at the same time
|
// jar file at the same time
|
||||||
aset.setImagePath(cfile.getPath());
|
aset.setImagePath(cfile.getPath());
|
||||||
aset.setImageProvider(new ImageProvider() {
|
aset.setImageProvider(improv);
|
||||||
public Image loadImage (String path)
|
|
||||||
throws IOException {
|
|
||||||
return ImageIO.read(new File(path));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
TrimmedTileSet tset = null;
|
TrimmedTileSet tset = null;
|
||||||
try {
|
try {
|
||||||
@@ -205,8 +211,8 @@ public class ComponentBundlerTask extends Task
|
|||||||
"Failure trimming tileset " +
|
"Failure trimming tileset " +
|
||||||
"[class=" + info[0] + ", name=" + info[1] +
|
"[class=" + info[0] + ", name=" + info[1] +
|
||||||
", action=" + info[2] +
|
", action=" + info[2] +
|
||||||
", srcimg=" + aset.getImagePath() +
|
", srcimg=" + aset.getImagePath() + "].");
|
||||||
", error=" + t.getMessage() + "].");
|
t.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// then write our trimmed tileset to the jar file
|
// then write our trimmed tileset to the jar file
|
||||||
|
|||||||
Reference in New Issue
Block a user