Various fixes to support negative tile coordinates; created sparse miso
scene model and associated business to store scene data in an arbitrary set of blocks rather than fixed arrays; finally stuck a fork in scene width and height as well as view width and height along with origin offset and a few other now obsolete bits. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2434 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: MisoScenePanel.java,v 1.8 2003/04/19 17:06:08 mdb Exp $
|
||||
// $Id: MisoScenePanel.java,v 1.9 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.client;
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.threerings.media.sprite.Sprite;
|
||||
import com.threerings.media.tile.Tile;
|
||||
import com.threerings.media.tile.TileManager;
|
||||
import com.threerings.media.tile.TileSet;
|
||||
import com.threerings.media.util.MathUtil;
|
||||
import com.threerings.media.util.Path;
|
||||
|
||||
import com.threerings.miso.Log;
|
||||
@@ -103,7 +104,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
||||
_masks.clear();
|
||||
|
||||
// recenter and rethink
|
||||
centerOnTile(_model.width/2, _model.height/2);
|
||||
centerOnTile(0, 0);
|
||||
rethink();
|
||||
repaint();
|
||||
}
|
||||
@@ -493,16 +494,6 @@ public class MisoScenePanel extends VirtualMediaPanel
|
||||
_activeMenu = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the desired size for the panel based on the requested and
|
||||
* calculated bounds of the scene view.
|
||||
*/
|
||||
public Dimension getPreferredSize ()
|
||||
{
|
||||
return (_metrics == null || isPreferredSizeSet()) ?
|
||||
super.getPreferredSize() : _metrics.bounds.getSize();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void setBounds (int x, int y, int width, int height)
|
||||
{
|
||||
@@ -589,22 +580,30 @@ public class MisoScenePanel extends VirtualMediaPanel
|
||||
// compute the tile bounds of this influential area
|
||||
Rectangle itb = new Rectangle();
|
||||
int minx, miny, maxx, maxy;
|
||||
Point tpos = MisoUtil.screenToTile(
|
||||
_metrics, _ibounds.x, _ibounds.y, new Point());
|
||||
Point tpos = new Point();
|
||||
|
||||
// calculate minimum x
|
||||
MisoUtil.screenToTile(_metrics, _ibounds.x, _ibounds.y, tpos);
|
||||
itb.x = tpos.x;
|
||||
minx = Math.max(0, tpos.x / _metrics.blockwid);
|
||||
minx = MathUtil.floorDiv(tpos.x, _metrics.blockwid);
|
||||
|
||||
// calculate minimum y
|
||||
MisoUtil.screenToTile(
|
||||
_metrics, _ibounds.x + _ibounds.width, _ibounds.y, tpos);
|
||||
itb.y = tpos.y;
|
||||
miny = Math.max(0, tpos.y / _metrics.blockhei);
|
||||
miny = MathUtil.floorDiv(tpos.y, _metrics.blockhei);
|
||||
|
||||
// calculate maximum x
|
||||
MisoUtil.screenToTile(_metrics, _ibounds.x + _ibounds.width,
|
||||
_ibounds.y + _ibounds.height, tpos);
|
||||
itb.width = (tpos.x-itb.x);
|
||||
maxx = Math.max(0, tpos.x / _metrics.blockwid);
|
||||
itb.width = (tpos.x-itb.x+1);
|
||||
maxx = MathUtil.floorDiv(tpos.x, _metrics.blockwid);
|
||||
|
||||
// calculate maximum y
|
||||
MisoUtil.screenToTile(
|
||||
_metrics, _ibounds.x, _ibounds.y + _ibounds.height, tpos);
|
||||
itb.height = (tpos.y-itb.y);
|
||||
maxy = Math.max(0, tpos.y / _metrics.blockhei);
|
||||
itb.height = (tpos.y-itb.y+1);
|
||||
maxy = MathUtil.floorDiv(tpos.y, _metrics.blockhei);
|
||||
|
||||
// Log.info("Resolving blocks from " + minx + "," + miny + " to " +
|
||||
// maxx + "," + maxy + " (" + StringUtil.toString(itb) + ").");
|
||||
@@ -630,7 +629,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
||||
// become so
|
||||
for (int yy = miny; yy <= maxy; yy++) {
|
||||
for (int xx = minx; xx <= maxx; xx++) {
|
||||
int bkey = (xx << 16) | yy;
|
||||
int bkey = compose(xx, yy);
|
||||
if (!_blocks.containsKey(bkey)) {
|
||||
SceneBlock block = new SceneBlock(
|
||||
this, xx*_metrics.blockwid, yy*_metrics.blockhei,
|
||||
@@ -642,11 +641,17 @@ public class MisoScenePanel extends VirtualMediaPanel
|
||||
}
|
||||
}
|
||||
|
||||
// if nothing changed, we need do nothing more
|
||||
if (!changed) {
|
||||
return;
|
||||
// if anything changed, we recompute our visible object set
|
||||
if (changed) {
|
||||
recomputeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recomputes our set of visible objects and their tips.
|
||||
*/
|
||||
protected void recomputeVisible ()
|
||||
{
|
||||
// flush our visible object set which we'll recreate later
|
||||
_vizobjs.clear();
|
||||
|
||||
@@ -682,11 +687,18 @@ public class MisoScenePanel extends VirtualMediaPanel
|
||||
*/
|
||||
protected SceneBlock getBlock (int tx, int ty)
|
||||
{
|
||||
if (tx < 0 || ty < 0) {
|
||||
return null;
|
||||
}
|
||||
int bkey = (tx/_metrics.blockwid << 16) | (ty/_metrics.blockhei);
|
||||
return (SceneBlock)_blocks.get(bkey);
|
||||
int bx = MathUtil.floorDiv(tx, _metrics.blockwid);
|
||||
int by = MathUtil.floorDiv(ty, _metrics.blockhei);
|
||||
return (SceneBlock)_blocks.get(compose(bx, by));
|
||||
}
|
||||
|
||||
/**
|
||||
* Masks off the lower 16 bits of the supplied integers and composes
|
||||
* them into a single int.
|
||||
*/
|
||||
protected static int compose (int x, int y)
|
||||
{
|
||||
return (x << 16) | (y & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -840,7 +852,7 @@ public class MisoScenePanel extends VirtualMediaPanel
|
||||
protected boolean updateTileCoords (int sx, int sy, Point tpos)
|
||||
{
|
||||
Point npos = MisoUtil.screenToTile(_metrics, sx, sy, new Point());
|
||||
if (!tpos.equals(npos) && _metrics.isCoordinateValid(npos.x, npos.y)) {
|
||||
if (!tpos.equals(npos)) {
|
||||
tpos.setLocation(npos.x, npos.y);
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneObject.java,v 1.3 2003/04/18 23:17:33 mdb Exp $
|
||||
// $Id: SceneObject.java,v 1.4 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.client;
|
||||
|
||||
@@ -218,6 +218,11 @@ public class SceneObject
|
||||
_sspot = MisoUtil.fullToScreen(
|
||||
metrics, _fspot.x, _fspot.y, new Point());
|
||||
}
|
||||
|
||||
// Log.info("Computed object metrics " +
|
||||
// "[tpos=" + StringUtil.coordsToString(tx, ty) +
|
||||
// ", info=" + info +
|
||||
// ", sbounds=" + StringUtil.toString(bounds) + "].");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: MisoSceneModel.java,v 1.15 2003/04/18 18:31:20 mdb Exp $
|
||||
// $Id: MisoSceneModel.java,v 1.16 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.Random;
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
|
||||
import com.threerings.media.tile.TileUtil;
|
||||
import com.threerings.media.util.MathUtil;
|
||||
|
||||
import com.threerings.miso.util.ObjectSet;
|
||||
|
||||
@@ -20,12 +19,6 @@ import com.threerings.miso.util.ObjectSet;
|
||||
public abstract class MisoSceneModel extends SimpleStreamableObject
|
||||
implements Cloneable
|
||||
{
|
||||
/** The width of this scene in tiles. */
|
||||
public short width;
|
||||
|
||||
/** The height of this scene in tiles. */
|
||||
public short height;
|
||||
|
||||
/**
|
||||
* Creates a completely uninitialized model suitable for little more
|
||||
* than unserialization.
|
||||
@@ -34,17 +27,6 @@ public abstract class MisoSceneModel extends SimpleStreamableObject
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a blank model with the specified dimensions.
|
||||
*/
|
||||
public MisoSceneModel (int width, int height)
|
||||
{
|
||||
this.width = (short)MathUtil.bound(
|
||||
Short.MIN_VALUE, width, Short.MAX_VALUE);
|
||||
this.height = (short)MathUtil.bound(
|
||||
Short.MIN_VALUE, height, Short.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fully qualified tile id of the base tile at the
|
||||
* specified coordinates. <code>-1</code> will be returned if there is
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SimpleMisoSceneModel.java,v 1.4 2003/04/18 22:59:18 mdb Exp $
|
||||
// $Id: SimpleMisoSceneModel.java,v 1.5 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.samskivert.util.ArrayUtil;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
import com.samskivert.util.ListUtil;
|
||||
|
||||
import com.threerings.media.util.MathUtil;
|
||||
import com.threerings.miso.util.ObjectSet;
|
||||
|
||||
/**
|
||||
@@ -25,6 +26,12 @@ import com.threerings.miso.util.ObjectSet;
|
||||
*/
|
||||
public class SimpleMisoSceneModel extends MisoSceneModel
|
||||
{
|
||||
/** The width of this scene in tiles. */
|
||||
public short width;
|
||||
|
||||
/** The height of this scene in tiles. */
|
||||
public short height;
|
||||
|
||||
/** The viewport width in tiles. */
|
||||
public int vwidth;
|
||||
|
||||
@@ -65,7 +72,10 @@ public class SimpleMisoSceneModel extends MisoSceneModel
|
||||
*/
|
||||
public SimpleMisoSceneModel (int width, int height, int vwidth, int vheight)
|
||||
{
|
||||
super(width, height);
|
||||
this.width = (short)MathUtil.bound(
|
||||
Short.MIN_VALUE, width, Short.MAX_VALUE);
|
||||
this.height = (short)MathUtil.bound(
|
||||
Short.MIN_VALUE, height, Short.MAX_VALUE);
|
||||
this.vwidth = vwidth;
|
||||
this.vheight = vheight;
|
||||
allocateBaseTileArray();
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
//
|
||||
// $Id: SparseMisoSceneModel.java,v 1.1 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
import com.samskivert.util.ListUtil;
|
||||
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
|
||||
import com.threerings.media.util.MathUtil;
|
||||
|
||||
import com.threerings.miso.Log;
|
||||
import com.threerings.miso.util.ObjectSet;
|
||||
|
||||
/**
|
||||
* Contains miso scene data that is broken up into NxN tile sections.
|
||||
*/
|
||||
public class SparseMisoSceneModel extends MisoSceneModel
|
||||
{
|
||||
/** An interface that allows external entities to "visit" and inspect
|
||||
* every object in this scene. */
|
||||
public static interface ObjectVisitor
|
||||
{
|
||||
/** Called for each object in the scene, interesting and not. */
|
||||
public void visit (int tileId, int x, int y);
|
||||
}
|
||||
|
||||
/** Contains information on a section of this scene. This is only
|
||||
* public so that the scene model parser can do its job, so don't go
|
||||
* poking around in here. */
|
||||
public static class Section extends SimpleStreamableObject
|
||||
implements Cloneable
|
||||
{
|
||||
/** The tile coordinate of our upper leftmost tile. */
|
||||
public short x, y;
|
||||
|
||||
/** The width of this section in tiles. */
|
||||
public int width;
|
||||
|
||||
/** The combined tile ids (tile set id and tile id) for our
|
||||
* section (in row major order). */
|
||||
public int[] baseTileIds;
|
||||
|
||||
/** The combined tile ids (tile set id and tile id) of the
|
||||
* "uninteresting" tiles in the object layer. */
|
||||
public int[] objectTileIds = new int[0];
|
||||
|
||||
/** The x coordinate of the "uninteresting" tiles in the object
|
||||
* layer. */
|
||||
public short[] objectXs = new short[0];
|
||||
|
||||
/** The y coordinate of the "uninteresting" tiles in the object
|
||||
* layer. */
|
||||
public short[] objectYs = new short[0];
|
||||
|
||||
/** Information records for the "interesting" objects in the
|
||||
* object layer. */
|
||||
public ObjectInfo[] objectInfo = new ObjectInfo[0];
|
||||
|
||||
/**
|
||||
* Creates a blank section instance, suitable for unserialization
|
||||
* or configuration by the XML scene parser.
|
||||
*/
|
||||
public Section ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new scene section with the specified dimensions.
|
||||
*/
|
||||
public Section (short x, short y, short width, short height)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
baseTileIds = new int[width*height];
|
||||
}
|
||||
|
||||
public int getBaseTileId (int col, int row) {
|
||||
// if (col < x || col >= (x+width) || row < y || row >= (y+width)) {
|
||||
// Log.warning("Requested bogus tile +" + col + "+" + row +
|
||||
// " from " + this + ".");
|
||||
// return -1;
|
||||
// } else {
|
||||
return baseTileIds[(row-y)*width+(col-x)];
|
||||
// }
|
||||
}
|
||||
|
||||
public void setBaseTile (int col, int row, int fqBaseTileId) {
|
||||
baseTileIds[(row-y)*width+(col-x)] = fqBaseTileId;
|
||||
}
|
||||
|
||||
public void addObject (ObjectInfo info) {
|
||||
if (info.isInteresting()) {
|
||||
objectInfo = (ObjectInfo[])ArrayUtil.append(objectInfo, info);
|
||||
} else {
|
||||
objectTileIds = ArrayUtil.append(objectTileIds, info.tileId);
|
||||
objectXs = ArrayUtil.append(objectXs, (short)info.x);
|
||||
objectYs = ArrayUtil.append(objectYs, (short)info.y);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeObject (ObjectInfo info) {
|
||||
// look for it in the interesting info array
|
||||
int oidx = ListUtil.indexOfEqual(objectInfo, info);
|
||||
if (oidx != -1) {
|
||||
objectInfo = (ObjectInfo[])
|
||||
ArrayUtil.splice(objectInfo, oidx, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
// look for it in the uninteresting arrays
|
||||
oidx = IntListUtil.indexOf(objectTileIds, info.tileId);
|
||||
if (oidx != -1) {
|
||||
objectTileIds = ArrayUtil.splice(objectTileIds, oidx, 1);
|
||||
objectXs = ArrayUtil.splice(objectXs, oidx, 1);
|
||||
objectYs = ArrayUtil.splice(objectYs, oidx, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void getObjects (Rectangle region, ObjectSet set) {
|
||||
// first look for intersecting interesting objects
|
||||
for (int ii = 0; ii < objectInfo.length; ii++) {
|
||||
ObjectInfo info = objectInfo[ii];
|
||||
if (region.contains(info.x, info.y)) {
|
||||
set.insert(info);
|
||||
}
|
||||
}
|
||||
|
||||
// now look for intersecting non-interesting objects
|
||||
for (int ii = 0; ii < objectTileIds.length; ii++) {
|
||||
int x = objectXs[ii], y = objectYs[ii];
|
||||
if (region.contains(x, y)) {
|
||||
set.insert(new ObjectInfo(objectTileIds[ii], x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone () {
|
||||
try {
|
||||
Section section = (Section)super.clone();
|
||||
section.baseTileIds = (int[])baseTileIds.clone();
|
||||
section.objectTileIds = (int[])objectTileIds.clone();
|
||||
section.objectXs = (short[])objectXs.clone();
|
||||
section.objectYs = (short[])objectYs.clone();
|
||||
section.objectInfo = (ObjectInfo[])objectInfo.clone();
|
||||
return section;
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
throw new RuntimeException(
|
||||
"SparseMisoSceneModel.Section.clone: " + cnse);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return ((width == 0) ? "<no bounds>" :
|
||||
(width + "x" + (baseTileIds.length/width))) +
|
||||
"+" + x + "+" + y +
|
||||
":" + objectInfo.length + ":" + objectTileIds.length;
|
||||
}
|
||||
}
|
||||
|
||||
/** The dimensions of a section of our scene. */
|
||||
public short swidth, sheight;
|
||||
|
||||
/**
|
||||
* Creates a scene model with the specified bounds.
|
||||
*
|
||||
* @param swidth the width of a single section (in tiles).
|
||||
* @param sheight the height of a single section (in tiles).
|
||||
*/
|
||||
public SparseMisoSceneModel (int swidth, int sheight)
|
||||
{
|
||||
this.swidth = (short)swidth;
|
||||
this.sheight = (short)sheight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a blank model suitable for unserialization.
|
||||
*/
|
||||
public SparseMisoSceneModel ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all interesting {@link ObjectInfo} records in this scene to
|
||||
* the supplied list.
|
||||
*/
|
||||
public void getInterestingObjects (ArrayList list)
|
||||
{
|
||||
for (Iterator iter = getSections(); iter.hasNext(); ) {
|
||||
Section sect = (Section)iter.next();
|
||||
for (int oo = 0; oo < sect.objectInfo.length; oo++) {
|
||||
list.add(sect.objectInfo[oo]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the supplied visitor of each object in this scene.
|
||||
*/
|
||||
public void visitObjects (ObjectVisitor visitor)
|
||||
{
|
||||
for (Iterator iter = getSections(); iter.hasNext(); ) {
|
||||
Section sect = (Section)iter.next();
|
||||
for (int oo = 0; oo < sect.objectInfo.length; oo++) {
|
||||
ObjectInfo oinfo = sect.objectInfo[oo];
|
||||
visitor.visit(oinfo.tileId, oinfo.x, oinfo.y);
|
||||
}
|
||||
for (int oo = 0; oo < sect.objectTileIds.length; oo++) {
|
||||
visitor.visit(sect.objectTileIds[oo],
|
||||
sect.objectXs[oo], sect.objectYs[oo]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getBaseTileId (int col, int row)
|
||||
{
|
||||
Section sec = getSection(col, row, false);
|
||||
return (sec == null) ? -1 : sec.getBaseTileId(col, row);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean setBaseTile (int fqBaseTileId, int col, int row)
|
||||
{
|
||||
getSection(col, row, true).setBaseTile(col, row, fqBaseTileId);
|
||||
return true;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void getObjects (Rectangle region, ObjectSet set)
|
||||
{
|
||||
int minx = MathUtil.floorDiv(region.x, swidth);
|
||||
int maxx = MathUtil.floorDiv(region.x+region.width-1, swidth);
|
||||
int miny = MathUtil.floorDiv(region.y, sheight);
|
||||
int maxy = MathUtil.floorDiv(region.y+region.height-1, sheight);
|
||||
for (int yy = miny; yy <= maxy; yy++) {
|
||||
for (int xx = minx; xx <= maxx; xx++) {
|
||||
Section sec = getSection(xx, yy, false);
|
||||
if (sec != null) {
|
||||
sec.getObjects(region, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void addObject (ObjectInfo info)
|
||||
{
|
||||
getSection(info.x, info.y, true).addObject(info);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void updateObject (ObjectInfo info)
|
||||
{
|
||||
// not efficient, but this is only done in editing situations
|
||||
removeObject(info);
|
||||
addObject(info);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean removeObject (ObjectInfo info)
|
||||
{
|
||||
Section sec = getSection(info.x, info.y, false);
|
||||
if (sec != null) {
|
||||
return sec.removeObject(info);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't call this method! This is only public so that the scene
|
||||
* parser can construct a scene from raw data. If only Java supported
|
||||
* class friendship.
|
||||
*/
|
||||
public void setSection (Section section)
|
||||
{
|
||||
_sections.put(key(section.x, section.y), section);
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't call this method! This is only public so that the scene
|
||||
* writer can generate XML from the raw scene data.
|
||||
*/
|
||||
public Iterator getSections ()
|
||||
{
|
||||
return _sections.values().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key for the specified section.
|
||||
*/
|
||||
protected final int key (int x, int y)
|
||||
{
|
||||
int sx = MathUtil.floorDiv(x, swidth);
|
||||
int sy = MathUtil.floorDiv(y, sheight);
|
||||
return (sx << 16) | (sy & 0xFFFF);
|
||||
}
|
||||
|
||||
/** Returns the section for the specified tile coordinate. */
|
||||
protected final Section getSection (int x, int y, boolean create)
|
||||
{
|
||||
int key = key(x, y);
|
||||
Section sect = (Section)_sections.get(key);
|
||||
if (sect == null && create) {
|
||||
short sx = (short)(MathUtil.floorDiv(x, swidth)*swidth);
|
||||
short sy = (short)(MathUtil.floorDiv(y, sheight)*sheight);
|
||||
_sections.put(key, sect = new Section(sx, sy, swidth, sheight));
|
||||
// Log.info("Created new section " + sect + ".");
|
||||
}
|
||||
return sect;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Object clone ()
|
||||
{
|
||||
SparseMisoSceneModel model = (SparseMisoSceneModel)super.clone();
|
||||
model._sections = new HashIntMap();
|
||||
for (Iterator iter = getSections(); iter.hasNext(); ) {
|
||||
Section sect = (Section)iter.next();
|
||||
model.setSection((Section)sect.clone());
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
/** Contains our sections in row major order. */
|
||||
protected HashIntMap _sections = new HashIntMap();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: VirtualMisoSceneModel.java,v 1.2 2003/04/18 18:31:21 mdb Exp $
|
||||
// $Id: VirtualMisoSceneModel.java,v 1.3 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.data;
|
||||
|
||||
@@ -16,11 +16,6 @@ public abstract class VirtualMisoSceneModel extends MisoSceneModel
|
||||
{
|
||||
}
|
||||
|
||||
public VirtualMisoSceneModel (int width, int height)
|
||||
{
|
||||
super(width, height);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public boolean setBaseTile (int fqTileId, int x, int y)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// $Id: SparseMisoSceneParser.java,v 1.1 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.tools.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.apache.commons.digester.Digester;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.threerings.tools.xml.NestableRuleSet;
|
||||
|
||||
import com.threerings.miso.data.SparseMisoSceneModel;
|
||||
|
||||
/**
|
||||
* A simple class for parsing simple miso scene models.
|
||||
*/
|
||||
public class SparseMisoSceneParser
|
||||
{
|
||||
/**
|
||||
* Constructs a scene parser that parses scenes with the specified XML
|
||||
* path prefix.
|
||||
*/
|
||||
public SparseMisoSceneParser (String prefix)
|
||||
{
|
||||
// create and configure our digester
|
||||
_digester = new Digester();
|
||||
|
||||
// create our scene rule set
|
||||
SparseMisoSceneRuleSet set = new SparseMisoSceneRuleSet();
|
||||
|
||||
// configure our top-level path prefix
|
||||
if (StringUtil.blank(prefix)) {
|
||||
_prefix = set.getOuterElement();
|
||||
} else {
|
||||
_prefix = prefix + "/" + set.getOuterElement();
|
||||
}
|
||||
|
||||
// add the scene rules
|
||||
set.addRuleInstances(_prefix, _digester);
|
||||
|
||||
// add a rule to grab the finished scene model
|
||||
_digester.addSetNext(
|
||||
_prefix, "setScene", SparseMisoSceneModel.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the XML file at the specified path into a scene model
|
||||
* instance.
|
||||
*/
|
||||
public SparseMisoSceneModel parseScene (String path)
|
||||
throws IOException, SAXException
|
||||
{
|
||||
_model = null;
|
||||
_digester.push(this);
|
||||
_digester.parse(new FileInputStream(path));
|
||||
return _model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the parser once the scene is parsed.
|
||||
*/
|
||||
public void setScene (SparseMisoSceneModel model)
|
||||
{
|
||||
_model = model;
|
||||
}
|
||||
|
||||
protected String _prefix;
|
||||
protected Digester _digester;
|
||||
protected SparseMisoSceneModel _model;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// $Id: SparseMisoSceneRuleSet.java,v 1.1 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.tools.xml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import org.apache.commons.digester.Digester;
|
||||
import org.apache.commons.digester.Rule;
|
||||
|
||||
import com.samskivert.xml.CallMethodSpecialRule;
|
||||
import com.samskivert.xml.SetFieldRule;
|
||||
import com.samskivert.xml.SetPropertyFieldsRule;
|
||||
|
||||
import com.threerings.tools.xml.NestableRuleSet;
|
||||
|
||||
import com.threerings.miso.data.ObjectInfo;
|
||||
import com.threerings.miso.data.SparseMisoSceneModel.Section;
|
||||
import com.threerings.miso.data.SparseMisoSceneModel;
|
||||
|
||||
/**
|
||||
* Used to parse a {@link SparseMisoSceneModel} from XML.
|
||||
*/
|
||||
public class SparseMisoSceneRuleSet implements NestableRuleSet
|
||||
{
|
||||
// documentation inherited from interface
|
||||
public String getOuterElement ()
|
||||
{
|
||||
return SparseMisoSceneWriter.OUTER_ELEMENT;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void addRuleInstances (String prefix, Digester dig)
|
||||
{
|
||||
// this creates the appropriate instance when we encounter our
|
||||
// prefix tag
|
||||
dig.addRule(prefix, new Rule(dig) {
|
||||
public void begin (Attributes attributes) throws Exception {
|
||||
digester.push(createMisoSceneModel());
|
||||
}
|
||||
public void end () throws Exception {
|
||||
digester.pop();
|
||||
}
|
||||
});
|
||||
|
||||
// set up rules to parse and set our fields
|
||||
dig.addRule(prefix + "/swidth", new SetFieldRule(dig, "swidth"));
|
||||
dig.addRule(prefix + "/sheight", new SetFieldRule(dig, "sheight"));
|
||||
|
||||
String sprefix = prefix + "/sections/section";
|
||||
dig.addObjectCreate(sprefix, Section.class.getName());
|
||||
dig.addRule(sprefix, new SetPropertyFieldsRule(dig));
|
||||
dig.addRule(sprefix + "/base", new SetFieldRule(dig, "baseTileIds"));
|
||||
dig.addObjectCreate(sprefix + "/objects/object",
|
||||
ObjectInfo.class.getName());
|
||||
dig.addRule(sprefix + "/objects/object",
|
||||
new SetPropertyFieldsRule(dig));
|
||||
dig.addSetNext(sprefix + "/objects/object", "addObject",
|
||||
ObjectInfo.class.getName());
|
||||
dig.addSetNext(sprefix, "setSection", Section.class.getName());
|
||||
}
|
||||
|
||||
protected SparseMisoSceneModel createMisoSceneModel ()
|
||||
{
|
||||
return new SparseMisoSceneModel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// $Id: SparseMisoSceneWriter.java,v 1.1 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.tools.xml;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
import com.megginson.sax.DataWriter;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.threerings.tools.xml.NestableWriter;
|
||||
|
||||
import com.threerings.miso.data.ObjectInfo;
|
||||
import com.threerings.miso.data.SparseMisoSceneModel.Section;
|
||||
import com.threerings.miso.data.SparseMisoSceneModel;
|
||||
|
||||
/**
|
||||
* Generates an XML representation of a {@link SparseMisoSceneModel}.
|
||||
*/
|
||||
public class SparseMisoSceneWriter implements NestableWriter
|
||||
{
|
||||
/** The element used to enclose scene models written with this
|
||||
* writer. */
|
||||
public static final String OUTER_ELEMENT = "miso";
|
||||
|
||||
// documentation inherited from interface
|
||||
public void write (Object object, DataWriter writer)
|
||||
throws SAXException
|
||||
{
|
||||
SparseMisoSceneModel model = (SparseMisoSceneModel)object;
|
||||
writer.startElement(OUTER_ELEMENT);
|
||||
writeSceneData(model, writer);
|
||||
writer.endElement(OUTER_ELEMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes just the scene data which is handy for derived classes which
|
||||
* may wish to add their own scene data to the scene output.
|
||||
*/
|
||||
protected void writeSceneData (SparseMisoSceneModel model,
|
||||
DataWriter writer)
|
||||
throws SAXException
|
||||
{
|
||||
writer.dataElement("swidth", Integer.toString(model.swidth));
|
||||
writer.dataElement("sheight", Integer.toString(model.sheight));
|
||||
|
||||
writer.startElement("sections");
|
||||
for (Iterator iter = model.getSections(); iter.hasNext(); ) {
|
||||
Section sect = (Section)iter.next();
|
||||
AttributesImpl attrs = new AttributesImpl();
|
||||
attrs.addAttribute("", "x", "", "", String.valueOf(sect.x));
|
||||
attrs.addAttribute("", "y", "", "", String.valueOf(sect.y));
|
||||
attrs.addAttribute("", "width", "", "", String.valueOf(sect.width));
|
||||
writer.startElement("", "section", "", attrs);
|
||||
|
||||
writer.dataElement(
|
||||
"base", StringUtil.toString(sect.baseTileIds, "", ""));
|
||||
|
||||
// write our uninteresting object tile information
|
||||
writer.startElement("objects");
|
||||
for (int ii = 0; ii < sect.objectTileIds.length; ii++) {
|
||||
attrs = new AttributesImpl();
|
||||
attrs.addAttribute("", "tileId", "", "",
|
||||
String.valueOf(sect.objectTileIds[ii]));
|
||||
attrs.addAttribute("", "x", "", "",
|
||||
String.valueOf(sect.objectXs[ii]));
|
||||
attrs.addAttribute("", "y", "", "",
|
||||
String.valueOf(sect.objectYs[ii]));
|
||||
writer.emptyElement("", "object", "", attrs);
|
||||
}
|
||||
|
||||
// write our interesting object tile information
|
||||
for (int ii = 0; ii < sect.objectInfo.length; ii++) {
|
||||
ObjectInfo info = sect.objectInfo[ii];
|
||||
attrs = new AttributesImpl();
|
||||
attrs.addAttribute("", "tileId", "", "",
|
||||
String.valueOf(info.tileId));
|
||||
attrs.addAttribute("", "x", "", "", String.valueOf(info.x));
|
||||
attrs.addAttribute("", "y", "", "", String.valueOf(info.y));
|
||||
|
||||
if (!StringUtil.blank(info.action)) {
|
||||
attrs.addAttribute("", "action", "", "", info.action);
|
||||
}
|
||||
if (info.priority != 0) {
|
||||
attrs.addAttribute("", "priority", "", "",
|
||||
String.valueOf(info.priority));
|
||||
}
|
||||
if (info.sx != 0 || info.sy != 0) {
|
||||
attrs.addAttribute("", "sx", "", "",
|
||||
String.valueOf(info.sx));
|
||||
attrs.addAttribute("", "sy", "", "",
|
||||
String.valueOf(info.sy));
|
||||
attrs.addAttribute("", "sorient", "", "",
|
||||
String.valueOf(info.sorient));
|
||||
}
|
||||
if (info.zations != 0) {
|
||||
attrs.addAttribute("", "zations", "", "",
|
||||
String.valueOf(info.zations));
|
||||
}
|
||||
writer.emptyElement("", "object", "", attrs);
|
||||
}
|
||||
writer.endElement("objects");
|
||||
writer.endElement("section");
|
||||
}
|
||||
writer.endElement("sections");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: MisoSceneMetrics.java,v 1.1 2003/04/17 19:21:16 mdb Exp $
|
||||
// $Id: MisoSceneMetrics.java,v 1.2 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.util;
|
||||
|
||||
@@ -23,22 +23,9 @@ public class MisoSceneMetrics
|
||||
/** Number of fine coordinates on each axis within a tile. */
|
||||
public int finegran;
|
||||
|
||||
/** Size of the view in tile count. */
|
||||
public int scenevwid, scenevhei;
|
||||
|
||||
/** Dimensions of our scene blocks in tile count. */
|
||||
public int blockwid = 10, blockhei = 10;
|
||||
|
||||
/** Whether or not this view can extend beyond the bounds defined by
|
||||
* the view width and height. True if it cannot, false if it can. */
|
||||
public boolean bounded = true;
|
||||
|
||||
/** The bounds of the view in screen pixel coordinates. */
|
||||
public Rectangle bounds;
|
||||
|
||||
/** The position in pixels at which tile (0, 0) is drawn. */
|
||||
public Point origin;
|
||||
|
||||
/** The length of a tile edge in pixels. */
|
||||
public float tilelen;
|
||||
|
||||
@@ -62,26 +49,13 @@ public class MisoSceneMetrics
|
||||
* @param tilehei the height in pixels of the tiles.
|
||||
* @param finegran the number of sub-tile divisions to use for fine
|
||||
* coordinates.
|
||||
* @param svwid the width in tiles of the viewport.
|
||||
* @param svhei the height in tiles of the viewport.
|
||||
* @param offy the offset of the origin (in tiles) from the top of the
|
||||
* viewport.
|
||||
*/
|
||||
public MisoSceneMetrics (int tilewid, int tilehei, int finegran,
|
||||
int svwid, int svhei, int offy)
|
||||
public MisoSceneMetrics (int tilewid, int tilehei, int finegran)
|
||||
{
|
||||
// keep track of this stuff
|
||||
this.tilewid = tilewid;
|
||||
this.tilehei = tilehei;
|
||||
this.finegran = finegran;
|
||||
this.scenevwid = svwid;
|
||||
this.scenevhei = svhei;
|
||||
|
||||
// set the desired scene view bounds
|
||||
bounds = new Rectangle(0, 0, scenevwid * tilewid, scenevhei * tilehei);
|
||||
|
||||
// set the scene display origin
|
||||
origin = new Point((bounds.width / 2), (offy * tilehei));
|
||||
|
||||
// halve the dimensions
|
||||
tilehwid = (tilewid / 2);
|
||||
@@ -107,28 +81,4 @@ public class MisoSceneMetrics
|
||||
finehwid = (int)((float)tilehwid / (float)finegran);
|
||||
finehhei = (int)((float)tilehhei / (float)finegran);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given tile coordinate is a valid coordinate in
|
||||
* our coordinate system (which allows tile coordinates from 0 to
|
||||
* 2^15-1).
|
||||
*/
|
||||
public boolean isCoordinateValid (int x, int y)
|
||||
{
|
||||
return (x >= 0 && x < Short.MAX_VALUE &&
|
||||
y >= 0 && y < Short.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given full coordinate is a valid coordinate
|
||||
* within the scene.
|
||||
*/
|
||||
public boolean isFullCoordinateValid (int x, int y)
|
||||
{
|
||||
int tx = MisoUtil.fullToTile(x), ty = MisoUtil.fullToTile(y);
|
||||
int fx = MisoUtil.fullToFine(x), fy = MisoUtil.fullToFine(y);
|
||||
return (isCoordinateValid(tx, ty) &&
|
||||
fx >= 0 && fx < finegran &&
|
||||
fy >= 0 && fy < finegran);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: MisoUtil.java,v 1.20 2003/04/18 22:59:04 mdb Exp $
|
||||
// $Id: MisoUtil.java,v 1.21 2003/04/19 22:40:34 mdb Exp $
|
||||
|
||||
package com.threerings.miso.util;
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.samskivert.swing.SmartPolygon;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.media.sprite.Sprite;
|
||||
import com.threerings.media.util.MathUtil;
|
||||
@@ -16,6 +17,7 @@ import com.threerings.util.DirectionCodes;
|
||||
import com.threerings.util.DirectionUtil;
|
||||
|
||||
import com.threerings.miso.Log;
|
||||
import com.threerings.miso.MisoConfig;
|
||||
|
||||
/**
|
||||
* Miscellaneous isometric-display-related utility routines.
|
||||
@@ -47,11 +49,11 @@ public class MisoUtil
|
||||
screenToFull(metrics, bx, by, bfpos);
|
||||
|
||||
// pull out the tile coordinates for each point
|
||||
int tax = afpos.x / FULL_TILE_FACTOR;
|
||||
int tay = afpos.y / FULL_TILE_FACTOR;
|
||||
int tax = fullToTile(afpos.x);
|
||||
int tay = fullToTile(afpos.y);
|
||||
|
||||
int tbx = bfpos.x / FULL_TILE_FACTOR;
|
||||
int tby = bfpos.y / FULL_TILE_FACTOR;
|
||||
int tbx = fullToTile(bfpos.x);
|
||||
int tby = fullToTile(bfpos.y);
|
||||
|
||||
// compare tile coordinates to determine direction
|
||||
int dir = getIsoDirection(tax, tay, tbx, tby);
|
||||
@@ -159,7 +161,7 @@ public class MisoUtil
|
||||
*/
|
||||
public static int fullToTile (int val)
|
||||
{
|
||||
return (val / FULL_TILE_FACTOR);
|
||||
return MathUtil.floorDiv(val, FULL_TILE_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +169,7 @@ public class MisoUtil
|
||||
*/
|
||||
public static int fullToFine (int val)
|
||||
{
|
||||
return (val - ((val / FULL_TILE_FACTOR) * FULL_TILE_FACTOR));
|
||||
return (val - (fullToTile(val) * FULL_TILE_FACTOR));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,14 +189,11 @@ public class MisoUtil
|
||||
{
|
||||
// determine the upper-left of the quadrant that contains our
|
||||
// point
|
||||
int zx = (int)Math.floor((float)(sx - metrics.origin.x) /
|
||||
metrics.tilewid);
|
||||
int zy = (int)Math.floor((float)(sy - metrics.origin.y) /
|
||||
metrics.tilehei);
|
||||
int zx = (int)Math.floor((float)sx / metrics.tilewid);
|
||||
int zy = (int)Math.floor((float)sy / metrics.tilehei);
|
||||
|
||||
// these are the screen coordinates of the tile's top
|
||||
int ox = (zx * metrics.tilewid + metrics.origin.x),
|
||||
oy = (zy * metrics.tilehei + metrics.origin.y);
|
||||
int ox = (zx * metrics.tilewid), oy = (zy * metrics.tilehei);
|
||||
|
||||
// these are the tile coordinates
|
||||
tpos.x = zy + zx; tpos.y = zy - zx;
|
||||
@@ -235,8 +234,8 @@ public class MisoUtil
|
||||
public static Point tileToScreen (
|
||||
MisoSceneMetrics metrics, int x, int y, Point spos)
|
||||
{
|
||||
spos.x = metrics.origin.x + ((x - y - 1) * metrics.tilehwid);
|
||||
spos.y = metrics.origin.y + ((x + y) * metrics.tilehhei);
|
||||
spos.x = (x - y - 1) * metrics.tilehwid;
|
||||
spos.y = (x + y) * metrics.tilehhei;
|
||||
return spos;
|
||||
}
|
||||
|
||||
@@ -289,6 +288,9 @@ public class MisoUtil
|
||||
// determine distance along the y-axis
|
||||
float ydist = MathUtil.distance(x, y, crossx, crossy);
|
||||
fpos.y = (int)(ydist / metrics.finelen);
|
||||
|
||||
// Log.info("Pixel to fine " + StringUtil.coordsToString(x, y) +
|
||||
// " -> " + StringUtil.toString(fpos) + ".");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,6 +315,13 @@ public class MisoUtil
|
||||
// get the screen coordinates for the containing tile
|
||||
Point spos = tileToScreen(metrics, tpos.x, tpos.y, new Point());
|
||||
|
||||
// Log.info("Screen to full " +
|
||||
// "[screen=" + StringUtil.coordsToString(sx, sy) +
|
||||
// ", tpos=" + StringUtil.toString(tpos) +
|
||||
// ", spos=" + StringUtil.toString(spos) +
|
||||
// ", fpix=" + StringUtil.coordsToString(
|
||||
// sx-spos.x, sy-spos.y) + "].");
|
||||
|
||||
// get the fine coordinates within the containing tile
|
||||
pixelToFine(metrics, sx - spos.x, sy - spos.y, fpos);
|
||||
|
||||
@@ -338,7 +347,7 @@ public class MisoUtil
|
||||
MisoSceneMetrics metrics, int x, int y, Point spos)
|
||||
{
|
||||
// get the tile screen position
|
||||
int tx = x / FULL_TILE_FACTOR, ty = y / FULL_TILE_FACTOR;
|
||||
int tx = fullToTile(x), ty = fullToTile(y);
|
||||
Point tspos = tileToScreen(metrics, tx, ty, new Point());
|
||||
|
||||
// get the pixel position of the fine coords within the tile
|
||||
|
||||
Reference in New Issue
Block a user