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: 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];
}