Changed MisoSceneModel so that it knows about the view width and height.

It no longer stores base tiles that are not visable in the view,
in fact it stores the base tiles in an array almost half the size as the
fully expanded scene array, and this new smaller array is used everywhere:
when saving the scene, serializing it to the user, or saving it in
the database.
We must now use the getBaseTile() and setBaseTile() methods to access the
base tiles because they are stored in this compressed format.
Also removed the fringe layer completely from the MisoSceneModel.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1369 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2002-05-17 19:06:23 +00:00
parent ab242f4a71
commit bb6b0f56ca
7 changed files with 180 additions and 86 deletions
@@ -1,5 +1,5 @@
//
// $Id: DisplayMisoSceneImpl.java,v 1.57 2002/05/03 04:12:48 mdb Exp $
// $Id: DisplayMisoSceneImpl.java,v 1.58 2002/05/17 19:06:23 ray Exp $
package com.threerings.miso.scene;
@@ -117,7 +117,7 @@ public class DisplayMisoSceneImpl
for (int column = 0; column < shei; column++) {
for (int row = 0; row < swid; row++) {
// first do the base layer
int tsid = _model.baseTileIds[swid*row+column];
int tsid = _model.getBaseTile(column, row);
if (tsid > 0) {
int tid = (tsid & 0xFFFF);
tsid >>= 16;
@@ -130,15 +130,6 @@ public class DisplayMisoSceneImpl
BaseTile mtile = (BaseTile)_tmgr.getTile(tsid, tid);
_base.setTile(column, row, mtile);
}
// then the fringe layer
tsid = _model.fringeTileIds[swid*row+column];
if (tsid > 0) {
int tid = (tsid & 0xFFFF);
tsid >>= 16;
Tile tile = _tmgr.getTile(tsid, tid);
_fringe.setTile(column, row, tile);
}
}
}
@@ -1,5 +1,5 @@
//
// $Id: IsoSceneViewModel.java,v 1.23 2002/03/28 22:32:32 mdb Exp $
// $Id: IsoSceneViewModel.java,v 1.24 2002/05/17 19:06:23 ray Exp $
package com.threerings.miso.scene;
@@ -34,6 +34,9 @@ public class IsoSceneViewModel
/** Scene dimensions in tile count. */
public int scenewid, scenehei;
/** Size of the view in tile count. */
public int scenevwid, scenevhei;
/** The bounds of the view in screen pixel coordinates. */
public Rectangle bounds;
@@ -87,6 +90,12 @@ public class IsoSceneViewModel
scenehei = MisoConfig.config.getValue(
SCENE_HEIGHT_KEY, DEF_SCENE_HEIGHT);
// and the view dimensions
scenevwid = MisoConfig.config.getValue(
SCENE_VWIDTH_KEY, DEF_SCENE_VWIDTH);
scenevhei = MisoConfig.config.getValue(
SCENE_VHEIGHT_KEY, DEF_SCENE_VHEIGHT);
// get the tile dimensions
tilewid = MisoConfig.config.getValue(TILE_WIDTH_KEY, DEF_TILE_WIDTH);
tilehei = MisoConfig.config.getValue(TILE_HEIGHT_KEY, DEF_TILE_HEIGHT);
@@ -102,12 +111,8 @@ public class IsoSceneViewModel
SHOW_FOOTPRINTS_KEY, DEF_SHOW_FOOTPRINTS);
// precalculate various things
int svwid = MisoConfig.config.getValue(
SCENE_VWIDTH_KEY, DEF_SCENE_VWIDTH);
int svhei = MisoConfig.config.getValue(
SCENE_VHEIGHT_KEY, DEF_SCENE_VHEIGHT);
int offy = MisoConfig.config.getValue(SCENE_OFFSET_Y_KEY, DEF_OFFSET_Y);
precalculate(svwid, svhei, offy);
precalculate(offy);
}
/**
@@ -135,11 +140,13 @@ public class IsoSceneViewModel
this.tilewid = tilewid;
this.tilehei = tilehei;
this.finegran = finegran;
this.scenevwid = svwid;
this.scenevhei = svhei;
// let our flags default to false
// precalculate various things
precalculate(svwid, svhei, offy);
precalculate(offy);
}
/**
@@ -203,10 +210,10 @@ public class IsoSceneViewModel
* Pre-calculate various member data that are commonly used in working
* with an isometric view.
*/
protected void precalculate (int svwid, int svhei, int offy)
protected void precalculate (int offy)
{
// set the desired scene view bounds
bounds = new Rectangle(0, 0, svwid * tilewid, svhei * tilehei);
bounds = new Rectangle(0, 0, scenevwid * tilewid, scenevhei * tilehei);
// set the scene display origin
origin = new Point((bounds.width / 2), (offy * tilehei));
@@ -1,5 +1,5 @@
//
// $Id: MisoSceneModel.java,v 1.7 2002/05/16 03:54:18 mdb Exp $
// $Id: MisoSceneModel.java,v 1.8 2002/05/17 19:06:23 ray Exp $
package com.threerings.miso.scene;
@@ -12,6 +12,8 @@ import java.nio.IntBuffer;
import com.samskivert.util.StringUtil;
import com.threerings.miso.Log;
/**
* The scene model is the bare bones representation of the data for a
* scene in the Miso system. From the scene model, one would create an
@@ -26,13 +28,16 @@ public class MisoSceneModel
/** The height of the scene in tile units. */
public int height;
/** The combined tile ids (tile set id and tile id) of the tiles in
* the base layer, in row-major order. */
public int[] baseTileIds;
/** The viewport width in tiles. */
public int vwidth;
/** The combined tile ids (tile set id and tile id) of the tiles in
* the fringe layer, in row-major order. */
public int[] fringeTileIds;
/** 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 files in
* the object layer in (x, y, tile id) format. */
@@ -44,25 +49,102 @@ public class MisoSceneModel
* empty string during serialization. */
public String[] objectActions;
/**
* Get the fully-qualified tile id of the base tile at the specified
* row and column.
*/
public int getBaseTile (int col, int row)
{
int index = getIndex(col, row);
return (index == -1) ? 0 : baseTileIds[index];
}
/**
* Set the fully-qualified tile id of a base tile.
*
* @return false if the specified tile coordinates are outside
* of the viewport and the tile was not saved.
*/
public boolean setBaseTile (int col, int row, int fqBaseTileId)
{
int index = getIndex(col, row);
if (index == -1) {
return false;
}
baseTileIds[index] = fqBaseTileId;
return true;
}
/**
* 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;
}
}
// documentation inherited
public void writeTo (DataOutputStream out)
throws IOException
{
int tcount = width*height;
int otc = objectTileIds.length;
int btc = baseTileIds.length;
// write everything into a ByteBuffer, viewed as an IntBuffer and
// then write the bytes from those operations out to the output
// stream
ByteBuffer bbuf = ByteBuffer.allocate(4*tcount + 4*otc + 4*3);
ByteBuffer bbuf = ByteBuffer.allocate(4*(btc + otc + 5));
IntBuffer ibuf = bbuf.asIntBuffer();
// insert the dimensions
ibuf.put(width);
ibuf.put(height);
ibuf.put(vwidth);
ibuf.put(vheight);
ibuf.put(otc);
// insert the layer data (except fringe)
// insert the layer data
ibuf.put(baseTileIds);
ibuf.put(objectTileIds);
@@ -85,18 +167,16 @@ public class MisoSceneModel
// what the data input stream expects
width = in.readInt();
height = in.readInt();
vwidth = in.readInt();
vheight = in.readInt();
int otc = in.readInt();
// read in the base layer
int tcount = width*height;
baseTileIds = new int[tcount];
for (int i = 0; i < tcount; i++) {
allocateBaseTileArray();
for (int i = 0; i < baseTileIds.length; i++) {
baseTileIds[i] = in.readInt();
}
// allocate, but don't read, the fringe layer
fringeTileIds = new int[tcount];
// read in the object layer
objectTileIds = new int[otc];
for (int i = 0; i < otc; i++) {
@@ -110,14 +190,50 @@ public class MisoSceneModel
}
}
/**
* Convert an old school model to the new-style, baby.
* TODO: Remove this method someday after we've converted all
* our old scenes.
*/
public void convertOldSchool (int vwidth, int vheight)
{
// sanity check
if (baseTileIds.length != (width * height)) {
Log.warning("This isn't an old-school scene model!");
return;
}
this.vwidth = vwidth;
this.vheight = vheight;
// make a copy of the oldschool base tile ids
int[] oldschool = baseTileIds;
allocateBaseTileArray();
int idx = 0;
for (int yy=0; yy < height; yy++) {
for (int xx=0; xx < width; xx++) {
setBaseTile(xx, yy, oldschool[idx++]);
}
}
}
/**
* Allocate the base tile array.
*/
protected void allocateBaseTileArray ()
{
baseTileIds = new int[vwidth + vheight + ((vwidth * vheight) << 1)];
}
/**
* Generates a string representation of this scene model.
*/
public String toString ()
{
return "[width=" + width + ", height=" + height +
", vwidth=" + vwidth + ", vheight=" + vheight +
", baseTileIds=" + StringUtil.toString(baseTileIds) +
", fringeTileIds=" + StringUtil.toString(fringeTileIds) +
", objectTileIds=" + StringUtil.toString(objectTileIds) +
", objectActions=" + StringUtil.toString(objectActions) + "]";
}
@@ -130,7 +246,6 @@ public class MisoSceneModel
{
MisoSceneModel model = (MisoSceneModel)super.clone();
model.baseTileIds = (int[])baseTileIds.clone();
model.fringeTileIds = (int[])fringeTileIds.clone();
model.objectTileIds = (int[])objectTileIds.clone();
model.objectActions = (String[])objectActions.clone();
return model;
@@ -143,7 +258,7 @@ public class MisoSceneModel
public static MisoSceneModel blankMisoSceneModel ()
{
MisoSceneModel model = new MisoSceneModel();
populateBlankMisoSceneModel(model, 0, 0);
populateBlankMisoSceneModel(model, 0, 0, 0, 0);
return model;
}
@@ -151,10 +266,11 @@ public class MisoSceneModel
* Creates and returns a blank scene model with the specified width
* and height.
*/
public static MisoSceneModel blankMisoSceneModel (int width, int height)
public static MisoSceneModel blankMisoSceneModel (
int width, int height, int vwidth, int vheight)
{
MisoSceneModel model = new MisoSceneModel();
populateBlankMisoSceneModel(model, width, height);
populateBlankMisoSceneModel(model, width, height, vwidth, vheight);
return model;
}
@@ -162,12 +278,13 @@ public class MisoSceneModel
* Populates a blank scene model with blank values.
*/
protected static void populateBlankMisoSceneModel (
MisoSceneModel model, int width, int height)
MisoSceneModel model, int width, int height, int vwidth, int vheight)
{
model.width = width;
model.height = height;
model.baseTileIds = new int[width*height];
model.fringeTileIds = new int[width*height];
model.vwidth = vwidth;
model.vheight = vheight;
model.allocateBaseTileArray();
model.objectTileIds = new int[0];
model.objectActions = new String[0];
}
@@ -1,5 +1,5 @@
//
// $Id: EditableMisoScene.java,v 1.15 2002/04/27 18:41:14 mdb Exp $
// $Id: EditableMisoScene.java,v 1.16 2002/05/17 19:06:23 ray Exp $
package com.threerings.miso.scene.tools;
@@ -58,17 +58,6 @@ public interface EditableMisoScene
*/
public void setBaseTiles (Rectangle r, BaseTileSet set, int setId);
/**
* Updates the tile at the specified location in the fringe layer.
*
* @param x the x-coordinate of the tile to set.
* @param y the y-coordinate of the tile to set.
* @param tile the tile to set.
* @param fqTileId the fully-qualified tile id (@see
* TileUtil#getFQTileId}) of the new default base tile.
*/
public void setFringeTile (int x, int y, Tile tile, int fqTileId);
/**
* Addds an object tile to this scene.
*
@@ -90,11 +79,6 @@ public interface EditableMisoScene
*/
public void clearBaseTile (int x, int y);
/**
* Clears out the tile at the specified location in the fringe layer.
*/
public void clearFringeTile (int x, int y);
/**
* Clears out the specified tile from the object list.
*/
@@ -1,5 +1,5 @@
//
// $Id: EditableMisoSceneImpl.java,v 1.19 2002/05/03 04:12:48 mdb Exp $
// $Id: EditableMisoSceneImpl.java,v 1.20 2002/05/17 19:06:23 ray Exp $
package com.threerings.miso.scene.tools;
@@ -91,8 +91,8 @@ public class EditableMisoSceneImpl
try {
int index = _rando.nextInt(setcount);
_base.setTile(x, y, (BaseTile) set.getTile(index));
_model.baseTileIds[_model.width*y + x] =
TileUtil.getFQTileId(setId, index);
_model.setBaseTile(
x, y, TileUtil.getFQTileId(setId, index));
} catch (NoSuchTileException nste) {
// not going to happen
@@ -109,18 +109,10 @@ public class EditableMisoSceneImpl
public void setBaseTile (int x, int y, BaseTile tile, int fqTileId)
{
_base.setTile(x, y, tile);
_model.baseTileIds[_model.width*y + x] = fqTileId;
_model.setBaseTile(x, y, fqTileId);
_fringer.fringe(_model, _fringe, new Rectangle(x, y, 1, 1), _rando);
}
// documentation inherited
public void setFringeTile (int x, int y, Tile tile, int fqTileId)
{
_fringe.setTile(x, y, tile);
// update the model as well
_model.fringeTileIds[_model.width*y + x] = fqTileId;
}
// documentation inherited
public void addObjectTile (ObjectTile tile, int x, int y, int fqTileId)
{
@@ -148,14 +140,6 @@ public class EditableMisoSceneImpl
_defaultBaseTileSet, _defaultBaseTileSetId);
}
// documentation inherited
public void clearFringeTile (int x, int y)
{
_fringe.setTile(x, y, null);
// clear it out in the model
_model.fringeTileIds[_model.width*y + x] = 0;
}
// documentation inherited
public void removeObjectTile (ObjectTile tile)
{
@@ -1,5 +1,5 @@
//
// $Id: MisoSceneRuleSet.java,v 1.8 2002/05/16 02:25:19 ray Exp $
// $Id: MisoSceneRuleSet.java,v 1.9 2002/05/17 19:06:23 ray Exp $
package com.threerings.miso.scene.tools.xml;
@@ -9,6 +9,7 @@ import org.apache.commons.digester.RuleSetBase;
import com.samskivert.xml.CallMethodSpecialRule;
import com.samskivert.xml.SetFieldRule;
import com.threerings.miso.Log;
import com.threerings.miso.scene.MisoSceneModel;
/**
@@ -51,6 +52,10 @@ public class MisoSceneRuleSet extends RuleSetBase
new SetFieldRule(digester, "width"));
digester.addRule(_prefix + "/height",
new SetFieldRule(digester, "height"));
digester.addRule(_prefix + "/viewwidth",
new SetFieldRule(digester, "vwidth"));
digester.addRule(_prefix + "/viewheight",
new SetFieldRule(digester, "vheight"));
digester.addRule(_prefix + "/base",
new SetFieldRule(digester, "baseTileIds"));
digester.addRule(_prefix + "/object",
@@ -72,8 +77,13 @@ public class MisoSceneRuleSet extends RuleSetBase
model.objectActions = new String[1];
}
// and allocate the fringe tile layer
model.fringeTileIds = new int[model.baseTileIds.length];
// check to see if we've read in an old-style model.
// TODO: remove this someday after all our scenes are
// converted.
if (model.vwidth == 0) {
model.convertOldSchool(10, 12);
Log.info("Converted old-school MisoSceneModel.");
}
}
});
}
@@ -1,5 +1,5 @@
//
// $Id: MisoSceneWriter.java,v 1.6 2002/05/16 02:25:19 ray Exp $
// $Id: MisoSceneWriter.java,v 1.7 2002/05/17 19:06:23 ray Exp $
package com.threerings.miso.scene.tools.xml;
@@ -38,9 +38,10 @@ public class MisoSceneWriter
{
writer.dataElement("width", Integer.toString(model.width));
writer.dataElement("height", Integer.toString(model.height));
writer.dataElement("viewwidth", Integer.toString(model.vwidth));
writer.dataElement("viewheight", Integer.toString(model.vheight));
writer.dataElement("base",
StringUtil.toString(model.baseTileIds, "", ""));
// note that we don't write the fringe layer.
writer.dataElement("object",
StringUtil.toString(model.objectTileIds, "", ""));
writer.dataElement("actions",