sim.portrayal3d.grid.quad.MeshPortrayal Maven / Gradle / Ivy
Show all versions of mason Show documentation
/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.portrayal3d.grid.quad;
import sim.util.*;
import sim.util.gui.*;
import sim.field.grid.*;
import sim.portrayal3d.grid.*;
import com.sun.j3d.utils.picking.*;
/**
* A QuadPortrayal which relates grid locations with intersections on a mesh (like positions on
* a Go board, coloring and changing the Z location of the intersections.
*
* Bug in MeshPortrayal. It appears that if values in MeshPortrayals
* cause "bends" in the angle of the underlying squares that are too severe (we've seen over 45 degrees),
* then when Java3D tries to pick the square you've double-clicked on, the "bent" squares will insist on
* being included in the pick collection. We believe this to be a bug in Sun's Java3D code. You'll
* see this happen when you double-click on a MeshPortrayal and the wrong-coordinate object pops up.
**/
public class MeshPortrayal extends QuadPortrayal
{
//float[] tmpCoords;
float[] tmpColor;
public MeshPortrayal(ColorMap colorDispenser)
{
this(colorDispenser,0);
}
public MeshPortrayal(ColorMap colorDispenser, double zScale)
{
super(colorDispenser,zScale);
//tmpCoords = new float[12];
tmpColor = new float[4];
}
static final int[] dx = {0, -1, -1, 0};
static final int[] dy = {0, 0, -1, -1};
public void setData(ValueGridCellInfo gridCell, float[] coordinates, float[] colors, int quadIndex,
int gridWidth, int gridHeight)
{
// cast the width and height into a mesh form (1- the normal values)
gridWidth -= 1;
gridHeight -= 1;
int x = gridCell.x;
int y = gridCell.y;
float value = (float)gridCell.value();
colorDispenser.getColor(value).getColorComponents(tmpColor);
value*=zScale;
// 3-2
// | | <- this is how I go through a quad.
// 0-1
//
// 3-2 3-2
// | | | |
// 0-1 0-1
// 3-2 3-2
// | | | |
// 0-1 0-1
//look for the four quads this vertex is part of.
for(int i=0; i<4; i++)
{
int cellx = x+dx[i];
int celly = y+dy[i];
if(cellx<0 || celly<0 || cellx>=gridWidth || celly>=gridHeight)
continue;
int iQuadIndex = cellx*gridHeight+celly;
int offset = iQuadIndex * 12 + i * 3;
coordinates[offset+0] = x;
coordinates[offset+1] = y;
coordinates[offset+2] = value + 0.1f;
System.arraycopy(tmpColor, 0, colors, (iQuadIndex*4+i)*3, 3); // 3 color values -- alpha transparency doesn't work here :-(
}
}
public Int2D getCellForIntersection(PickIntersection pi, Grid2D field)
{
int[] indices = pi.getPrimitiveVertexIndices();
int closenessOffset = pi.getClosestVertexIndex();
closenessOffset = indices[closenessOffset]%4;
// 3 2
// 0 1
int xExtraOffset = (closenessOffset ==3 || closenessOffset ==0)? 0 :1;
int yExtraOffset = (closenessOffset ==3 || closenessOffset ==2)? 1 :0;
int height = field.getHeight();
int x = (indices[0]/4)/(height-1)+xExtraOffset;
int y = (indices[0]/4)%(height-1)+yExtraOffset;
return new Int2D(x,y);
}
}