diff --git a/src/java/com/threerings/miso/client/IsoSceneView.java b/src/java/com/threerings/miso/client/IsoSceneView.java index ccfb5e7da..490e1c0d1 100644 --- a/src/java/com/threerings/miso/client/IsoSceneView.java +++ b/src/java/com/threerings/miso/client/IsoSceneView.java @@ -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; +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.*; +import java.util.ArrayList; + import com.threerings.miso.Log; import com.threerings.miso.sprite.*; import com.threerings.miso.tile.Tile; import com.threerings.miso.tile.TileManager; -import java.awt.*; -import java.awt.image.*; -import java.util.ArrayList; - /** * The IsoSceneView provides an isometric view of a * particular scene. @@ -33,8 +34,9 @@ public class IsoSceneView implements EditableSceneView setModel(model); - // initialize the highlighted tile + // initialize the highlighted objects _htile = new Point(-1, -1); + _hfull = new Point(-1, -1); // get the font used to render tile coordinates _font = new Font("Arial", Font.PLAIN, 7); @@ -83,6 +85,9 @@ public class IsoSceneView implements EditableSceneView // draw an outline around the highlighted tile 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 //paintMouseLines(gfx); @@ -109,7 +114,7 @@ public class IsoSceneView implements EditableSceneView for (int xx = 0; xx < Scene.TILE_WIDTH; xx++) { for (int yy = 0; yy < Scene.TILE_HEIGHT; 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; // 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 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. * @@ -227,7 +209,8 @@ public class IsoSceneView implements EditableSceneView // draw all sprites residing in the current tile // 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 @@ -317,23 +300,48 @@ public class IsoSceneView implements EditableSceneView */ protected void paintHighlightedTile (Graphics2D gfx, int x, int y) { + if (x == -1 || y == -1) return; + // set the desired stroke and color Stroke ostroke = gfx.getStroke(); gfx.setStroke(HLT_STROKE); gfx.setColor(HLT_COLOR); // draw the tile outline - gfx.draw(getTilePolygon(x, y)); + gfx.draw(IsoUtil.getTilePolygon(_model, x, y)); // restore the original stroke 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) { 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. * @@ -478,7 +486,7 @@ public class IsoSceneView implements EditableSceneView public void setModel (IsoSceneModel model) { _model = model; - _model.calculateXAxis(); + _model.precalculate(); } public Path getPath (Sprite sprite, int x, int y) @@ -489,10 +497,16 @@ public class IsoSceneView implements EditableSceneView return null; } - // create path from current loc to destination + // 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 Path path = new Path(sprite.x, sprite.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; } @@ -506,6 +520,9 @@ public class IsoSceneView implements EditableSceneView /** The currently highlighted tile. */ protected Point _htile; + /** The currently highlighted full coordinate. */ + protected Point _hfull; + /** The font to draw tile coordinates. */ protected Font _font; diff --git a/src/java/com/threerings/miso/client/IsoSceneViewModel.java b/src/java/com/threerings/miso/client/IsoSceneViewModel.java index e101554a7..92f035cda 100644 --- a/src/java/com/threerings/miso/client/IsoSceneViewModel.java +++ b/src/java/com/threerings/miso/client/IsoSceneViewModel.java @@ -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; @@ -23,6 +23,9 @@ public class IsoSceneModel /** Tile dimensions and half-dimensions in the view. */ public int tilewid, tilehei, tilehwid, tilehhei; + /** Fine coordinate dimensions. */ + public int finehwid, finehhei; + /** Number of fine coordinates on each axis within a tile. */ public int finegran; @@ -149,13 +152,13 @@ public class IsoSceneModel } /** - * Pre-calculate the x-axis lines for later use in converting - * screen coordinates to tile coordinates and tile-based pixel - * coordinates to fine coordinates. + * Pre-calculate various values that are commonly used in working + * with an isometric view. Includes x-axis line values for use in + * 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 // 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].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 // calculate the edge length separating each fine coordinate finelen = tilelen / (float)finegran; - // calculate the x-axis line + // calculate the fine-coordinate x-axis line fineSlopeX = (float)tilehei / (float)tilewid; fineBX = -(fineSlopeX * (float)tilehwid); fineSlopeY = -fineSlopeX; + + // calculate the fine coordinate dimensions + finehwid = (int)((float)tilehwid / (float)finegran); + finehhei = (int)((float)tilehhei / (float)finegran); } } diff --git a/src/java/com/threerings/miso/client/IsoUtil.java b/src/java/com/threerings/miso/client/IsoUtil.java index 0dbcf2b88..b2d8b1d9d 100644 --- a/src/java/com/threerings/miso/client/IsoUtil.java +++ b/src/java/com/threerings/miso/client/IsoUtil.java @@ -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; import java.awt.Point; +import java.awt.Polygon; import com.threerings.miso.sprite.Path; import com.threerings.miso.util.MathUtil; @@ -144,6 +145,22 @@ public class IsoUtil 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 * 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); } + /** + * 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. */ protected static final int FULL_TILE_FACTOR = 100; } diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java b/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java index dd0130d75..64af044bc 100644 --- a/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java +++ b/tests/src/java/com/threerings/miso/viewer/ViewerSceneViewPanel.java @@ -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; @@ -100,7 +100,7 @@ public class ViewerSceneViewPanel extends SceneViewPanel } // 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) { }