Major revampage to support composited actions that create images that are

exactly big enough to accomodate all of their trimmed components and no
bigger.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1501 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2002-06-19 23:31:57 +00:00
parent 330767e193
commit 0ddf11ab57
6 changed files with 206 additions and 65 deletions
@@ -1,10 +1,13 @@
//
// $Id: CompositedActionFrames.java,v 1.4 2002/05/15 23:54:04 mdb Exp $
// $Id: CompositedActionFrames.java,v 1.5 2002/06/19 23:31:57 mdb Exp $
package com.threerings.cast;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import com.samskivert.util.StringUtil;
import com.threerings.media.sprite.MultiFrameImage;
import com.threerings.media.util.Colorization;
@@ -27,50 +30,70 @@ public class CompositedActionFrames
public CompositedActionFrames (ActionFrames[] sources)
{
_sources = sources;
// the sources must all have the same frame count, so we just use
// the count from the first one
// the sources must all have the same frame count, and each
// orientation must also have the same frame count, so we just use
// the count from the first source and first orientation
_frameCount = _sources[0].getFrames(NORTH).getFrameCount();
_images = new Image[DIRECTION_COUNT][_frameCount];
_bounds = new Rectangle[DIRECTION_COUNT][_frameCount];
}
// documentation inherited from interface
public MultiFrameImage getFrames (final int orient)
public TrimmedMultiFrameImage getFrames (final int orient)
{
return new MultiFrameImage() {
return new TrimmedMultiFrameImage() {
// documentation inherited
public int getFrameCount ()
{
return _proto.getFrameCount();
public int getFrameCount () {
return _frameCount;
}
// documentation inherited from interface
public int getWidth (int index)
{
return _proto.getWidth(index);
public int getWidth (int index) {
// composite the frame if necessary
if (_bounds[orient][index] == null) {
getFrame(orient, index);
}
return _bounds[orient][index].width;
}
// documentation inherited from interface
public int getHeight (int index)
{
return _proto.getHeight(index);
public int getHeight (int index) {
// composite the frame if necessary
if (_bounds[orient][index] == null) {
getFrame(orient, index);
}
return _bounds[orient][index].height;
}
// documentation inherited from interface
public void paintFrame (Graphics g, int index, int x, int y)
{
public void paintFrame (Graphics g, int index, int x, int y) {
g.drawImage(getFrame(orient, index), x, y, null);
}
// 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);
}
protected MultiFrameImage _proto = _sources[0].getFrames(orient);
// documentation inherited from interface
public void getTrimmedBounds (int index, Rectangle bounds) {
bounds.setBounds(0, 0, getWidth(index), getHeight(index));
}
};
}
// documentation inherited from interface
public int getXOrigin (int orient, int frameIdx)
{
return _bounds[orient][frameIdx].x;
}
// documentation inherited from interface
public int getYOrigin (int orient, int frameIdx)
{
return _bounds[orient][frameIdx].y;
}
// documentation inherited from interface
public ActionFrames cloneColorized (Colorization[] zations)
{
@@ -80,15 +103,19 @@ public class CompositedActionFrames
// documentation inherited
protected Image getFrame (int orient, int index)
{
// create the frame if we don't already have it
// 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
if (_images[orient][index] == null) {
// Log.info("Compositing [orient=" + orient +
// ", index=" + index + "].");
_images[orient][index] = compositeFrames(orient, index);
}
return _images[orient][index];
}
@@ -101,22 +128,45 @@ public class CompositedActionFrames
*/
protected Image compositeFrames (int orient, int index)
{
Image dest = null;
Graphics g = null;
int scount = _sources.length;
// long start = System.currentTimeMillis();
for (int ii = 0; ii < _sources.length; ii++) {
MultiFrameImage source = _sources[ii].getFrames(orient);
// create the image now that we know how big it should be
if (dest == null) {
dest = ImageUtil.createImage(source.getWidth(index),
source.getHeight(index));
g = dest.getGraphics();
// // DEBUG
// int width = 0, height = 0;
// first we need to determine the bounds of the rectangle that
// will enclose all of our various components
Rectangle tbounds = new Rectangle();
Rectangle bounds = _bounds[orient][index] = new Rectangle(0, 0, 0, 0);
for (int ii = 0; ii < scount; ii++) {
TrimmedMultiFrameImage source = _sources[ii].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);
}
// render the particular action from this component into the
// target image
source.paintFrame(g, index, 0, 0);
// // DEBUG
// for (int ff = 0; ff < _frameCount; ff++) {
// width = Math.max(width, source.getWidth(ff));
// height = Math.max(height, source.getHeight(ff));
// }
}
// create the image now that we know how big it should be
Image dest = ImageUtil.createImage(bounds.width, bounds.height);
Graphics g = dest.getGraphics();
// now render each of the components into a composited frame
for (int ii = 0; ii < scount; ii++) {
TrimmedMultiFrameImage source = _sources[ii].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
@@ -124,6 +174,16 @@ public class CompositedActionFrames
g.dispose();
}
// Log.info("Composited [orient=" + orient + ", index=" + index +
// ", tbounds=" + StringUtil.toString(bounds) +
// ", width=" + width + ", height=" + height + "].");
// keep track of our new origin
bounds.x = (_sources[0].getXOrigin(orient, index) - bounds.x);
bounds.y = (_sources[0].getYOrigin(orient, index) - bounds.y);
// Log.info("New origin [x=" + bounds.x + ", y=" + bounds.y + "].");
// long now = System.currentTimeMillis();
// Log.info("Composited " + sources.length + " frames in " +
// (now-start) + " millis.");
@@ -139,4 +199,7 @@ public class CompositedActionFrames
/** The frame images. */
protected Image[][] _images;
/** Used to track our trimmed frame bounds. */
protected Rectangle[][] _bounds;
}