Miso scene revamp to more cleanly deal with object tiles and their
associated metrics. Also fixed render order handling such that any overlapping object tiles are rendered in the order that they are added to the scene. This gives us control over what to do in situations that are impossible to determine based on object footprint alone. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1708 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: DirtyItemList.java,v 1.12 2002/07/08 21:41:30 mdb Exp $
|
||||
// $Id: DirtyItemList.java,v 1.13 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene;
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.samskivert.util.StringUtil;
|
||||
import com.threerings.media.Log;
|
||||
import com.threerings.media.sprite.Sprite;
|
||||
import com.threerings.media.tile.ObjectTile;
|
||||
import com.threerings.miso.scene.util.IsoUtil;
|
||||
|
||||
/**
|
||||
* The dirty item list keeps track of dirty sprites and object tiles
|
||||
@@ -43,18 +44,14 @@ public class DirtyItemList
|
||||
* Appends the dirty object tile at the given coordinates to the dirty
|
||||
* item list.
|
||||
*
|
||||
* @param tile the object tile that is dirty.
|
||||
* @param bounds the bounds of this object tile.
|
||||
* @param scene the scene object that is dirty.
|
||||
* @param footprint the footprint of the object tile if it should be
|
||||
* rendered, null otherwise.
|
||||
* @param tx the object tile's x tile position.
|
||||
* @param ty the object tile's y tile position.
|
||||
*/
|
||||
public void appendDirtyObject (
|
||||
ObjectTile tile, Rectangle bounds, Shape footprint, int tx, int ty)
|
||||
public void appendDirtyObject (SceneObject scobj, Shape footprint)
|
||||
{
|
||||
DirtyItem item = getDirtyItem();
|
||||
item.init(tile, bounds, footprint, tx, ty);
|
||||
item.init(scobj, scobj.bounds, footprint, scobj.x, scobj.y);
|
||||
_items.add(item);
|
||||
}
|
||||
|
||||
@@ -237,8 +234,8 @@ public class DirtyItemList
|
||||
// rightmost tiles are equivalent
|
||||
lx = rx = ox;
|
||||
ly = ry = oy;
|
||||
if (obj instanceof ObjectTile) {
|
||||
ObjectTile tile = (ObjectTile)obj;
|
||||
if (obj instanceof SceneObject) {
|
||||
ObjectTile tile = ((SceneObject)obj).tile;
|
||||
lx -= (tile.getBaseWidth() - 1);
|
||||
ry -= (tile.getBaseHeight() - 1);
|
||||
}
|
||||
@@ -261,7 +258,7 @@ public class DirtyItemList
|
||||
if (obj instanceof Sprite) {
|
||||
((Sprite)obj).paint(gfx);
|
||||
} else {
|
||||
((ObjectTile)obj).paint(gfx, bounds.x, bounds.y);
|
||||
((SceneObject)obj).tile.paint(gfx, bounds.x, bounds.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,14 +283,19 @@ public class DirtyItemList
|
||||
|
||||
// sprites are equivalent if they're the same sprite
|
||||
DirtyItem b = (DirtyItem)other;
|
||||
if ((obj instanceof Sprite) && (b.obj instanceof Sprite)) {
|
||||
return (obj == b.obj);
|
||||
}
|
||||
return obj.equals(b.obj);
|
||||
// if ((obj instanceof Sprite) && (b.obj instanceof Sprite)) {
|
||||
// return (obj == b.obj);
|
||||
// }
|
||||
|
||||
// object-to-object or object-to-sprite are distinguished
|
||||
// simply by origin tile coordinate since they can never
|
||||
// occupy the same tile
|
||||
return (ox == b.ox && oy == b.oy);
|
||||
// // objects are equivalent if they are the same object
|
||||
// if ((obj instanceof SceneObject) && (b.obj instanceof SceneObject)) {
|
||||
// return (obj == b.obj);
|
||||
// }
|
||||
|
||||
// // object-to-sprite are distinguished simply by origin tile
|
||||
// // coordinate since they can never occupy the same tile
|
||||
// return (ox == b.ox && oy == b.oy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,9 +524,22 @@ public class DirtyItemList
|
||||
}
|
||||
}
|
||||
|
||||
// establish a consistent ordering between objects. see the
|
||||
// diagram at "narya/docs/miso/render_sort_diagram.png" for
|
||||
// more information.
|
||||
// if the two objects are scene objects and they overlap, we
|
||||
// compare them solely based on the order in which they were
|
||||
// added to the scene; this allows the scene creator to avoid
|
||||
// all sorts of sticky business wherein the render order
|
||||
// between two overlapping objects cannot be determined
|
||||
if ((da.obj instanceof SceneObject) &&
|
||||
(db.obj instanceof SceneObject)) {
|
||||
SceneObject soa = (SceneObject)da.obj;
|
||||
SceneObject sob = (SceneObject)db.obj;
|
||||
if (IsoUtil.objectFootprintsOverlap(soa, sob)) {
|
||||
return (soa.index - sob.index);
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise use a consistent ordering for non-overlappers;
|
||||
// see narya/docs/miso/render_sort_diagram.png for more info
|
||||
if (da.lx > db.ox) {
|
||||
return 1;
|
||||
} else if (da.ry > db.oy) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: DisplayMisoScene.java,v 1.5 2002/04/27 18:41:14 mdb Exp $
|
||||
// $Id: DisplayMisoScene.java,v 1.6 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene;
|
||||
|
||||
@@ -29,26 +29,29 @@ public interface DisplayMisoScene
|
||||
public Tile getFringeTile (int x, int y);
|
||||
|
||||
/**
|
||||
* Returns an iterator over all object tiles in this scene.
|
||||
* Returns the number of object tiles in the scene.
|
||||
*/
|
||||
public Iterator getObjectTiles ();
|
||||
public int getObjectCount ();
|
||||
|
||||
/**
|
||||
* Returns the object tile with the specified index.
|
||||
*/
|
||||
public ObjectTile getObjectTile (int index);
|
||||
|
||||
/**
|
||||
* Returns the tile coordinates for the specified object tile.
|
||||
*
|
||||
* @param tile the tile for which coordinates are to be fetched; this
|
||||
* tile must have been obtained from a call to {@link
|
||||
* #getObjectTiles}.
|
||||
* @param index the index of the object tile for which coordinates are
|
||||
* desired.
|
||||
*/
|
||||
public Point getObjectCoords (ObjectTile tile);
|
||||
public Point getObjectCoords (int index);
|
||||
|
||||
/**
|
||||
* Returns the action associated with the specified object tile. Null
|
||||
* is returned if the object tile does not have an associated action.
|
||||
*
|
||||
* @param tile the tile for which the action is to be fetched; this
|
||||
* tile must have been obtained from a call to {@link
|
||||
* #getObjectTiles}.
|
||||
* @param index the index of the object for which the action is
|
||||
* desired.
|
||||
*/
|
||||
public String getObjectAction (ObjectTile tile);
|
||||
public String getObjectAction (int index);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: DisplayMisoSceneImpl.java,v 1.59 2002/09/12 21:10:31 mdb Exp $
|
||||
// $Id: DisplayMisoSceneImpl.java,v 1.60 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene;
|
||||
|
||||
@@ -157,31 +157,32 @@ public class DisplayMisoSceneImpl
|
||||
* Called to expand each object read from the model into an actual
|
||||
* object tile instance with the appropriate additional data.
|
||||
*
|
||||
* @return the newly created object tile (which will have been put
|
||||
* into all the appropriate lists and tables).
|
||||
* @return the object info record for the newly created object tile
|
||||
* (which will have been put into all the appropriate lists and
|
||||
* tables).
|
||||
*/
|
||||
protected ObjectTile expandObject (
|
||||
protected ObjectInfo expandObject (
|
||||
int col, int row, int tsid, int tid, int fqTid, String action)
|
||||
throws NoSuchTileException, NoSuchTileSetException
|
||||
{
|
||||
// create the object tile and stick it in the list
|
||||
ObjectTile otile = (ObjectTile)_tmgr.getTile(tsid, tid);
|
||||
_objects.add(otile);
|
||||
_coords.put(otile, new Point(col, row));
|
||||
|
||||
// stick the action in the actions table if there is one
|
||||
// create and initialize an object info record for this object
|
||||
ObjectInfo oinfo = createObjectInfo();
|
||||
oinfo.object = (ObjectTile)_tmgr.getTile(tsid, tid);
|
||||
oinfo.coords = new Point(col, row);
|
||||
if (!StringUtil.blank(action)) {
|
||||
_actions.put(otile, action);
|
||||
oinfo.action = action;
|
||||
}
|
||||
|
||||
// generate a "shadow" for this object tile by toggling the
|
||||
// "covered" flag on in all base tiles below it (to prevent
|
||||
// sprites from walking on those tiles)
|
||||
setObjectTileFootprint(otile, col, row, true);
|
||||
setObjectTileFootprint(oinfo.object, col, row, true);
|
||||
|
||||
// return the object tile so that derived classes have easy access
|
||||
// to it
|
||||
return otile;
|
||||
// add the info record to the list
|
||||
_objects.add(oinfo);
|
||||
|
||||
// return the object info so that derived classes may access it
|
||||
return oinfo;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
@@ -197,21 +198,27 @@ public class DisplayMisoSceneImpl
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Iterator getObjectTiles ()
|
||||
public int getObjectCount ()
|
||||
{
|
||||
return _objects.iterator();
|
||||
return _objects.size();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Point getObjectCoords (ObjectTile tile)
|
||||
public ObjectTile getObjectTile (int index)
|
||||
{
|
||||
return (Point)_coords.get(tile);
|
||||
return ((ObjectInfo)_objects.get(index)).object;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public String getObjectAction (ObjectTile tile)
|
||||
public Point getObjectCoords (int index)
|
||||
{
|
||||
return (String)_actions.get(tile);
|
||||
return ((ObjectInfo)_objects.get(index)).coords;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public String getObjectAction (int index)
|
||||
{
|
||||
return ((ObjectInfo)_objects.get(index)).action;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,6 +232,33 @@ public class DisplayMisoSceneImpl
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an object info. This allows derived classes to extend the
|
||||
* object info record.
|
||||
*/
|
||||
protected ObjectInfo createObjectInfo ()
|
||||
{
|
||||
return new ObjectInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the object info record for the object tile at the specified
|
||||
* location. Two of the same kind of object tile cannot exist at the
|
||||
* same location.
|
||||
*/
|
||||
protected ObjectInfo getObjectInfo (ObjectTile tile, int x, int y)
|
||||
{
|
||||
int ocount = _objects.size();
|
||||
for (int ii = 0; ii < ocount; ii++) {
|
||||
ObjectInfo info = (ObjectInfo)_objects.get(ii);
|
||||
if (info.object == tile &&
|
||||
info.coords.x == x && info.coords.y == y) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the "covered" flag on all base tiles that are in the footprint
|
||||
* of the specified object tile.
|
||||
@@ -274,18 +308,21 @@ public class DisplayMisoSceneImpl
|
||||
/** The fringe layer of tiles. */
|
||||
protected TileLayer _fringe;
|
||||
|
||||
/** The object tiles. */
|
||||
/** The object info records. */
|
||||
protected ArrayList _objects = new ArrayList();
|
||||
|
||||
/** A map from object tile to coordinate records. */
|
||||
protected HashMap _coords = new HashMap();
|
||||
|
||||
/** A map from object tile to action string. */
|
||||
protected HashMap _actions = new HashMap();
|
||||
|
||||
/** The autofringer. */
|
||||
protected AutoFringer _fringer;
|
||||
|
||||
/** A random number generator for filling random base tiles and fringes. */
|
||||
protected Random _rando = new Random();
|
||||
|
||||
/** Used to report information on objects in this scene. */
|
||||
protected static class ObjectInfo
|
||||
{
|
||||
public ObjectInfo () {}
|
||||
public ObjectTile object;
|
||||
public Point coords;
|
||||
public String action;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// $Id: DisplayObjectInfo.java,v 1.1 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.media.tile.ObjectTile;
|
||||
|
||||
/**
|
||||
* Used to track information about an object in the scene.
|
||||
*/
|
||||
public class SceneObject
|
||||
{
|
||||
/** A reference to the object tile itself. */
|
||||
public ObjectTile tile;
|
||||
|
||||
/** The x and y tile coordinates of the object. */
|
||||
public int x = -1, y = -1;
|
||||
|
||||
/** The object's index in the scene object list. */
|
||||
public int index = -1;
|
||||
|
||||
/** The action associated with this object or null if it has no
|
||||
* action. */
|
||||
public String action;
|
||||
|
||||
/** The object's bounding rectangle. */
|
||||
public Rectangle bounds;
|
||||
|
||||
/**
|
||||
* Convenience constructor.
|
||||
*/
|
||||
public SceneObject (int x, int y, ObjectTile tile)
|
||||
{
|
||||
this.tile = tile;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other instanceof SceneObject) {
|
||||
return (index == ((SceneObject)other).index);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int hashCode ()
|
||||
{
|
||||
return x ^ y ^ index ^ tile.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this instance.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return StringUtil.fieldsToString(this);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: IsoSceneView.java,v 1.118 2002/09/05 02:21:54 shaper Exp $
|
||||
// $Id: IsoSceneView.java,v 1.119 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene;
|
||||
|
||||
@@ -17,8 +17,6 @@ import java.awt.Stroke;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
@@ -162,34 +160,27 @@ public class IsoSceneView implements SceneView
|
||||
*/
|
||||
protected void paintHighlights (Graphics2D gfx, Rectangle clip)
|
||||
{
|
||||
// if we're not highlighting object tiles, bail now
|
||||
// if we're not highlighting anything, bail now
|
||||
if (_hmode == HIGHLIGHT_NEVER) {
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon hpoly = null;
|
||||
|
||||
// if the highlighted object is an object tile, we want to
|
||||
// highlight that
|
||||
if (_hobject instanceof ObjectTile) {
|
||||
ObjectTile otile = (ObjectTile)_hobject;
|
||||
// if we're only highlighting objects with actions, make sure
|
||||
// this one has an action
|
||||
String action = _scene.getObjectAction(otile);
|
||||
if (_hmode != HIGHLIGHT_WITH_ACTION || !StringUtil.blank(action)) {
|
||||
hpoly = IsoUtil.getObjectFootprint(
|
||||
_model, _hcoords.x, _hcoords.y, otile);
|
||||
// if we have a hover object, do some business
|
||||
if (_hobject != null && _hobject instanceof SceneObject) {
|
||||
SceneObject scobj = (SceneObject)_hobject;
|
||||
if (scobj.action != null || _hmode == HIGHLIGHT_ALWAYS) {
|
||||
hpoly = IsoUtil.getObjectFootprint(_model, scobj);
|
||||
}
|
||||
}
|
||||
|
||||
// if we have no highlight object, but we're in HIGHLIGHT_ALL,
|
||||
// then paint the bounds of the highlighted base tile
|
||||
if (hpoly == null && _hmode == HIGHLIGHT_ALL &&
|
||||
_hcoords.x != -1 && _hcoords.y != -1) {
|
||||
// if we had no valid hover object, but we're in HIGHLIGHT_ALWAYS,
|
||||
// go for the tile outline
|
||||
if (hpoly == null && _hmode == HIGHLIGHT_ALWAYS) {
|
||||
hpoly = IsoUtil.getTilePolygon(_model, _hcoords.x, _hcoords.y);
|
||||
}
|
||||
|
||||
// if we've determined that there's something to highlight
|
||||
if (hpoly != null) {
|
||||
// set the desired stroke and color
|
||||
Stroke ostroke = gfx.getStroke();
|
||||
@@ -394,26 +385,24 @@ public class IsoSceneView implements SceneView
|
||||
}
|
||||
|
||||
// add any objects impacted by the dirty rectangle
|
||||
Iterator iter = _objects.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ObjectMetrics metrics = (ObjectMetrics)iter.next();
|
||||
Rectangle obounds = metrics.bounds;
|
||||
if (!obounds.intersects(clip)) {
|
||||
int ocount = _objects.size();
|
||||
for (int ii = 0; ii < ocount; ii++) {
|
||||
SceneObject scobj = (SceneObject)_objects.get(ii);
|
||||
if (!scobj.bounds.intersects(clip)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// compute the footprint if we're rendering those
|
||||
Polygon foot = null;
|
||||
if (_model.showFootprints) {
|
||||
foot = IsoUtil.getObjectFootprint(
|
||||
_model, metrics.x, metrics.y, metrics.tile);
|
||||
foot = IsoUtil.getObjectFootprint(_model, scobj);
|
||||
}
|
||||
|
||||
// add the object to the dirty items list
|
||||
_dirtyItems.appendDirtyObject(
|
||||
metrics.tile, obounds, foot, metrics.x, metrics.y);
|
||||
_dirtyItems.appendDirtyObject(scobj, foot);
|
||||
|
||||
// Log.info("Dirtied item: Object(" +
|
||||
// metrics.x + ", " + metrics.y + ")");
|
||||
// scobj.x + ", " + scobj.y + ")");
|
||||
}
|
||||
|
||||
// Log.info("renderDirtyItems [items=" + _dirtyItems.size() + "].");
|
||||
@@ -434,46 +423,28 @@ public class IsoSceneView implements SceneView
|
||||
_objects.clear();
|
||||
|
||||
// generate metric records for all objects
|
||||
Iterator oiter = _scene.getObjectTiles();
|
||||
while (oiter.hasNext()) {
|
||||
ObjectTile tile = (ObjectTile)oiter.next();
|
||||
Point coords = _scene.getObjectCoords(tile);
|
||||
generateObjectMetrics(tile, coords.x, coords.y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates object tile metrics for the supplied object tile and adds
|
||||
* them to the list.
|
||||
*/
|
||||
protected void generateObjectMetrics (ObjectTile tile, int x, int y)
|
||||
{
|
||||
// create a metrics record for this object
|
||||
ObjectMetrics metrics = new ObjectMetrics();
|
||||
metrics.tile = tile;
|
||||
metrics.x = x;
|
||||
metrics.y = y;
|
||||
metrics.bounds = IsoUtil.getObjectBounds(_model, x, y, tile);
|
||||
|
||||
// and add it to the list
|
||||
_objects.add(metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out the object metrics for the specified object.
|
||||
*/
|
||||
protected void clearObjectMetrics (ObjectTile tile)
|
||||
{
|
||||
int ocount = _objects.size();
|
||||
int ocount = _scene.getObjectCount();
|
||||
for (int ii = 0; ii < ocount; ii++) {
|
||||
ObjectMetrics metrics = (ObjectMetrics)_objects.get(ii);
|
||||
if (metrics.tile == tile) {
|
||||
_objects.remove(ii);
|
||||
return;
|
||||
}
|
||||
createSceneObject(_scene.getObjectCoords(ii).x,
|
||||
_scene.getObjectCoords(ii).y,
|
||||
_scene.getObjectTile(ii), ii,
|
||||
_scene.getObjectAction(ii));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new scene object and adds it to the list.
|
||||
*/
|
||||
protected void createSceneObject (
|
||||
int x, int y, ObjectTile tile, int index, String action)
|
||||
{
|
||||
SceneObject scobj = new SceneObject(x, y, tile);
|
||||
scobj.index = index;
|
||||
scobj.action = action;
|
||||
scobj.bounds = IsoUtil.getObjectBounds(_model, scobj);
|
||||
_objects.add(scobj);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Path getPath (MisoCharacterSprite sprite, int x, int y)
|
||||
{
|
||||
@@ -513,10 +484,11 @@ public class IsoSceneView implements SceneView
|
||||
int x = e.getX(), y = e.getY();
|
||||
boolean repaint = false;
|
||||
|
||||
// update the base tile coordinates that the mouse is over (if
|
||||
// it's also over an object tile, we'll override these values)
|
||||
// update the mouse's tile coordinates
|
||||
boolean newtile = updateTileCoords(x, y, _hcoords);
|
||||
// if we're highlighting base tiles, we may need to repaint
|
||||
if (_hmode == HIGHLIGHT_ALL) {
|
||||
repaint = (updateTileCoords(x, y, _hcoords) || repaint);
|
||||
repaint = (newtile || repaint);
|
||||
}
|
||||
|
||||
// compute the list of objects over which the mouse is hovering
|
||||
@@ -544,19 +516,14 @@ public class IsoSceneView implements SceneView
|
||||
if (icount > 0) {
|
||||
DirtyItem item = (DirtyItem)_hitList.get(icount-1);
|
||||
hobject = item.obj;
|
||||
|
||||
// if this is an object tile, we need to update the hcoords
|
||||
if (hobject instanceof ObjectTile) {
|
||||
_hcoords.x = item.ox;
|
||||
_hcoords.y = item.oy;
|
||||
}
|
||||
}
|
||||
|
||||
// if this hover object is different than before, we'll need to be
|
||||
// repainted
|
||||
// repainted unless we're not highlighting anything
|
||||
if (hobject != _hobject) {
|
||||
repaint = hoverObjectWillChange(hobject) || repaint;
|
||||
repaint |= (_hmode != HIGHLIGHT_NEVER);
|
||||
_hobject = hobject;
|
||||
// Log.info("New hover object [ho=" + _hobject + "].");
|
||||
}
|
||||
|
||||
// clear out the hitlists
|
||||
@@ -566,24 +533,6 @@ public class IsoSceneView implements SceneView
|
||||
return repaint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to inform that the hover object, _hobject, has changed.
|
||||
* When overriding this method, be sure not to short-circuit any
|
||||
* calls to super() unless you mean to.
|
||||
*
|
||||
* @return true if we need to repaint.
|
||||
*/
|
||||
protected boolean hoverObjectWillChange (Object newhobject)
|
||||
{
|
||||
// we need to repaint if we're highlighting objects, but if
|
||||
// we're only highlighting objects with actions, we only need
|
||||
// to repaint if the object has an action
|
||||
return (_hmode == HIGHLIGHT_WITH_ACTION)
|
||||
? ((newhobject instanceof ObjectTile) &&
|
||||
(_scene.getObjectAction((ObjectTile)newhobject) != null))
|
||||
: (_hmode != HIGHLIGHT_NEVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to the supplied dirty item list, all of the object tiles that
|
||||
* are hit by the specified point (meaning the point is contained
|
||||
@@ -592,10 +541,10 @@ public class IsoSceneView implements SceneView
|
||||
*/
|
||||
protected void getHitObjects (DirtyItemList list, int x, int y)
|
||||
{
|
||||
Iterator iter = _objects.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ObjectMetrics metrics = (ObjectMetrics)iter.next();
|
||||
Rectangle pbounds = metrics.bounds;
|
||||
int ocount = _objects.size();
|
||||
for (int ii = 0; ii < ocount; ii++) {
|
||||
SceneObject scobj = (SceneObject)_objects.get(ii);
|
||||
Rectangle pbounds = scobj.bounds;
|
||||
// skip bounding rects that don't contain the point
|
||||
if (!pbounds.contains(x, y)) {
|
||||
continue;
|
||||
@@ -603,13 +552,12 @@ public class IsoSceneView implements SceneView
|
||||
|
||||
// now check that the pixel in the tile image is
|
||||
// non-transparent at that point
|
||||
if (!metrics.tile.hitTest(x - pbounds.x, y - pbounds.y)) {
|
||||
if (!scobj.tile.hitTest(x - pbounds.x, y - pbounds.y)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// we've passed the test, add the object to the list
|
||||
list.appendDirtyObject(metrics.tile, metrics.bounds, null,
|
||||
metrics.x, metrics.y);
|
||||
list.appendDirtyObject(scobj, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,30 +577,13 @@ public class IsoSceneView implements SceneView
|
||||
|
||||
/**
|
||||
* Returns the tile coordinates of the tile over which the mouse is
|
||||
* hovering (which are the origin coordinates in the case of an object
|
||||
* tile).
|
||||
* hovering.
|
||||
*/
|
||||
public Point getHoverCoords ()
|
||||
{
|
||||
return _hcoords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounds of the given object in the scene in screen
|
||||
* coordinates, or <code>null</code> if there is no such object.
|
||||
*/
|
||||
public Rectangle getObjectTileBounds (int x, int y, ObjectTile tile)
|
||||
{
|
||||
Iterator iter = _objects.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ObjectMetrics metrics = (ObjectMetrics)iter.next();
|
||||
if (metrics.tile == tile && metrics.x == x && metrics.y == y) {
|
||||
return metrics.bounds;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the supplied screen coordinates into tile coordinates,
|
||||
* writing the values into the supplied {@link Point} instance and
|
||||
@@ -677,22 +608,6 @@ public class IsoSceneView implements SceneView
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class used to cache necessary information on all object tiles in
|
||||
* the scene.
|
||||
*/
|
||||
protected static class ObjectMetrics
|
||||
{
|
||||
/** The x and y tile coordinates of the object. */
|
||||
public int x, y;
|
||||
|
||||
/** A reference to the object tile itself. */
|
||||
public ObjectTile tile;
|
||||
|
||||
/** The object's bounding rectangle. */
|
||||
public Rectangle bounds;
|
||||
}
|
||||
|
||||
/** The sprite manager. */
|
||||
protected SpriteManager _spritemgr;
|
||||
|
||||
@@ -731,13 +646,12 @@ public class IsoSceneView implements SceneView
|
||||
/** The highlight mode. */
|
||||
protected int _hmode = HIGHLIGHT_NEVER;
|
||||
|
||||
/** The coordinates of the currently highlighted base or object
|
||||
* tile. */
|
||||
protected Point _hcoords = new Point(-1, -1);
|
||||
|
||||
/** The object that the mouse is currently hovering over. */
|
||||
/** Info on the object that the mouse is currently hovering over. */
|
||||
protected Object _hobject;
|
||||
|
||||
/** Used to track the tile coordinates over which the mouse is hovering. */
|
||||
protected Point _hcoords = new Point();
|
||||
|
||||
/** The font to draw tile coordinates. */
|
||||
protected Font _font = new Font("Arial", Font.PLAIN, 7);
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//
|
||||
// $Id: SceneView.java,v 1.29 2002/06/18 22:38:12 mdb Exp $
|
||||
// $Id: SceneView.java,v 1.30 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
@@ -71,8 +72,10 @@ public interface SceneView
|
||||
public void mouseExited (MouseEvent e);
|
||||
|
||||
/**
|
||||
* Returns the object (sprite or object tile) over which the mouse is
|
||||
* currently hovering.
|
||||
* Returns information about the object over which the mouse is
|
||||
* currently hovering (either a {@link SceneObject} or a {@link
|
||||
* MisoCharacterSprite}), or null if the mouse is not hovering over
|
||||
* anything of interest.
|
||||
*/
|
||||
public Object getHoverObject ();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: IsoUtil.java,v 1.38 2002/07/08 21:41:30 mdb Exp $
|
||||
// $Id: IsoUtil.java,v 1.39 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene.util;
|
||||
|
||||
@@ -10,7 +10,6 @@ import java.awt.Rectangle;
|
||||
import com.samskivert.swing.SmartPolygon;
|
||||
|
||||
import com.threerings.media.sprite.Sprite;
|
||||
import com.threerings.media.tile.ObjectTile;
|
||||
import com.threerings.media.util.MathUtil;
|
||||
|
||||
import com.threerings.util.DirectionCodes;
|
||||
@@ -19,6 +18,7 @@ import com.threerings.util.DirectionUtil;
|
||||
import com.threerings.miso.Log;
|
||||
import com.threerings.miso.scene.IsoSceneViewModel;
|
||||
import com.threerings.miso.scene.MisoCharacterSprite;
|
||||
import com.threerings.miso.scene.SceneObject;
|
||||
|
||||
/**
|
||||
* The <code>IsoUtil</code> class is a holding place for miscellaneous
|
||||
@@ -58,12 +58,12 @@ public class IsoUtil
|
||||
* @return the bounding polygon.
|
||||
*/
|
||||
public static Polygon getObjectFootprint (
|
||||
IsoSceneViewModel model, int tx, int ty, ObjectTile tile)
|
||||
IsoSceneViewModel model, SceneObject scobj)
|
||||
{
|
||||
Polygon boundsPoly = new SmartPolygon();
|
||||
Point tpos = tileToScreen(model, tx, ty, new Point());
|
||||
Point tpos = tileToScreen(model, scobj.x, scobj.y, new Point());
|
||||
|
||||
int bwid = tile.getBaseWidth(), bhei = tile.getBaseHeight();
|
||||
int bwid = scobj.tile.getBaseWidth(), bhei = scobj.tile.getBaseHeight();
|
||||
int oox = tpos.x + model.tilehwid, ooy = tpos.y + model.tilehei;
|
||||
int rx = oox, ry = ooy;
|
||||
|
||||
@@ -104,16 +104,16 @@ public class IsoUtil
|
||||
* @return the bounding polygon.
|
||||
*/
|
||||
public static Polygon getTightObjectBounds (
|
||||
IsoSceneViewModel model, int tx, int ty, ObjectTile tile)
|
||||
IsoSceneViewModel model, SceneObject scobj)
|
||||
{
|
||||
Point tpos = tileToScreen(model, tx, ty, new Point());
|
||||
Point tpos = tileToScreen(model, scobj.x, scobj.y, new Point());
|
||||
|
||||
// if the tile has an origin, use that, otherwise compute the
|
||||
// origin based on the tile footprint
|
||||
int tox = tile.getOriginX(), toy = tile.getOriginY();
|
||||
int tox = scobj.tile.getOriginX(), toy = scobj.tile.getOriginY();
|
||||
if (tox == -1 || toy == -1) {
|
||||
tox = tile.getBaseWidth() * model.tilehwid;
|
||||
toy = tile.getHeight();
|
||||
tox = scobj.tile.getBaseWidth() * model.tilehwid;
|
||||
toy = scobj.tile.getHeight();
|
||||
}
|
||||
|
||||
float slope = (float)model.tilehei / (float)model.tilewid;
|
||||
@@ -127,7 +127,7 @@ public class IsoUtil
|
||||
boundsPoly.addPoint(rx, ry);
|
||||
|
||||
// top-right point
|
||||
rx = sx + tile.getWidth();
|
||||
rx = sx + scobj.tile.getWidth();
|
||||
boundsPoly.addPoint(rx, ry);
|
||||
|
||||
// bottom-right point
|
||||
@@ -161,24 +161,25 @@ public class IsoUtil
|
||||
* @return the bounding rectangle.
|
||||
*/
|
||||
public static Rectangle getObjectBounds (
|
||||
IsoSceneViewModel model, int tx, int ty, ObjectTile tile)
|
||||
IsoSceneViewModel model, SceneObject scobj)
|
||||
{
|
||||
Point tpos = tileToScreen(model, tx, ty, new Point());
|
||||
Point tpos = tileToScreen(model, scobj.x, scobj.y, new Point());
|
||||
|
||||
// if the tile has an origin, use that, otherwise compute the
|
||||
// origin based on the tile footprint
|
||||
int tox = tile.getOriginX(), toy = tile.getOriginY();
|
||||
int tox = scobj.tile.getOriginX(), toy = scobj.tile.getOriginY();
|
||||
if (tox == Integer.MIN_VALUE) {
|
||||
tox = tile.getBaseWidth() * model.tilehwid;
|
||||
tox = scobj.tile.getBaseWidth() * model.tilehwid;
|
||||
}
|
||||
if (toy == Integer.MIN_VALUE) {
|
||||
toy = tile.getHeight();
|
||||
toy = scobj.tile.getHeight();
|
||||
}
|
||||
|
||||
int oox = tpos.x + model.tilehwid, ooy = tpos.y + model.tilehei;
|
||||
int sx = oox - tox, sy = ooy - toy;
|
||||
|
||||
return new Rectangle(sx, sy, tile.getWidth(), tile.getHeight());
|
||||
return new Rectangle(
|
||||
sx, sy, scobj.tile.getWidth(), scobj.tile.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,13 +187,12 @@ public class IsoUtil
|
||||
* the objects occupy the specified coordinates, false if not.
|
||||
*/
|
||||
public static boolean objectFootprintsOverlap (
|
||||
ObjectTile tile1, int x1, int y1,
|
||||
ObjectTile tile2, int x2, int y2)
|
||||
SceneObject so1, SceneObject so2)
|
||||
{
|
||||
return (x2 > x1 - tile1.getBaseWidth() &&
|
||||
x1 > x2 - tile2.getBaseWidth() &&
|
||||
y2 > y1 - tile1.getBaseHeight() &&
|
||||
y1 > y2 - tile2.getBaseHeight());
|
||||
return (so2.x > so1.x - so1.tile.getBaseWidth() &&
|
||||
so1.x > so2.x - so2.tile.getBaseWidth() &&
|
||||
so2.y > so1.y - so1.tile.getBaseHeight() &&
|
||||
so1.y > so2.y - so2.tile.getBaseHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: EditableMisoScene.java,v 1.16 2002/05/17 19:06:23 ray Exp $
|
||||
// $Id: EditableMisoScene.java,v 1.17 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene.tools;
|
||||
|
||||
@@ -66,13 +66,15 @@ public interface EditableMisoScene
|
||||
* @param tile the tile to set.
|
||||
* @param fqTileId the fully-qualified tile id (@see
|
||||
* TileUtil#getFQTileId}) of the new default base tile.
|
||||
*
|
||||
* @return the new object's index in the object list.
|
||||
*/
|
||||
public void addObjectTile (ObjectTile tile, int x, int y, int fqTileId);
|
||||
public int addObjectTile (ObjectTile tile, int x, int y, int fqTileId);
|
||||
|
||||
/**
|
||||
* Sets the action string for the specified object tile.
|
||||
*/
|
||||
public void setObjectAction (ObjectTile tile, String action);
|
||||
public void setObjectAction (int index, String action);
|
||||
|
||||
/**
|
||||
* Clears out the tile at the specified location in the base layer.
|
||||
@@ -80,14 +82,15 @@ public interface EditableMisoScene
|
||||
public void clearBaseTile (int x, int y);
|
||||
|
||||
/**
|
||||
* Clears out the specified tile from the object list.
|
||||
* Clears out the specified object tile at the specified coordinates
|
||||
* from the object list.
|
||||
*/
|
||||
public void removeObjectTile (ObjectTile tile);
|
||||
public void removeObjectTile (int index);
|
||||
|
||||
/**
|
||||
* Clears the action string for the specified object tile.
|
||||
*/
|
||||
public void clearObjectAction (ObjectTile tile);
|
||||
public void clearObjectAction (int index);
|
||||
|
||||
/**
|
||||
* Returns a reference to the miso scene model that reflects the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: EditableMisoSceneImpl.java,v 1.21 2002/09/12 21:10:31 mdb Exp $
|
||||
// $Id: EditableMisoSceneImpl.java,v 1.22 2002/09/18 02:32:57 mdb Exp $
|
||||
|
||||
package com.threerings.miso.scene.tools;
|
||||
|
||||
@@ -110,22 +110,26 @@ public class EditableMisoSceneImpl
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void addObjectTile (ObjectTile tile, int x, int y, int fqTileId)
|
||||
public int addObjectTile (ObjectTile tile, int x, int y, int fqTileId)
|
||||
{
|
||||
// add the tile to the list
|
||||
_objects.add(tile);
|
||||
_coords.put(tile, new Point(x, y));
|
||||
_objectTileIds.put(tile, new Integer(fqTileId));
|
||||
// create an object info record and add it to the list
|
||||
EditableObjectInfo info = (EditableObjectInfo)createObjectInfo();
|
||||
info.object = tile;
|
||||
info.coords = new Point(x, y);
|
||||
info.fqTileId = fqTileId;
|
||||
_objects.add(info);
|
||||
|
||||
// toggle the "covered" flag on in all base tiles below this
|
||||
// object tile
|
||||
setObjectTileFootprint(tile, x, y, true);
|
||||
|
||||
return _objects.size()-1;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void setObjectAction (ObjectTile tile, String action)
|
||||
public void setObjectAction (int index, String action)
|
||||
{
|
||||
_actions.put(tile, action);
|
||||
((ObjectInfo)_objects.get(index)).action = action;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -137,25 +141,20 @@ public class EditableMisoSceneImpl
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void removeObjectTile (ObjectTile tile)
|
||||
public void removeObjectTile (int index)
|
||||
{
|
||||
// remove the tile from the list and tables
|
||||
_objects.remove(tile);
|
||||
_actions.remove(tile);
|
||||
_objectTileIds.remove(tile);
|
||||
ObjectInfo info = (ObjectInfo)_objects.remove(index);
|
||||
|
||||
Point p = (Point)_coords.remove(tile);
|
||||
if (p != null) {
|
||||
// toggle the "covered" flag off on the base tiles in this
|
||||
// object tile's footprint
|
||||
setObjectTileFootprint(tile, p.x, p.y, false);
|
||||
}
|
||||
// toggle the "covered" flag off on the base tiles in this object
|
||||
// tile's footprint
|
||||
setObjectTileFootprint(
|
||||
info.object, info.coords.x, info.coords.y, false);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clearObjectAction (ObjectTile tile)
|
||||
public void clearObjectAction (int index)
|
||||
{
|
||||
_actions.remove(tile);
|
||||
((ObjectInfo)_objects.get(index)).action = null;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -171,12 +170,11 @@ public class EditableMisoSceneImpl
|
||||
String[] actions = new String[ocount];
|
||||
|
||||
for (int ii = 0; ii < ocount; ii++) {
|
||||
ObjectTile tile = (ObjectTile)_objects.get(ii);
|
||||
Point coords = (Point)_coords.get(tile);
|
||||
otids[3*ii] = coords.x;
|
||||
otids[3*ii+1] = coords.y;
|
||||
otids[3*ii+2] = ((Integer)_objectTileIds.get(tile)).intValue();
|
||||
actions[ii] = (String)_actions.get(tile);
|
||||
EditableObjectInfo info = (EditableObjectInfo)_objects.get(ii);
|
||||
otids[3*ii] = info.coords.x;
|
||||
otids[3*ii+1] = info.coords.y;
|
||||
otids[3*ii+2] = info.fqTileId;
|
||||
actions[ii] = info.action;
|
||||
}
|
||||
|
||||
// stuff the new arrays into the model
|
||||
@@ -189,30 +187,32 @@ public class EditableMisoSceneImpl
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected ObjectTile expandObject (
|
||||
protected ObjectInfo createObjectInfo ()
|
||||
{
|
||||
return new EditableObjectInfo();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected ObjectInfo expandObject (
|
||||
int col, int row, int tsid, int tid, int fqTid, String action)
|
||||
throws NoSuchTileException, NoSuchTileSetException
|
||||
{
|
||||
// do the actual object creation
|
||||
ObjectTile tile = super.expandObject(
|
||||
col, row, tsid, tid, fqTid, action);
|
||||
|
||||
// make sure our array is created (we have to do this specially
|
||||
// here because this method is called before our constructor is
|
||||
// called; yay Java!)
|
||||
if (_objectTileIds == null) {
|
||||
_objectTileIds = new HashMap();
|
||||
}
|
||||
EditableObjectInfo info = (EditableObjectInfo)
|
||||
super.expandObject(col, row, tsid, tid, fqTid, action);
|
||||
|
||||
// we need this to track object layer mods
|
||||
_objectTileIds.put(tile, new Integer(fqTid));
|
||||
info.fqTileId = fqTid;
|
||||
|
||||
// pass on the objecty goodness
|
||||
return tile;
|
||||
return info;
|
||||
}
|
||||
|
||||
/** Where we keep track of object tile ids. */
|
||||
protected HashMap _objectTileIds = new HashMap();
|
||||
/** Used to report information on objects in this scene. */
|
||||
protected static class EditableObjectInfo extends ObjectInfo
|
||||
{
|
||||
public int fqTileId;
|
||||
}
|
||||
|
||||
/** The default tileset with which to fill the base layer. */
|
||||
protected BaseTileSet _defaultBaseTileSet;
|
||||
|
||||
Reference in New Issue
Block a user