Behold, Nenya, Ring of Water and repository for our media and animation related
goodies, both Java 2D and LWJGL/JME 3D. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@1 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// $Id: MisoContext.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.miso.util;
|
||||
|
||||
import com.threerings.media.FrameManager;
|
||||
import com.threerings.miso.tile.MisoTileManager;
|
||||
|
||||
/**
|
||||
* Provides Miso code with access to the managers that it needs to do its
|
||||
* thing.
|
||||
*/
|
||||
public interface MisoContext
|
||||
{
|
||||
/**
|
||||
* Returns the frame manager that our scene panel will interact with.
|
||||
*/
|
||||
public FrameManager getFrameManager ();
|
||||
|
||||
/**
|
||||
* Returns a reference to the tile manager. This reference is valid
|
||||
* for the lifetime of the application.
|
||||
*/
|
||||
public MisoTileManager getTileManager ();
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// $Id: MisoSceneMetrics.java 3310 2005-01-24 23:08:21Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.miso.util;
|
||||
|
||||
import com.threerings.miso.client.MisoScenePanel;
|
||||
|
||||
/**
|
||||
* Contains information on the configuration of a particular isometric
|
||||
* view. The member data are public to facilitate convenient referencing
|
||||
* by the {@link MisoScenePanel} class, the values should not be modified
|
||||
* once the metrics are constructed.
|
||||
*/
|
||||
public class MisoSceneMetrics
|
||||
{
|
||||
/** 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;
|
||||
|
||||
/** Dimensions of our scene blocks in tile count. */
|
||||
public short blockwid = 4, blockhei = 4;
|
||||
|
||||
/** The length of a tile edge in pixels. */
|
||||
public float tilelen;
|
||||
|
||||
/** The slope of the x- and y-axis lines. */
|
||||
public float slopeX, slopeY;
|
||||
|
||||
/** The length between fine coordinates in pixels. */
|
||||
public float finelen;
|
||||
|
||||
/** The y-intercept of the x-axis line within a tile. */
|
||||
public float fineBX;
|
||||
|
||||
/** The slope of the x- and y-axis lines within a tile. */
|
||||
public float fineSlopeX, fineSlopeY;
|
||||
|
||||
/**
|
||||
* Constructs scene metrics by directly specifying the desired config
|
||||
* parameters.
|
||||
*
|
||||
* @param tilewid the width in pixels of the tiles.
|
||||
* @param tilehei the height in pixels of the tiles.
|
||||
* @param finegran the number of sub-tile divisions to use for fine
|
||||
* coordinates.
|
||||
*/
|
||||
public MisoSceneMetrics (int tilewid, int tilehei, int finegran)
|
||||
{
|
||||
// keep track of this stuff
|
||||
this.tilewid = tilewid;
|
||||
this.tilehei = tilehei;
|
||||
this.finegran = finegran;
|
||||
|
||||
// halve the dimensions
|
||||
tilehwid = (tilewid / 2);
|
||||
tilehhei = (tilehei / 2);
|
||||
|
||||
// calculate the length of a tile edge in pixels
|
||||
tilelen = (float) Math.sqrt(
|
||||
(tilehwid * tilehwid) + (tilehhei * tilehhei));
|
||||
|
||||
// calculate the slope of the x- and y-axis lines
|
||||
slopeX = (float)tilehei / (float)tilewid;
|
||||
slopeY = -slopeX;
|
||||
|
||||
// calculate the edge length separating each fine coordinate
|
||||
finelen = tilelen / (float)finegran;
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,518 @@
|
||||
//
|
||||
// $Id: MisoUtil.java 3628 2005-06-28 17:42:55Z mdb $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.miso.util;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Polygon;
|
||||
|
||||
import com.samskivert.swing.SmartPolygon;
|
||||
|
||||
import com.threerings.util.DirectionCodes;
|
||||
import com.threerings.util.DirectionUtil;
|
||||
|
||||
import com.threerings.media.util.MathUtil;
|
||||
|
||||
/**
|
||||
* Miscellaneous isometric-display-related utility routines.
|
||||
*/
|
||||
public class MisoUtil
|
||||
implements DirectionCodes
|
||||
{
|
||||
/**
|
||||
* Given two points in screen pixel coordinates, return the
|
||||
* compass direction that point B lies in from point A from an
|
||||
* isometric perspective.
|
||||
*
|
||||
* @param ax the x-position of point A.
|
||||
* @param ay the y-position of point A.
|
||||
* @param bx the x-position of point B.
|
||||
* @param by the y-position of point B.
|
||||
*
|
||||
* @return the direction specified as one of the <code>Sprite</code>
|
||||
* class's direction constants.
|
||||
*/
|
||||
public static int getDirection (
|
||||
MisoSceneMetrics metrics, int ax, int ay, int bx, int by)
|
||||
{
|
||||
Point afpos = new Point(), bfpos = new Point();
|
||||
|
||||
// convert screen coordinates to full coordinates to get both
|
||||
// tile coordinates and fine coordinates
|
||||
screenToFull(metrics, ax, ay, afpos);
|
||||
screenToFull(metrics, bx, by, bfpos);
|
||||
|
||||
// pull out the tile coordinates for each point
|
||||
int tax = fullToTile(afpos.x);
|
||||
int tay = fullToTile(afpos.y);
|
||||
|
||||
int tbx = fullToTile(bfpos.x);
|
||||
int tby = fullToTile(bfpos.y);
|
||||
|
||||
// compare tile coordinates to determine direction
|
||||
int dir = getIsoDirection(tax, tay, tbx, tby);
|
||||
if (dir != DirectionCodes.NONE) {
|
||||
return dir;
|
||||
}
|
||||
|
||||
// destination point is in the same tile as the
|
||||
// origination point, so consider fine coordinates
|
||||
|
||||
// pull out the fine coordinates for each point
|
||||
int fax = afpos.x - (tax * FULL_TILE_FACTOR);
|
||||
int fay = afpos.y - (tay * FULL_TILE_FACTOR);
|
||||
|
||||
int fbx = bfpos.x - (tbx * FULL_TILE_FACTOR);
|
||||
int fby = bfpos.y - (tby * FULL_TILE_FACTOR);
|
||||
|
||||
// compare fine coordinates to determine direction
|
||||
dir = getIsoDirection(fax, fay, fbx, fby);
|
||||
|
||||
// arbitrarily return southwest if fine coords were also equivalent
|
||||
return (dir == -1) ? SOUTHWEST : dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two points in an isometric coordinate system (in which {@link
|
||||
* #NORTH} is in the direction of the negative x-axis and {@link
|
||||
* #WEST} in the direction of the negative y-axis), return the compass
|
||||
* direction that point B lies in from point A. This method is used
|
||||
* to determine direction for both tile coordinates and fine
|
||||
* coordinates within a tile, since the coordinate systems are the
|
||||
* same.
|
||||
*
|
||||
* @param ax the x-position of point A.
|
||||
* @param ay the y-position of point A.
|
||||
* @param bx the x-position of point B.
|
||||
* @param by the y-position of point B.
|
||||
*
|
||||
* @return the direction specified as one of the <code>Sprite</code>
|
||||
* class's direction constants, or <code>DirectionCodes.NONE</code> if
|
||||
* point B is equivalent to point A.
|
||||
*/
|
||||
public static int getIsoDirection (int ax, int ay, int bx, int by)
|
||||
{
|
||||
// head off a div by 0 at the pass..
|
||||
if (bx == ax) {
|
||||
if (by == ay) {
|
||||
return DirectionCodes.NONE;
|
||||
}
|
||||
return (by < ay) ? EAST : WEST;
|
||||
}
|
||||
|
||||
// figure direction base on the slope of the line
|
||||
float slope = ((float) (ay - by)) / ((float) Math.abs(ax - bx));
|
||||
if (slope > 2f) {
|
||||
return EAST;
|
||||
}
|
||||
if (slope > .5f) {
|
||||
return (bx < ax) ? NORTHEAST : SOUTHEAST;
|
||||
}
|
||||
if (slope > -.5f) {
|
||||
return (bx < ax) ? NORTH : SOUTH;
|
||||
}
|
||||
if (slope > -2f) {
|
||||
return (bx < ax) ? NORTHWEST : SOUTHWEST;
|
||||
}
|
||||
return WEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two points in screen coordinates, return the isometrically
|
||||
* projected compass direction that point B lies in from point A.
|
||||
*
|
||||
* @param ax the x-position of point A.
|
||||
* @param ay the y-position of point A.
|
||||
* @param bx the x-position of point B.
|
||||
* @param by the y-position of point B.
|
||||
*
|
||||
* @return the direction specified as one of the <code>Sprite</code>
|
||||
* class's direction constants, or <code>DirectionCodes.NONE</code> if
|
||||
* point B is equivalent to point A.
|
||||
*/
|
||||
public static int getProjectedIsoDirection (int ax, int ay, int bx, int by)
|
||||
{
|
||||
return toIsoDirection(DirectionUtil.getDirection(ax, ay, bx, by));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a non-isometric orientation (where north points toward the
|
||||
* top of the screen) to an isometric orientation where north points
|
||||
* toward the upper-left corner of the screen.
|
||||
*/
|
||||
public static int toIsoDirection (int dir)
|
||||
{
|
||||
if (dir != DirectionCodes.NONE) {
|
||||
// rotate the direction clockwise (ie. change SOUTHEAST to
|
||||
// SOUTH)
|
||||
dir = DirectionUtil.rotateCW(dir, 2);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tile coordinate of the given full coordinate.
|
||||
*/
|
||||
public static int fullToTile (int val)
|
||||
{
|
||||
return MathUtil.floorDiv(val, FULL_TILE_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fine coordinate of the given full coordinate.
|
||||
*/
|
||||
public static int fullToFine (int val)
|
||||
{
|
||||
return (val - (fullToTile(val) * FULL_TILE_FACTOR));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given screen-based pixel coordinates to their
|
||||
* corresponding tile-based coordinates. Converted coordinates
|
||||
* are placed in the given point object.
|
||||
*
|
||||
* @param sx the screen x-position pixel coordinate.
|
||||
* @param sy the screen y-position pixel coordinate.
|
||||
* @param tpos the point object to place coordinates in.
|
||||
*
|
||||
* @return the point instance supplied via the <code>tpos</code>
|
||||
* parameter.
|
||||
*/
|
||||
public static Point screenToTile (
|
||||
MisoSceneMetrics metrics, int sx, int sy, Point tpos)
|
||||
{
|
||||
// determine the upper-left of the quadrant that contains our
|
||||
// point
|
||||
int zx = (int)Math.floor((float)sx / metrics.tilewid);
|
||||
int zy = (int)Math.floor((float)sy / metrics.tilehei);
|
||||
|
||||
// these are the screen coordinates of the tile's top
|
||||
int ox = (zx * metrics.tilewid), oy = (zy * metrics.tilehei);
|
||||
|
||||
// these are the tile coordinates
|
||||
tpos.x = zy + zx; tpos.y = zy - zx;
|
||||
|
||||
// now determine which of the four tiles our point occupies
|
||||
int dx = sx - ox, dy = sy - oy;
|
||||
|
||||
if (Math.round(metrics.slopeY * dx + metrics.tilehei) <= dy) {
|
||||
tpos.x += 1;
|
||||
}
|
||||
|
||||
if (Math.round(metrics.slopeX * dx) > dy) {
|
||||
tpos.y -= 1;
|
||||
}
|
||||
|
||||
// Log.info("Converted [sx=" + sx + ", sy=" + sy +
|
||||
// ", zx=" + zx + ", zy=" + zy +
|
||||
// ", ox=" + ox + ", oy=" + oy +
|
||||
// ", dx=" + dx + ", dy=" + dy +
|
||||
// ", tpos.x=" + tpos.x + ", tpos.y=" + tpos.y + "].");
|
||||
return tpos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given tile-based coordinates to their corresponding
|
||||
* screen-based pixel coordinates. The screen coordinate for a tile is
|
||||
* the upper-left coordinate of the rectangle that bounds the tile
|
||||
* polygon. Converted coordinates are placed in the given point
|
||||
* object.
|
||||
*
|
||||
* @param x the tile x-position coordinate.
|
||||
* @param y the tile y-position coordinate.
|
||||
* @param spos the point object to place coordinates in.
|
||||
*
|
||||
* @return the point instance supplied via the <code>spos</code>
|
||||
* parameter.
|
||||
*/
|
||||
public static Point tileToScreen (
|
||||
MisoSceneMetrics metrics, int x, int y, Point spos)
|
||||
{
|
||||
spos.x = (x - y - 1) * metrics.tilehwid;
|
||||
spos.y = (x + y) * metrics.tilehhei;
|
||||
return spos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (
|
||||
MisoSceneMetrics metrics, int x, int y, Point ppos)
|
||||
{
|
||||
ppos.x = metrics.tilehwid + ((x - y) * metrics.finehwid);
|
||||
ppos.y = (x + y) * metrics.finehhei;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given pixel coordinates, whose origin is at the
|
||||
* top-left of a tile's containing rectangle, to fine coordinates
|
||||
* within that tile. Converted coordinates are placed in the
|
||||
* given point object.
|
||||
*
|
||||
* @param x the x-position pixel coordinate.
|
||||
* @param y the y-position pixel coordinate.
|
||||
* @param fpos the point object to place coordinates in.
|
||||
*/
|
||||
public static void pixelToFine (
|
||||
MisoSceneMetrics metrics, int x, int y, Point fpos)
|
||||
{
|
||||
// calculate line parallel to the y-axis (from the given
|
||||
// x/y-pos to the x-axis)
|
||||
float bY = y - (metrics.fineSlopeY * x);
|
||||
|
||||
// determine intersection of x- and y-axis lines
|
||||
int crossx = (int)((bY - metrics.fineBX) /
|
||||
(metrics.fineSlopeX - metrics.fineSlopeY));
|
||||
int crossy = (int)((metrics.fineSlopeY * crossx) + bY);
|
||||
|
||||
// TODO: final position should check distance between our
|
||||
// position and the surrounding fine coords and return the
|
||||
// actual closest fine coord, rather than just dividing.
|
||||
|
||||
// determine distance along the x-axis
|
||||
float xdist = MathUtil.distance(metrics.tilehwid, 0, crossx, crossy);
|
||||
fpos.x = (int)(xdist / metrics.finelen);
|
||||
|
||||
// determine distance along the y-axis
|
||||
float ydist = MathUtil.distance(x, y, crossx, crossy);
|
||||
fpos.y = (int)(ydist / metrics.finelen);
|
||||
|
||||
// Log.info("Pixel to fine " + StringUtil.coordsToString(x, y) +
|
||||
// " -> " + StringUtil.toString(fpos) + ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given screen-based pixel coordinates to full
|
||||
* scene-based coordinates that include both the tile coordinates
|
||||
* and the fine coordinates in each dimension. Converted
|
||||
* coordinates are placed in the given point object.
|
||||
*
|
||||
* @param sx the screen x-position pixel coordinate.
|
||||
* @param sy the screen y-position pixel coordinate.
|
||||
* @param fpos the point object to place coordinates in.
|
||||
*
|
||||
* @return the point passed in to receive the coordinates.
|
||||
*/
|
||||
public static Point screenToFull (
|
||||
MisoSceneMetrics metrics, int sx, int sy, Point fpos)
|
||||
{
|
||||
// get the tile coordinates
|
||||
Point tpos = new Point();
|
||||
screenToTile(metrics, sx, sy, tpos);
|
||||
|
||||
// get the screen coordinates for the containing tile
|
||||
Point spos = tileToScreen(metrics, tpos.x, tpos.y, new Point());
|
||||
|
||||
// Log.info("Screen to full " +
|
||||
// "[screen=" + StringUtil.coordsToString(sx, sy) +
|
||||
// ", tpos=" + StringUtil.toString(tpos) +
|
||||
// ", spos=" + StringUtil.toString(spos) +
|
||||
// ", fpix=" + StringUtil.coordsToString(
|
||||
// sx-spos.x, sy-spos.y) + "].");
|
||||
|
||||
// get the fine coordinates within the containing tile
|
||||
pixelToFine(metrics, sx - spos.x, sy - spos.y, fpos);
|
||||
|
||||
// toss in the tile coordinates for good measure
|
||||
fpos.x += (tpos.x * FULL_TILE_FACTOR);
|
||||
fpos.y += (tpos.y * FULL_TILE_FACTOR);
|
||||
|
||||
return fpos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @return the point passed in to receive the coordinates.
|
||||
*/
|
||||
public static Point fullToScreen (
|
||||
MisoSceneMetrics metrics, int x, int y, Point spos)
|
||||
{
|
||||
// get the tile screen position
|
||||
int tx = fullToTile(x), ty = fullToTile(y);
|
||||
Point tspos = tileToScreen(metrics, tx, ty, new Point());
|
||||
|
||||
// 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(metrics, 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 spos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given fine coordinate to a full coordinate (a tile
|
||||
* coordinate plus a fine coordinate remainder). The fine coordinate
|
||||
* is assumed to be relative to tile <code>(0, 0)</code>.
|
||||
*/
|
||||
public static int fineToFull (MisoSceneMetrics metrics, int fine)
|
||||
{
|
||||
return toFull(fine / metrics.finegran, fine % metrics.finegran);
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes the supplied tile coordinate and fine coordinate offset
|
||||
* into a full coordinate.
|
||||
*/
|
||||
public static int toFull (int tile, int fine)
|
||||
{
|
||||
return tile * FULL_TILE_FACTOR + fine;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (
|
||||
MisoSceneMetrics metrics, int x, int y)
|
||||
{
|
||||
return getFootprintPolygon(metrics, x, y, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a screen-coordinates polygon framing the two specified
|
||||
* tile-coordinate points.
|
||||
*/
|
||||
public static Polygon getMultiTilePolygon (MisoSceneMetrics metrics,
|
||||
Point sp1, Point sp2)
|
||||
{
|
||||
int x = Math.min(sp1.x, sp2.x), y = Math.min(sp1.y, sp2.y);
|
||||
int width = Math.abs(sp1.x-sp2.x)+1, height = Math.abs(sp1.y-sp2.y)+1;
|
||||
return getFootprintPolygon(metrics, x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a polygon framing the specified scene footprint.
|
||||
*
|
||||
* @param x the x tile coordinate of the "upper-left" of the footprint.
|
||||
* @param y the y tile coordinate of the "upper-left" of the footprint.
|
||||
* @param width the width in tiles of the footprint.
|
||||
* @param height the height in tiles of the footprint.
|
||||
*/
|
||||
public static Polygon getFootprintPolygon (
|
||||
MisoSceneMetrics metrics, int x, int y, int width, int height)
|
||||
{
|
||||
SmartPolygon footprint = new SmartPolygon();
|
||||
Point tpos = MisoUtil.tileToScreen(metrics, x, y, new Point());
|
||||
|
||||
// start with top-center point
|
||||
int rx = tpos.x + metrics.tilehwid, ry = tpos.y;
|
||||
footprint.addPoint(rx, ry);
|
||||
// right point
|
||||
rx += width * metrics.tilehwid;
|
||||
ry += width * metrics.tilehhei;
|
||||
footprint.addPoint(rx, ry);
|
||||
// bottom-center point
|
||||
rx -= height * metrics.tilehwid;
|
||||
ry += height * metrics.tilehhei;
|
||||
footprint.addPoint(rx, ry);
|
||||
// left point
|
||||
rx -= width * metrics.tilehwid;
|
||||
ry -= width * metrics.tilehhei;
|
||||
footprint.addPoint(rx, ry);
|
||||
// end with top-center point
|
||||
rx += height * metrics.tilehwid;
|
||||
ry -= height * metrics.tilehhei;
|
||||
footprint.addPoint(rx, ry);
|
||||
|
||||
return footprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the supplied fine coordinates to the supplied tile coordinates
|
||||
* to compute full coordinates.
|
||||
*
|
||||
* @return the point object supplied as <code>full</code>.
|
||||
*/
|
||||
public static Point tilePlusFineToFull (MisoSceneMetrics metrics,
|
||||
int tileX, int tileY,
|
||||
int fineX, int fineY,
|
||||
Point full)
|
||||
{
|
||||
int dtx = fineX / metrics.finegran;
|
||||
int dty = fineY / metrics.finegran;
|
||||
int fx = fineX - dtx * metrics.finegran;
|
||||
if (fx < 0) {
|
||||
dtx--;
|
||||
fx += metrics.finegran;
|
||||
}
|
||||
int fy = fineY - dty * metrics.finegran;
|
||||
if (fy < 0) {
|
||||
dty--;
|
||||
fy += metrics.finegran;
|
||||
}
|
||||
|
||||
full.x = toFull(tileX + dtx, fx);
|
||||
full.y = toFull(tileY + dty, fy);
|
||||
return full;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns x and y scene coordinates into an integer key.
|
||||
*
|
||||
* @return the hash key, given x and y.
|
||||
*/
|
||||
public static final int coordsToKey (int x, int y)
|
||||
{
|
||||
return ((y << 16) & (0xFFFF0000)) | (x & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the x coordinate from an integer hash key.
|
||||
*
|
||||
* @return the x coordinate.
|
||||
*/
|
||||
public static final int xCoordFromKey (int key)
|
||||
{
|
||||
return (key & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the y coordinate from an integer hash key.
|
||||
*
|
||||
* @return the y coordinate from the hash key.
|
||||
*/
|
||||
public static final int yCoordFromKey (int key)
|
||||
{
|
||||
return ((key >> 16) & 0xFFFF);
|
||||
}
|
||||
|
||||
/** Multiplication factor to embed tile coords in full coords. */
|
||||
protected static final int FULL_TILE_FACTOR = 100;
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
//
|
||||
// $Id: ObjectSet.java 4191 2006-06-13 22:42:20Z ray $
|
||||
//
|
||||
// Narya library - tools for developing networked games
|
||||
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
|
||||
// http://www.threerings.net/code/narya/
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.threerings.miso.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
import com.samskivert.util.ListUtil;
|
||||
|
||||
import com.threerings.miso.Log;
|
||||
import com.threerings.miso.data.ObjectInfo;
|
||||
|
||||
/**
|
||||
* Used to store an (arbitrarily) ordered, low-impact iteratable (doesn't
|
||||
* require object creation), set of {@link ObjectInfo} instances.
|
||||
*/
|
||||
public class ObjectSet
|
||||
{
|
||||
/**
|
||||
* Inserts the supplied object into the set.
|
||||
*
|
||||
* @return true if it was inserted, false if the object was already in
|
||||
* the set.
|
||||
*/
|
||||
public boolean insert (ObjectInfo info)
|
||||
{
|
||||
// bail if it's already in the set
|
||||
int ipos = indexOf(info);
|
||||
if (ipos >= 0) {
|
||||
// log a warning because the caller shouldn't be doing this
|
||||
Log.warning("Requested to add an object to a set that already " +
|
||||
"contains such an object [ninfo=" + info +
|
||||
", oinfo=" + _objs[ipos] + "].");
|
||||
Thread.dumpStack();
|
||||
return false;
|
||||
}
|
||||
|
||||
// otherwise insert it
|
||||
ipos = -(ipos+1);
|
||||
_objs = ListUtil.insert(_objs, ipos, info);
|
||||
_size++;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified object is in the set, false if it is
|
||||
* not.
|
||||
*/
|
||||
public boolean contains (ObjectInfo info)
|
||||
{
|
||||
return (indexOf(info) >= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of objects in this set.
|
||||
*/
|
||||
public int size ()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object with the specified index. The index must & be
|
||||
* between <code>0</code> and {@link #size}<code>-1</code>.
|
||||
*/
|
||||
public ObjectInfo get (int index)
|
||||
{
|
||||
return (ObjectInfo)_objs[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the object at the specified index.
|
||||
*/
|
||||
public void remove (int index)
|
||||
{
|
||||
ListUtil.remove(_objs, index);
|
||||
_size--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified object from the set.
|
||||
*
|
||||
* @return true if it was removed, false if it was not in the set.
|
||||
*/
|
||||
public boolean remove (ObjectInfo info)
|
||||
{
|
||||
int opos = indexOf(info);
|
||||
if (opos >= 0) {
|
||||
remove(opos);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out the contents of this set.
|
||||
*/
|
||||
public void clear ()
|
||||
{
|
||||
_size = 0;
|
||||
Arrays.fill(_objs, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the contents of this object set to an array.
|
||||
*/
|
||||
public ObjectInfo[] toArray ()
|
||||
{
|
||||
ObjectInfo[] info = new ObjectInfo[_size];
|
||||
System.arraycopy(_objs, 0, info, 0, _size);
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this instance.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder("[");
|
||||
for (int ii = 0; ii < _size; ii++) {
|
||||
if (ii > 0) {
|
||||
buf.append(", ");
|
||||
}
|
||||
buf.append(_objs[ii]);
|
||||
}
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the object or it's insertion index if it is
|
||||
* not in the set.
|
||||
*/
|
||||
protected final int indexOf (ObjectInfo info)
|
||||
{
|
||||
return ArrayUtil.binarySearch(_objs, 0, _size, info, INFO_COMP);
|
||||
}
|
||||
|
||||
/** Our sorted array of objects. */
|
||||
protected Object[] _objs = new Object[DEFAULT_SIZE];
|
||||
|
||||
/** The number of objects in the set. */
|
||||
protected int _size;
|
||||
|
||||
/** We simply sort the objects in order of their hash code. We don't
|
||||
* care about their order, it exists only to support binary search. */
|
||||
protected static final Comparator INFO_COMP = new Comparator() {
|
||||
public int compare (Object o1, Object o2) {
|
||||
ObjectInfo do1 = (ObjectInfo)o1;
|
||||
ObjectInfo do2 = (ObjectInfo)o2;
|
||||
if (do1.tileId == do2.tileId) {
|
||||
return ((do1.x << 16) + do1.y) - ((do2.x << 16) + do2.y);
|
||||
} else {
|
||||
return do1.tileId - do2.tileId;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** We start big because we know these will in general contain at
|
||||
* least in the tens of objects. */
|
||||
protected static final int DEFAULT_SIZE = 16;
|
||||
}
|
||||
Reference in New Issue
Block a user