Added more support for full and fine coordinates. Constrain path

destinations to full coordinates.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@198 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Walter Korman
2001-08-08 22:29:39 +00:00
parent 65b95f5698
commit 5770a15d3c
4 changed files with 138 additions and 47 deletions
@@ -1,17 +1,18 @@
// //
// $Id: IsoSceneView.java,v 1.30 2001/08/08 21:24:20 shaper Exp $ // $Id: IsoSceneView.java,v 1.31 2001/08/08 22:29:39 shaper Exp $
package com.threerings.miso.scene; package com.threerings.miso.scene;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.ArrayList;
import com.threerings.miso.Log; import com.threerings.miso.Log;
import com.threerings.miso.sprite.*; import com.threerings.miso.sprite.*;
import com.threerings.miso.tile.Tile; import com.threerings.miso.tile.Tile;
import com.threerings.miso.tile.TileManager; import com.threerings.miso.tile.TileManager;
import java.awt.*;
import java.awt.image.*;
import java.util.ArrayList;
/** /**
* The <code>IsoSceneView</code> provides an isometric view of a * The <code>IsoSceneView</code> provides an isometric view of a
* particular scene. * particular scene.
@@ -33,8 +34,9 @@ public class IsoSceneView implements EditableSceneView
setModel(model); setModel(model);
// initialize the highlighted tile // initialize the highlighted objects
_htile = new Point(-1, -1); _htile = new Point(-1, -1);
_hfull = new Point(-1, -1);
// get the font used to render tile coordinates // get the font used to render tile coordinates
_font = new Font("Arial", Font.PLAIN, 7); _font = new Font("Arial", Font.PLAIN, 7);
@@ -83,6 +85,9 @@ public class IsoSceneView implements EditableSceneView
// draw an outline around the highlighted tile // draw an outline around the highlighted tile
paintHighlightedTile(gfx, _htile.x, _htile.y); paintHighlightedTile(gfx, _htile.x, _htile.y);
// draw an outline around the highlighted full coordinate
paintHighlightedFull(gfx, _hfull.x, _hfull.y);
// draw lines illustrating tracking of the mouse position // draw lines illustrating tracking of the mouse position
//paintMouseLines(gfx); //paintMouseLines(gfx);
@@ -109,7 +114,7 @@ public class IsoSceneView implements EditableSceneView
for (int xx = 0; xx < Scene.TILE_WIDTH; xx++) { for (int xx = 0; xx < Scene.TILE_WIDTH; xx++) {
for (int yy = 0; yy < Scene.TILE_HEIGHT; yy++) { for (int yy = 0; yy < Scene.TILE_HEIGHT; yy++) {
if (_dirty[xx][yy]) { if (_dirty[xx][yy]) {
gfx.draw(getTilePolygon(xx, yy)); gfx.draw(IsoUtil.getTilePolygon(_model, xx, yy));
} }
} }
} }
@@ -139,7 +144,7 @@ public class IsoSceneView implements EditableSceneView
if (!_dirty[xx][yy]) continue; if (!_dirty[xx][yy]) continue;
// get the tile's screen position // get the tile's screen position
Polygon poly = getTilePolygon(xx, yy); Polygon poly = IsoUtil.getTilePolygon(_model, xx, yy);
// draw all layers at this tile position // draw all layers at this tile position
for (int kk = 0; kk < Scene.NUM_LAYERS; kk++) { for (int kk = 0; kk < Scene.NUM_LAYERS; kk++) {
@@ -165,29 +170,6 @@ public class IsoSceneView implements EditableSceneView
} }
} }
/**
* Return a polygon framing the specified tile.
*
* @param x the tile x-position coordinate.
* @param y the tile y-position coordinate.
*/
protected Polygon getTilePolygon (int x, int y)
{
// get the top-left screen coordinate for the tile
Point spos = new Point();
IsoUtil.tileToScreen(_model, x, y, spos);
// create a polygon framing the tile
Polygon poly = new Polygon();
poly.addPoint(spos.x, spos.y + _model.tilehhei);
poly.addPoint(spos.x + _model.tilehwid, spos.y);
poly.addPoint(spos.x + _model.tilewid, spos.y + _model.tilehhei);
poly.addPoint(spos.x + _model.tilehwid, spos.y + _model.tilehei);
poly.addPoint(spos.x, spos.y + _model.tilehhei);
return poly;
}
/** /**
* Render the scene to the given graphics context. * Render the scene to the given graphics context.
* *
@@ -227,7 +209,8 @@ public class IsoSceneView implements EditableSceneView
// draw all sprites residing in the current tile // draw all sprites residing in the current tile
// TODO: simplify other tile positioning here to use poly // TODO: simplify other tile positioning here to use poly
_spritemgr.renderSprites(gfx, getTilePolygon(tx, ty)); _spritemgr.renderSprites(
gfx, IsoUtil.getTilePolygon(_model, tx, ty));
} }
// draw tile coordinates in each tile // draw tile coordinates in each tile
@@ -317,23 +300,48 @@ public class IsoSceneView implements EditableSceneView
*/ */
protected void paintHighlightedTile (Graphics2D gfx, int x, int y) protected void paintHighlightedTile (Graphics2D gfx, int x, int y)
{ {
if (x == -1 || y == -1) return;
// set the desired stroke and color // set the desired stroke and color
Stroke ostroke = gfx.getStroke(); Stroke ostroke = gfx.getStroke();
gfx.setStroke(HLT_STROKE); gfx.setStroke(HLT_STROKE);
gfx.setColor(HLT_COLOR); gfx.setColor(HLT_COLOR);
// draw the tile outline // draw the tile outline
gfx.draw(getTilePolygon(x, y)); gfx.draw(IsoUtil.getTilePolygon(_model, x, y));
// restore the original stroke // restore the original stroke
gfx.setStroke(ostroke); gfx.setStroke(ostroke);
} }
/**
* Paint a highlight around the specified full coordinate.
*
* @param gfx the graphics context.
* @param x the full x-position coordinate.
* @param y the full y-position coordinate.
*/
protected void paintHighlightedFull (Graphics2D gfx, int x, int y)
{
if (x == -1 || y == -1) return;
Point spos = new Point();
IsoUtil.fullToScreen(_model, x, y, spos);
gfx.setColor(Color.red);
gfx.draw(new Ellipse2D.Float(spos.x, spos.y, 3, 3));
}
public void setHighlightedTile (int sx, int sy) public void setHighlightedTile (int sx, int sy)
{ {
IsoUtil.screenToTile(_model, sx, sy, _htile); IsoUtil.screenToTile(_model, sx, sy, _htile);
} }
public void setHighlightedFull (int x, int y)
{
IsoUtil.screenToFull(_model, x, y, _hfull);
}
/** /**
* Invalidate a list of rectangles in the view for later repainting. * Invalidate a list of rectangles in the view for later repainting.
* *
@@ -478,7 +486,7 @@ public class IsoSceneView implements EditableSceneView
public void setModel (IsoSceneModel model) public void setModel (IsoSceneModel model)
{ {
_model = model; _model = model;
_model.calculateXAxis(); _model.precalculate();
} }
public Path getPath (Sprite sprite, int x, int y) public Path getPath (Sprite sprite, int x, int y)
@@ -489,10 +497,16 @@ public class IsoSceneView implements EditableSceneView
return null; return null;
} }
// constrain destination pixels to fine coordinates
Point fpos = new Point();
IsoUtil.screenToFull(_model, x, y, fpos);
Point spos = new Point();
IsoUtil.fullToScreen(_model, fpos.x, fpos.y, spos);
// create path from current loc to destination // create path from current loc to destination
Path path = new Path(sprite.x, sprite.y); Path path = new Path(sprite.x, sprite.y);
int dir = IsoUtil.getDirection(_model, sprite.x, sprite.y, x, y); int dir = IsoUtil.getDirection(_model, sprite.x, sprite.y, x, y);
path.addNode(x, y, dir); path.addNode(spos.x, spos.y, dir);
return path; return path;
} }
@@ -506,6 +520,9 @@ public class IsoSceneView implements EditableSceneView
/** The currently highlighted tile. */ /** The currently highlighted tile. */
protected Point _htile; protected Point _htile;
/** The currently highlighted full coordinate. */
protected Point _hfull;
/** The font to draw tile coordinates. */ /** The font to draw tile coordinates. */
protected Font _font; protected Font _font;
@@ -1,5 +1,5 @@
// //
// $Id: IsoSceneViewModel.java,v 1.4 2001/08/07 18:29:17 shaper Exp $ // $Id: IsoSceneViewModel.java,v 1.5 2001/08/08 22:29:39 shaper Exp $
package com.threerings.miso.scene; package com.threerings.miso.scene;
@@ -23,6 +23,9 @@ public class IsoSceneModel
/** Tile dimensions and half-dimensions in the view. */ /** Tile dimensions and half-dimensions in the view. */
public int tilewid, tilehei, tilehwid, tilehhei; public int tilewid, tilehei, tilehwid, tilehhei;
/** Fine coordinate dimensions. */
public int finehwid, finehhei;
/** Number of fine coordinates on each axis within a tile. */ /** Number of fine coordinates on each axis within a tile. */
public int finegran; public int finegran;
@@ -149,13 +152,13 @@ public class IsoSceneModel
} }
/** /**
* Pre-calculate the x-axis lines for later use in converting * Pre-calculate various values that are commonly used in working
* screen coordinates to tile coordinates and tile-based pixel * with an isometric view. Includes x-axis line values for use in
* coordinates to fine coordinates. * converting coordinates, and fine coordinate dimensions.
*/ */
public void calculateXAxis () public void precalculate ()
{ {
// first calculate scene-based x-axis line for conversion from // calculate scene-based x-axis line for conversion from
// screen to tile coordinates // screen to tile coordinates
// create the x- and y-axis lines // create the x- and y-axis lines
@@ -172,15 +175,19 @@ public class IsoSceneModel
lineX[1].x = lineX[0].x + (tilehwid * Scene.TILE_WIDTH); lineX[1].x = lineX[0].x + (tilehwid * Scene.TILE_WIDTH);
lineX[1].y = lineX[0].y + (int)((slopeX * lineX[1].x) + bX); lineX[1].y = lineX[0].y + (int)((slopeX * lineX[1].x) + bX);
// next calculate tile-based x-axis line for conversion from // calculate tile-based x-axis line for conversion from
// tile-based pixel to fine coordinates // tile-based pixel to fine coordinates
// calculate the edge length separating each fine coordinate // calculate the edge length separating each fine coordinate
finelen = tilelen / (float)finegran; finelen = tilelen / (float)finegran;
// calculate the x-axis line // calculate the fine-coordinate x-axis line
fineSlopeX = (float)tilehei / (float)tilewid; fineSlopeX = (float)tilehei / (float)tilewid;
fineBX = -(fineSlopeX * (float)tilehwid); fineBX = -(fineSlopeX * (float)tilehwid);
fineSlopeY = -fineSlopeX; fineSlopeY = -fineSlopeX;
// calculate the fine coordinate dimensions
finehwid = (int)((float)tilehwid / (float)finegran);
finehhei = (int)((float)tilehhei / (float)finegran);
} }
} }
@@ -1,9 +1,10 @@
// //
// $Id: IsoUtil.java,v 1.2 2001/08/07 18:29:17 shaper Exp $ // $Id: IsoUtil.java,v 1.3 2001/08/08 22:29:39 shaper Exp $
package com.threerings.miso.scene; package com.threerings.miso.scene;
import java.awt.Point; import java.awt.Point;
import java.awt.Polygon;
import com.threerings.miso.sprite.Path; import com.threerings.miso.sprite.Path;
import com.threerings.miso.util.MathUtil; import com.threerings.miso.util.MathUtil;
@@ -144,6 +145,22 @@ public class IsoUtil
spos.y = model.origin.y + ((x + y) * model.tilehhei); spos.y = model.origin.y + ((x + y) * model.tilehhei);
} }
/**
* Convert the given fine coordinates to pixel coordinates within
* the containing tile. Converted coordinates are placed in the
* given point object.
*
* @param x the x-position fine coordinate.
* @param y the y-position fine coordinate.
* @param ppos the point object to place coordinates in.
*/
public static void fineToPixel (
IsoSceneModel model, int x, int y, Point ppos)
{
ppos.x = model.tilehwid + ((x - y - 1) * model.finehwid);
ppos.y = (x + y) * model.finehhei;
}
/** /**
* Convert the given pixel coordinates, whose origin is at the * Convert the given pixel coordinates, whose origin is at the
* top-left of a tile's containing rectangle, to fine coordinates * top-left of a tile's containing rectangle, to fine coordinates
@@ -208,6 +225,56 @@ public class IsoUtil
fpos.y += (tpos.y * FULL_TILE_FACTOR); fpos.y += (tpos.y * FULL_TILE_FACTOR);
} }
/**
* Convert the given full coordinates to screen-based pixel
* coordinates. Converted coordinates are placed in the given
* point object.
*
* @param x the x-position full coordinate.
* @param y the y-position full coordinate.
* @param spos the point object to place coordinates in.
*/
public static void fullToScreen (
IsoSceneModel model, int x, int y, Point spos)
{
// get the tile screen position
Point tspos = new Point();
int tx = x / FULL_TILE_FACTOR, ty = y / FULL_TILE_FACTOR;
tileToScreen(model, tx, ty, tspos);
// get the pixel position of the fine coords within the tile
Point ppos = new Point();
int fx = x - (tx * FULL_TILE_FACTOR), fy = y - (ty * FULL_TILE_FACTOR);
fineToPixel(model, fx, fy, ppos);
// final position is tile position offset by fine position
spos.x = tspos.x + ppos.x;
spos.y = tspos.y + ppos.y;
}
/**
* Return a polygon framing the specified tile.
*
* @param x the tile x-position coordinate.
* @param y the tile y-position coordinate.
*/
public static Polygon getTilePolygon (IsoSceneModel model, int x, int y)
{
// get the top-left screen coordinate for the tile
Point spos = new Point();
IsoUtil.tileToScreen(model, x, y, spos);
// create a polygon framing the tile
Polygon poly = new Polygon();
poly.addPoint(spos.x, spos.y + model.tilehhei);
poly.addPoint(spos.x + model.tilehwid, spos.y);
poly.addPoint(spos.x + model.tilewid, spos.y + model.tilehhei);
poly.addPoint(spos.x + model.tilehwid, spos.y + model.tilehei);
poly.addPoint(spos.x, spos.y + model.tilehhei);
return poly;
}
/** Multiplication factor to embed tile coords in full coords. */ /** Multiplication factor to embed tile coords in full coords. */
protected static final int FULL_TILE_FACTOR = 100; protected static final int FULL_TILE_FACTOR = 100;
} }
@@ -1,5 +1,5 @@
// //
// $Id: ViewerSceneViewPanel.java,v 1.4 2001/08/08 03:19:39 shaper Exp $ // $Id: ViewerSceneViewPanel.java,v 1.5 2001/08/08 22:29:39 shaper Exp $
package com.threerings.miso.viewer; package com.threerings.miso.viewer;
@@ -100,7 +100,7 @@ public class ViewerSceneViewPanel extends SceneViewPanel
} }
// hackily highlight the tile that was clicked on for happy testing // hackily highlight the tile that was clicked on for happy testing
// ((EditableSceneView)_view).setHighlightedTile(x, y); ((EditableSceneView)_view).setHighlightedFull(x, y);
} }
public void mouseClicked (MouseEvent e) { } public void mouseClicked (MouseEvent e) { }