More work on object placement, removal, and rendering within scenes.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@479 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: IsoUtil.java,v 1.8 2001/10/13 01:08:59 shaper Exp $
|
||||
// $Id: IsoUtil.java,v 1.9 2001/10/17 22:21:22 shaper Exp $
|
||||
|
||||
package com.threerings.miso.scene.util;
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.awt.*;
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.threerings.media.sprite.Sprite;
|
||||
import com.threerings.media.sprite.DirtyItemList;
|
||||
import com.threerings.media.sprite.DirtyItemList.DirtyItem;
|
||||
import com.threerings.media.tile.ObjectTile;
|
||||
import com.threerings.media.util.MathUtil;
|
||||
|
||||
@@ -20,16 +20,66 @@ import com.threerings.miso.scene.*;
|
||||
*/
|
||||
public class IsoUtil
|
||||
{
|
||||
/** The comparator used to sort dirty items in ascending render order. */
|
||||
/** The dirty item comparator used to sort dirty items back to front. */
|
||||
public static final Comparator DIRTY_COMP = new DirtyItemComparator();
|
||||
|
||||
/**
|
||||
* Returns a polygon bounding all footprint tiles of the given
|
||||
* object tile.
|
||||
*
|
||||
* @param model the scene view model.
|
||||
* @param root the polygon for the root tile at which the object
|
||||
* is located.
|
||||
* @param tile the object tile.
|
||||
*
|
||||
* @return the bounding polygon.
|
||||
*/
|
||||
public static Polygon getObjectFootprint (
|
||||
IsoSceneViewModel model, Polygon root, ObjectTile tile)
|
||||
{
|
||||
Rectangle bounds = root.getBounds();
|
||||
int sx = bounds.x - ((tile.baseWidth - 1) * model.tilehwid);
|
||||
int sy = bounds.y - tile.height + model.tilehei;
|
||||
|
||||
Polygon boundsPoly = new Polygon();
|
||||
int rx = sx, ry = sy;
|
||||
|
||||
// right point
|
||||
rx = sx + tile.width;
|
||||
ry = bounds.y - ((tile.baseHeight - 2) * model.tilehhei);
|
||||
boundsPoly.addPoint(rx, ry);
|
||||
|
||||
// bottom-middle point
|
||||
rx = bounds.x + model.tilehwid;
|
||||
ry = bounds.y + model.tilehei;
|
||||
boundsPoly.addPoint(rx, ry);
|
||||
|
||||
// left point
|
||||
rx = sx;
|
||||
ry = bounds.y - ((tile.baseWidth - 2) * model.tilehhei);
|
||||
boundsPoly.addPoint(rx, ry);
|
||||
|
||||
// top-middle point
|
||||
rx += (tile.baseHeight * model.tilehwid);
|
||||
ry -= (tile.baseHeight * model.tilehhei);
|
||||
boundsPoly.addPoint(rx, ry);
|
||||
|
||||
// right point
|
||||
rx = sx + tile.width;
|
||||
ry = bounds.y - ((tile.baseHeight - 2) * model.tilehhei);
|
||||
boundsPoly.addPoint(rx, ry);
|
||||
|
||||
return boundsPoly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a polygon bounding the given object tile display image,
|
||||
* with the bottom of the polygon shaped to conform to the known
|
||||
* object dimensions.
|
||||
*
|
||||
* @param model the scene view model.
|
||||
* @param root the root tile at which the object is located.
|
||||
* @param root the polygon for the root tile at which the object
|
||||
* is located.
|
||||
* @param tile the object tile.
|
||||
*
|
||||
* @return the bounding polygon.
|
||||
@@ -345,18 +395,26 @@ public class IsoUtil
|
||||
protected static final int FULL_TILE_FACTOR = 100;
|
||||
|
||||
/**
|
||||
* A comparator class to facilitate sorting the dirty items in
|
||||
* ascending x- and y-coordinate order suitable for rendering in
|
||||
* the isometric view with proper visual results.
|
||||
* A comparator class for use in sorting the dirty sprites and
|
||||
* objects in a scene in ascending x- and y-coordinate order
|
||||
* suitable for rendering in the isometric view with proper visual
|
||||
* results.
|
||||
*/
|
||||
protected static class DirtyItemComparator implements Comparator
|
||||
public static class DirtyItemComparator implements Comparator
|
||||
{
|
||||
public int compare (Object a, Object b)
|
||||
{
|
||||
DirtyItemList.DirtyItem da = (DirtyItemList.DirtyItem)a;
|
||||
DirtyItemList.DirtyItem db = (DirtyItemList.DirtyItem)b;
|
||||
DirtyItem da = (DirtyItem)a;
|
||||
DirtyItem db = (DirtyItem)b;
|
||||
|
||||
if (da.y <= db.y && da.x <= db.x) {
|
||||
// check whether right edge of a overlaps with left edge of b
|
||||
int comp = getRightOverlap(da, db);
|
||||
if (comp != 0) {
|
||||
return comp;
|
||||
}
|
||||
|
||||
// determine ordering based purely on coordinates
|
||||
if (da.x <= db.x && da.y <= db.y) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -367,5 +425,52 @@ public class IsoUtil
|
||||
{
|
||||
return (obj == this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the right edge of <code>da</code> to see whether it
|
||||
* overlaps with the left edge of <code>db</code>.
|
||||
*
|
||||
* @return -1 if <code>da</code> should be rendered behind
|
||||
* <code>db</code>, 0 if the right edge of <code>da</code>
|
||||
* does not overlap with <code>db</code>, and 1 if
|
||||
* <code>da</code> should be rendered in front of
|
||||
* <code>db</code>.
|
||||
*/
|
||||
protected int getRightOverlap (DirtyItem da, DirtyItem db)
|
||||
{
|
||||
int ax = da.x, bx = db.x;
|
||||
int ay = da.y, by = db.y;
|
||||
|
||||
// get da's rightmost corner coordinate
|
||||
if (da.obj instanceof ObjectTile) {
|
||||
ay -= (((ObjectTile)da.obj).baseHeight - 1);
|
||||
}
|
||||
|
||||
// get db's leftmost corner coordinate
|
||||
if (db.obj instanceof ObjectTile) {
|
||||
bx -= (((ObjectTile)db.obj).baseWidth - 1);
|
||||
}
|
||||
|
||||
// Log.info("getOverlap [ax=" + ax + ", ay=" + ay +
|
||||
// ", bx=" + bx + ", by=" + by + "].");
|
||||
|
||||
if (ax > bx && ay < by) {
|
||||
// we most certainly don't overlap
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// calculate inequality constant for db's leftmost corner
|
||||
int k = (bx + by);
|
||||
|
||||
// we need to determine whether to render da in front of
|
||||
// db, so we check whether da's rightmost corner is above
|
||||
// or below db's leftmost corner.
|
||||
if (ay <= k - ax) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user