Behold, Nenya, Ring of Water and repository for our media and animation related

goodies, both Java 2D and LWJGL/JME 3D.


git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@1 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Michael Bayne
2006-06-23 18:07:28 +00:00
commit c2117ee86d
570 changed files with 61913 additions and 0 deletions
@@ -0,0 +1,129 @@
//
// $Id: MisoSceneModel.java 3726 2005-10-11 19:17:43Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.miso.data;
import java.awt.Rectangle;
import java.util.Random;
import com.threerings.io.SimpleStreamableObject;
import com.threerings.miso.util.ObjectSet;
/**
* Contains basic information for a miso scene model that is shared among
* the specialized model implementations.
*/
public abstract class MisoSceneModel extends SimpleStreamableObject
implements Cloneable
{
/**
* Creates a completely uninitialized model suitable for little more
* than unserialization.
*/
public MisoSceneModel ()
{
}
/**
* Returns the fully qualified tile id of the base tile at the
* specified coordinates. <code>-1</code> will be returned if there is
* no tile at the specified coordinate.
*/
public abstract int getBaseTileId (int x, int y);
/**
* Updates the tile at the specified location in the base layer.
*
* <p> Note that if there are fringe tiles associated with this scene,
* calling this method may result in the surrounding fringe tiles
* being cleared and subsequently recalculated. This should not be
* called on a displaying scene unless you know what you are doing.
*
* @param fqTileId the fully-qualified tile id (@see
* TileUtil#getFQTileId}) of the tile to set.
* @param x the x-coordinate of the tile to set.
* @param y the y-coordinate of the tile to set.
*
* @return false if the specified tile coordinates are outside of the
* scene and the tile was not saved, true otherwise.
*/
public abstract boolean setBaseTile (int fqTileId, int x, int y);
/**
* Updates the default base tileset id for this scene.
*/
public void setDefaultBaseTileSet (int tileSetId)
{
// nothing doing
}
/**
* Scene models can return a default tileset to be used when no base
* tile data exists for a particular tile.
*/
public int getDefaultBaseTileSet ()
{
return 0;
}
/**
* Populates the supplied object set with info on all objects whose
* origin falls in the requested region.
*/
public abstract void getObjects (Rectangle region, ObjectSet set);
/**
* Adds an object to this scene.
*
* @return true if the object was added, false if the add was rejected
* due to being a duplicate.
*/
public abstract boolean addObject (ObjectInfo info);
/**
* Updates an object in this scene.
*/
public abstract void updateObject (ObjectInfo info);
/**
* Removes the specified object from the scene.
*
* @return true if it was removed, false if the object was not in the
* scene.
*/
public abstract boolean removeObject (ObjectInfo info);
/**
* Creates a copy of this scene model.
*/
public Object clone ()
{
try {
return (MisoSceneModel)super.clone();
} catch (CloneNotSupportedException cnse) {
throw new RuntimeException("MisoSceneModel.clone: " + cnse);
}
}
/** A random number generator for filling random base tiles. */
protected transient Random _rando = new Random();
}
@@ -0,0 +1,168 @@
//
// $Id: ObjectInfo.java 3749 2005-11-09 04:00:16Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.miso.data;
import com.samskivert.util.StringUtil;
import com.threerings.io.SimpleStreamableObject;
import com.threerings.media.tile.TileUtil;
/**
* Contains information about an object in a Miso scene.
*/
public class ObjectInfo extends SimpleStreamableObject
implements Cloneable
{
/** The fully qualified object tile id. */
public int tileId;
/** The x and y tile coordinates of the object. */
public int x, y;
/** Don't access this directly unless you are serializing this
* instance. Use {@link #getPriority} instead. */
public byte priority = 0;
/** The action associated with this object or null if it has no
* action. */
public String action;
/** A "spot" associated with this object (specified as an offset from
* the fine coordinates of the object's origin tile). */
public byte sx, sy;
/** The orientation of the "spot" associated with this object. */
public byte sorient;
/** Up to two colorization assignments for this object. */
public int zations;
/**
* Convenience constructor.
*/
public ObjectInfo (int tileId, int x, int y)
{
this.tileId = tileId;
this.x = x;
this.y = y;
}
/**
* Creates an object info that is a copy of the supplied info.
*/
public ObjectInfo (ObjectInfo other)
{
this.tileId = other.tileId;
this.x = other.x;
this.y = other.y;
this.priority = other.priority;
this.action = other.action;
this.sx = other.sx;
this.sy = other.sy;
this.sorient = other.sorient;
this.zations = other.zations;
}
/**
* Zero argument constructor needed for unserialization.
*/
public ObjectInfo ()
{
}
/**
* Returns the render priority of this object tile.
*/
public int getPriority ()
{
return priority;
}
/**
* Returns the primary colorization assignment.
*/
public int getPrimaryZation ()
{
return (zations & 0xFFFF);
}
/**
* Returns the secondary colorization assignment.
*/
public int getSecondaryZation ()
{
return ((zations >> 16) & 0xFFFF);
}
/**
* Sets the primary and secondary colorization assignments.
*/
public void setZations (short primary, short secondary)
{
zations = ((secondary << 16) | primary);
}
/**
* Returns true if this object info contains non-default data for
* anything other than the tile id and coordinates.
*/
public boolean isInteresting ()
{
return (!StringUtil.isBlank(action) || priority != 0 ||
sx != 0 || sy != 0 || zations != 0);
}
// documentation inherited
public boolean equals (Object other)
{
if (other instanceof ObjectInfo) {
ObjectInfo ooi = (ObjectInfo)other;
return (x == ooi.x && y == ooi.y && tileId == ooi.tileId);
} else {
return false;
}
}
// documentation inherited
public int hashCode ()
{
return x ^ y ^ tileId;
}
// documentation inherited
public Object clone ()
{
try {
return super.clone();
} catch (CloneNotSupportedException cnse) {
// notgunnahappen.
return null;
}
}
/** Enhances our {@link SimpleStreamableObject#toString} output. */
public String tileIdToString ()
{
return (TileUtil.getTileSetId(tileId) + ":" +
TileUtil.getTileIndex(tileId));
}
}
@@ -0,0 +1,282 @@
//
// $Id: SimpleMisoSceneModel.java 4191 2006-06-13 22:42:20Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.miso.data;
import java.awt.Rectangle;
import java.util.ArrayList;
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;
/**
* Contains miso scene data for a scene that is assumed to be reasonably
* simple and small, such that all base tile data for the entire scene can
* be stored in a single contiguous array.
*
* <p> Additionally, it makes the assumption that the single model will be
* used to display a scene on a rectangular screen (dimensions defined by
* {@link #vwidth} and {@link #vheight}) and further optimizes the base
* tile array to obviate the need to store tile data for things that fall
* outside the bounds of the screen.
*/
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;
/** The viewport height in tiles. */
public int vheight;
/** The combined tile ids (tile set id and tile id) in compressed
* format. Don't go poking around in here, use the accessor
* methods. */
public int[] baseTileIds;
/** The combined tile ids (tile set id and tile id) of the
* "uninteresting" tiles in the object layer. */
public int[] objectTileIds;
/** The x coordinate of the "uninteresting" tiles in the object
* layer. */
public short[] objectXs;
/** The y coordinate of the "uninteresting" tiles in the object
* layer. */
public short[] objectYs;
/** Information records for the "interesting" objects in the object
* layer. */
public ObjectInfo[] objectInfo;
/**
* Creates a completely uninitialized model suitable for little more
* than unserialization.
*/
public SimpleMisoSceneModel ()
{
}
/**
* Creates a blank scene model with the specified dimensions.
*/
public SimpleMisoSceneModel (int width, int height, int vwidth, int vheight)
{
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();
// start with zero-length object arrays
objectTileIds = new int[0];
objectXs = new short[0];
objectYs = new short[0];
objectInfo = new ObjectInfo[0];
}
// documentation inherited
public int getBaseTileId (int col, int row)
{
int index = getIndex(col, row);
return (index == -1) ? 0 : baseTileIds[index];
}
// documentation inherited
public boolean setBaseTile (int fqBaseTileId, int col, int row)
{
int index = getIndex(col, row);
if (index == -1) {
return false;
}
baseTileIds[index] = fqBaseTileId;
return true;
}
// documentation inherited
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));
}
}
}
// documentation inherited
public boolean 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);
}
return true;
}
// 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)
{
// look for it in the interesting info array
int oidx = ListUtil.indexOf(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;
}
// documentation inherited
public Object clone ()
{
SimpleMisoSceneModel model = (SimpleMisoSceneModel)super.clone();
model.baseTileIds = (int[])baseTileIds.clone();
model.objectTileIds = (int[])objectTileIds.clone();
model.objectXs = (short[])objectXs.clone();
model.objectYs = (short[])objectYs.clone();
model.objectInfo = (ObjectInfo[])objectInfo.clone();
return model;
}
/**
* Get the index into the baseTileIds[] for the specified
* x and y coordinates, or return -1 if the specified coordinates
* are outside of the viewable area.
*
* Assumption: The viewable area is centered and aligned as far
* to the top of the isometric scene as possible, such that
* the upper-left corner is at the point where the tiles
* (0, vwid) and (0, vwid-1) touch. The upper-right corner
* is at the point where the tiles (vwid-1, 0) and (vwid, 0)
* touch.
*
* The viewable area is made up of "fat" rows and "thin" rows. The
* fat rows display one more tile than the thin rows because their
* first and last tiles are halfway off the viewable area. The thin
* rows are fully contained within the viewable area except for the
* first and last thin rows, which display only their bottom and top
* halves, respectively. Note that #fatrows == #thinrows - 1;
*/
protected int getIndex (int x, int y)
{
// check to see if the index lies in one of the "fat" rows
if (((x + y) & 1) == (vwidth & 1)) {
int col = (vwidth + x - y) >> 1;
int row = x - col;
if ((col < 0) || (col > vwidth) ||
(row < 0) || (row >= vheight)) {
return -1; // out of view
}
return (vwidth + 1) * row + col;
} else {
// the index must be in a "thin" row
int col = (vwidth + x - y - 1) >> 1;
int row = x - col;
if ((col < 0) || (col >= vwidth) ||
(row < 0) || (row > vheight)) {
return -1; // out of view
}
// we store the all the fat rows first, then all the thin
// rows, the '(vwidth + 1) * vheight' is the size of all
// the fat rows.
return row * vwidth + col + (vwidth + 1) * vheight;
}
}
/**
* Allocate the base tile array.
*/
protected void allocateBaseTileArray ()
{
baseTileIds = new int[vwidth + vheight + ((vwidth * vheight) << 1)];
}
/**
* Populates the interesting and uninteresting parts of a miso scene
* model given lists of {@link ObjectInfo} records for each.
*/
public static void populateObjects (SimpleMisoSceneModel model,
ArrayList ilist, ArrayList ulist)
{
// set up the uninteresting arrays
int ucount = ulist.size();
model.objectTileIds = new int[ucount];
model.objectXs = new short[ucount];
model.objectYs = new short[ucount];
for (int ii = 0; ii < ucount; ii++) {
ObjectInfo info = (ObjectInfo)ulist.get(ii);
model.objectTileIds[ii] = info.tileId;
model.objectXs[ii] = (short)info.x;
model.objectYs[ii] = (short)info.y;
}
// set up the interesting array
int icount = ilist.size();
model.objectInfo = new ObjectInfo[icount];
ilist.toArray(model.objectInfo);
}
}
@@ -0,0 +1,445 @@
//
// $Id: SparseMisoSceneModel.java 4191 2006-06-13 22:42:20Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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.ListUtil;
import com.samskivert.util.StringUtil;
import com.threerings.io.SimpleStreamableObject;
import com.threerings.media.util.MathUtil;
import com.threerings.util.StreamableHashIntMap;
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 (ObjectInfo info);
}
/** 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 boolean addObject (ObjectInfo info) {
// sanity check: see if there is already an object of this
// type at these coordinates
int dupidx;
if ((dupidx = ListUtil.indexOf(objectInfo, info)) != -1) {
Log.warning("Refusing to add duplicate object [ninfo=" + info +
", oinfo=" + objectInfo[dupidx] + "].");
return false;
}
if ((dupidx = indexOfUn(info)) != -1) {
Log.warning("Refusing to add duplicate object " +
"[info=" + info + "].");
return false;
}
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);
}
return true;
}
public boolean removeObject (ObjectInfo info) {
// look for it in the interesting info array
int oidx = ListUtil.indexOf(objectInfo, info);
if (oidx != -1) {
objectInfo = (ObjectInfo[])
ArrayUtil.splice(objectInfo, oidx, 1);
return true;
}
// look for it in the uninteresting arrays
oidx = indexOfUn(info);
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;
}
/**
* Returns the index of the specified object in the uninteresting
* arrays or -1 if it is not in this section as an uninteresting
* object.
*/
protected int indexOfUn (ObjectInfo info)
{
for (int ii = 0; ii < objectTileIds.length; ii++) {
if (objectTileIds[ii] == info.tileId &&
objectXs[ii] == info.x && objectYs[ii] == info.y) {
return ii;
}
}
return -1;
}
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));
}
}
}
/**
* Returns true if this section contains no data beyond the default.
* Used when saving a sparse scene: we omit blank sections.
*/
public boolean isBlank ()
{
if ((objectTileIds.length != 0) || (objectInfo.length != 0)) {
return false;
}
for (int ii=0, nn=baseTileIds.length; ii < nn; ii++) {
if (baseTileIds[ii] != 0) {
return false;
}
}
return true;
}
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;
/** The tileset to use when we have no tile data. */
public int defTileSet = 0;
/**
* 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)
{
visitObjects(visitor, false);
}
/**
* Informs the supplied visitor of each object in this scene.
*
* @param interestingOnly if true, only the interesting objects will
* be visited.
*/
public void visitObjects (ObjectVisitor visitor, boolean interestingOnly)
{
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);
}
if (!interestingOnly) {
ObjectInfo info = new ObjectInfo();
for (int oo = 0; oo < sect.objectTileIds.length; oo++) {
info.tileId = sect.objectTileIds[oo];
info.x = sect.objectXs[oo];
info.y = sect.objectYs[oo];
visitor.visit(info);
}
}
}
}
// 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 setDefaultBaseTileSet (int tileSetId)
{
defTileSet = tileSetId;
}
// documentation inherited
public int getDefaultBaseTileSet ()
{
return defTileSet;
}
// documentation inherited
public void getObjects (Rectangle region, ObjectSet set)
{
int minx = MathUtil.floorDiv(region.x, swidth)*swidth;
int maxx = MathUtil.floorDiv(region.x+region.width-1, swidth)*swidth;
int miny = MathUtil.floorDiv(region.y, sheight)*sheight;
int maxy = MathUtil.floorDiv(region.y+region.height-1, sheight)*sheight;
for (int yy = miny; yy <= maxy; yy += sheight) {
for (int xx = minx; xx <= maxx; xx += swidth) {
Section sec = getSection(xx, yy, false);
if (sec != null) {
sec.getObjects(region, set);
}
}
}
}
// documentation inherited
public boolean addObject (ObjectInfo info)
{
return 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();
}
// documentation inherited
protected void toString (StringBuilder buf)
{
super.toString(buf);
buf.append(", sections=" +
StringUtil.toString(_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 StreamableHashIntMap();
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 StreamableHashIntMap _sections = new StreamableHashIntMap();
}
@@ -0,0 +1,58 @@
//
// $Id: VirtualMisoSceneModel.java 4191 2006-06-13 22:42:20Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.miso.data;
/**
* A convenient base class for "virtual" scenes which do not allow editing
* and compute the base and object tiles rather than obtain them from some
* data structure.
*/
public abstract class VirtualMisoSceneModel extends MisoSceneModel
{
public VirtualMisoSceneModel ()
{
}
// documentation inherited from interface
public boolean setBaseTile (int fqTileId, int x, int y)
{
throw new UnsupportedOperationException();
}
// documentation inherited from interface
public boolean addObject (ObjectInfo info)
{
throw new UnsupportedOperationException();
}
// documentation inherited from interface
public void updateObject (ObjectInfo info)
{
throw new UnsupportedOperationException();
}
// documentation inherited from interface
public boolean removeObject (ObjectInfo info)
{
throw new UnsupportedOperationException();
}
}