Fringe a tile at a time; made some small performance tweaks.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2266 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2003-02-12 05:38:12 +00:00
parent a9ba8fdfe5
commit eaf00bf441
@@ -1,5 +1,5 @@
// //
// $Id: AutoFringer.java,v 1.18 2003/01/31 23:10:45 mdb Exp $ // $Id: AutoFringer.java,v 1.19 2003/02/12 05:38:12 mdb Exp $
package com.threerings.miso.tile; package com.threerings.miso.tile;
@@ -11,10 +11,9 @@ import java.awt.image.BufferedImage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Random; import java.util.Random;
import com.samskivert.util.HashIntMap; import com.samskivert.util.CheapIntMap;
import com.samskivert.util.QuickSort; import com.samskivert.util.QuickSort;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
@@ -24,11 +23,8 @@ import com.threerings.media.image.BufferedMirage;
import com.threerings.media.tile.NoSuchTileException; import com.threerings.media.tile.NoSuchTileException;
import com.threerings.media.tile.NoSuchTileSetException; import com.threerings.media.tile.NoSuchTileSetException;
import com.threerings.media.tile.Tile; import com.threerings.media.tile.Tile;
import com.threerings.media.tile.TileLayer;
import com.threerings.media.tile.TileManager; import com.threerings.media.tile.TileManager;
import com.threerings.media.tile.TileSet; import com.threerings.media.tile.TileSet;
import com.threerings.media.tile.TileUtil;
import com.threerings.media.tile.UniformTileSet;
import com.threerings.media.image.ImageUtil; import com.threerings.media.image.ImageUtil;
@@ -36,16 +32,17 @@ import com.threerings.media.image.BackedVolatileMirage;
import com.threerings.media.image.ImageManager; import com.threerings.media.image.ImageManager;
import com.threerings.media.image.Mirage; import com.threerings.media.image.Mirage;
import com.threerings.miso.data.MisoSceneModel; import com.threerings.miso.data.MisoScene;
/** /**
* Automatically fringes a scene according to the rules in the * Automatically fringes a scene according to the rules in the supplied
* FringeConfiguration. * fringe configuration.
*/ */
public class AutoFringer public class AutoFringer
{ {
/** /**
* Construct an AutoFringer * Constructs an instance that will fringe according to the rules in
* the supplied fringe configuration.
*/ */
public AutoFringer (FringeConfiguration fringeconf, ImageManager imgr, public AutoFringer (FringeConfiguration fringeconf, ImageManager imgr,
TileManager tmgr) TileManager tmgr)
@@ -56,89 +53,44 @@ public class AutoFringer
} }
/** /**
* Automatically fringe the entire scene. * Compute and return the fringe tile to be inserted at the specified
*/
public void fringe (MisoSceneModel scene, TileLayer fringelayer, long seed)
{
fringe(scene, fringelayer, new Random(seed));
}
/**
* Automatically fringe the entire scene.
*/
public void fringe (
MisoSceneModel scene, TileLayer fringelayer, Random rando)
{
fringe(scene, fringelayer,
new Rectangle(0, 0, scene.width, scene.height), rando);
}
/**
* Automatically generate fringe information for the specified
* rectangular region <strong>and the tiles they influence</strong>
* and insert into the fringe TileLayer.
*/
public void fringe (MisoSceneModel scene, TileLayer fringelayer,
Rectangle r, Random rando)
{
long start = System.currentTimeMillis();
// create a hash to cache our masks
HashMap maskcache = new HashMap();
int lastrow = Math.min(r.y + r.height + 1, scene.height);
int lastcol = Math.min(r.x + r.width + 1, scene.width);
for (int row = Math.max(r.y - 1, 0); row < lastrow; row++) {
for (int col = Math.max(r.x - 1, 0); col < lastcol; col++) {
Tile tile = getFringeTile(scene, row, col, maskcache, rando);
fringelayer.setTile(col, row, tile);
}
}
// and then we throw maskcache out...
// long now = System.currentTimeMillis();
// long size = ImageUtil.getEstimatedMemoryUsage(
// maskcache.values().iterator());
// Log.debug("Finished fringing scene [ms=" + (now - start) +
// ", mem=" + (size / 1024) + "k" +
// ", size=" + maskcache.size() + "].");
}
/**
* Compute and return the fringe Tile to be inserted at the specified
* location. * location.
*/ */
protected Tile getFringeTile (MisoSceneModel scene, int row, int col, public Tile getFringeTile (MisoScene scene, int col, int row,
HashMap masks, Random rando) HashMap masks, Random rando)
{ {
HashIntMap fringers = new HashIntMap();
int hei = scene.height;
int wid = scene.width;
// get the tileset id of the base tile we are considering // get the tileset id of the base tile we are considering
int underset = scene.getBaseTile(col, row) >> 16; int underset = scene.getBaseTileId(col, row) >> 16;
// start with a clean temporary fringer map
_fringers.clear();
// walk through our influence tiles // walk through our influence tiles
int maxy = Math.min(hei, row + 2); int maxy = row + 2, maxx = col + 2;
int maxx = Math.min(wid, col + 2); for (int y = row - 1; y < maxy; y++) {
for (int y = Math.max(0, row - 1); y < maxy; y++) { for (int x = col - 1; x < maxx; x++) {
for (int x = Math.max(0, col - 1); x < maxx; x++) {
// we sensibly do not consider ourselves // we sensibly do not consider ourselves
if ((x == col) && (y == row)) { if ((x == col) && (y == row)) {
continue; continue;
} }
int baseset = scene.getBaseTile(x, y) >> 16; // make sure there's a tile at this position
int btid = scene.getBaseTileId(x, y);
if (btid == -1) {
continue;
}
// determine if it fringes on our tile
int baseset = btid >> 16;
int pri = _fringeconf.fringesOn(baseset, underset); int pri = _fringeconf.fringesOn(baseset, underset);
if (pri == -1) { if (pri == -1) {
continue; continue;
} }
FringerRec fringer = (FringerRec) fringers.get(baseset); FringerRec fringer = (FringerRec)_fringers.get(baseset);
if (fringer == null) { if (fringer == null) {
fringer = new FringerRec(baseset, pri); fringer = new FringerRec(baseset, pri);
fringers.put(baseset, fringer); _fringers.put(baseset, fringer);
} }
// now turn on the appropriate fringebits // now turn on the appropriate fringebits
@@ -146,17 +98,19 @@ public class AutoFringer
} }
} }
// if nothing fringed, we're done. // if nothing fringed, we're done
int numfringers = fringers.size(); int numfringers = _fringers.size();
if (numfringers == 0) { if (numfringers == 0) {
return null; return null;
} }
// otherwise compose a FringeTile from the specified fringes // otherwise compose a FringeTile from the specified fringes
FringerRec[] frecs = new FringerRec[numfringers]; FringerRec[] frecs = new FringerRec[numfringers];
Iterator iter = fringers.elements(); for (int ii = 0, pp = 0; ii < 16; ii++) {
for (int ii=0; ii < frecs.length; ii++) { FringerRec rec = (FringerRec)_fringers.getValue(ii);
frecs[ii] = (FringerRec) iter.next(); if (rec != null) {
frecs[pp++] = rec;
}
} }
return composeFringeTile(frecs, masks, rando); return composeFringeTile(frecs, masks, rando);
@@ -411,4 +365,5 @@ public class AutoFringer
protected ImageManager _imgr; protected ImageManager _imgr;
protected TileManager _tmgr; protected TileManager _tmgr;
protected FringeConfiguration _fringeconf; protected FringeConfiguration _fringeconf;
protected CheapIntMap _fringers = new CheapIntMap(16);
} }