/*
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.simple;
import sim.portrayal3d.*;
import javax.vecmath.*;
import sim.portrayal.*;
import javax.media.j3d.*;
import java.awt.*;
/**
* Portrays objects as a cube of the specified color or appearance (flat opaque white by default)
* which fills the region from (-0.5*scale,-0.5*scale,-0.5*scale) to (0.5*scale,0.5*scale,0.5*scale).
* Objects portrayed by this portrayal are selectable.
*/
public class CubePortrayal3D extends SimplePortrayal3D
{
Appearance appearance;
boolean generateTextureCoordinates;
/** Constructs a CubePortrayal3D with a default (flat opaque white) appearance and a scale of 1.0. */
public CubePortrayal3D()
{
this(1f);
}
/** Constructs a CubePortrayal3D with a default (flat opaque white) appearance and the given scale. */
public CubePortrayal3D(double scale)
{
this(Color.white,scale);
}
/** Constructs a CubePortrayal3D with a flat opaque appearance of the given color and a scale of 1.0. */
public CubePortrayal3D(Color color)
{
this(color,1f);
}
/** Constructs a CubePortrayal3D with a flat opaque appearance of the given color and the given scale. */
public CubePortrayal3D(Color color, double scale)
{
this(appearanceForColor(color), false, scale);
}
/** Constructs a CubePortrayal3D with the given (opaque) image and a scale of 1.0. */
public CubePortrayal3D(Image image)
{
this(image,1f);
}
/** Constructs a CubePortrayal3D with the given (opaque) image and scale. */
public CubePortrayal3D(Image image, double scale)
{
this(appearanceForImage(image,true),true,scale);
}
/** Constructs a CubePortrayal3D with the given appearance and scale, plus whether or not to generate normals or texture coordinates. Without texture coordiantes, a texture will not be displayed */
public CubePortrayal3D(Appearance appearance, boolean generateTextureCoordinates, double scale)
{
this.generateTextureCoordinates = generateTextureCoordinates;
this.appearance = appearance;
for(int i=0;i<scaledVerts.length;i++)
scaledVerts[i] = verts[i]*(float)scale;
}
final float[] scaledVerts = new float[verts.length];
static final float[] verts =
{
// front face
0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f,
// back face
-0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f,
// right face
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f,
// left face
-0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
// top face
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f,
// bottom face
-0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f,
};
public TransformGroup getModel(Object obj, TransformGroup j3dModel)
{
if(j3dModel==null)
{
j3dModel = new TransformGroup();
j3dModel.setCapability(Group.ALLOW_CHILDREN_READ);
QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES |
(generateTextureCoordinates ? QuadArray.TEXTURE_COORDINATE_2 : 0) );
quadArray.setCoordinates(0, scaledVerts);
// specify the four corners of the image are four vertices (Java3D pretends that the
// image runs from (0,0) to (1,1) in pixels). Thus the image is stretched to fit the
// quad, but of course the quad has already been set up to be the right dimensions for the
// image, so it's all good. -- dunno if this works, it works right for ImagePortrayal3D
// -- maybe we'll have to go back to using a Box, ugh.
if (generateTextureCoordinates)
{
quadArray.setTextureCoordinate(0,0,new TexCoord2f(1,1));
quadArray.setTextureCoordinate(0,1,new TexCoord2f(1,0));
quadArray.setTextureCoordinate(0,2,new TexCoord2f(0,0));
quadArray.setTextureCoordinate(0,3,new TexCoord2f(0,1));
}
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_BACK);
if(!appearance.isLive())
appearance.setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_WRITE);
appearance.setPolygonAttributes(pa);
Shape3D localShape = new Shape3D(quadArray,appearance);
localShape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
setPickableFlags(localShape);
// build a LocationWrapper for the object
LocationWrapper pickI = new LocationWrapper(obj, null, getCurrentFieldPortrayal());
localShape.setUserData(pickI);
j3dModel.addChild(localShape);
}
return j3dModel;
}
}