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:
Walter Korman
2001-10-17 22:21:22 +00:00
parent b0a8f3b6fc
commit 2ecd879692
9 changed files with 260 additions and 199 deletions
@@ -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;
}
}
}
}