/*
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.network;
import java.awt.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import sim.util.*;
import com.sun.j3d.utils.geometry.*;
import sim.portrayal3d.simple.*;
/**
* This implementation of GenericEdgePortrayal3D uses Arrow,
* which aggregates two primitives. This class provides
* to the super class with uniform/transparent access to all the shapes,
* regardless of the primitives they belong to.
*
* @author Gabriel Balan
* In 2006
*/
public class ArrowEdgePortrayal3D extends PrimitiveEdgePortrayal3D
{
static Double3D dummyFrom = new Double3D(0f,-1f,0f);
static Double3D dummyTo = new Double3D(0f,1f,0f);
public ArrowEdgePortrayal3D()
{
this(null, Color.white, null, DEFAULT_RADIUS);
}
/** @deprecated */
public ArrowEdgePortrayal3D(double radius)
{
this(null, Color.white, null, radius);
}
/** @deprecated */
public ArrowEdgePortrayal3D(double radius, Appearance ap)
{
this(ap, Color.white, null, radius);
}
/** @deprecated */
public ArrowEdgePortrayal3D(Color labelColor)
{
this(null, labelColor, null, DEFAULT_RADIUS);
}
public ArrowEdgePortrayal3D(Appearance appearance, Color labelColor)
{
this(appearance, labelColor, null, DEFAULT_RADIUS);
}
public ArrowEdgePortrayal3D(Color color, Color labelColor)
{
this(appearanceForColor(color), labelColor, null, DEFAULT_RADIUS);
}
/** Assumes that the image is opaque */
public ArrowEdgePortrayal3D(Image image, Color labelColor)
{
this(appearanceForImage(image, true), labelColor, null, DEFAULT_RADIUS);
}
public ArrowEdgePortrayal3D(Appearance appearance, Color labelColor, Font labelFont, double radius)
{
super(new Arrow(radius, dummyFrom, dummyTo, null, null, appearance), appearance, labelColor, labelFont);
}
/** the arrow body has 3 (body, top, bottom), arrow head has 2 (bottom and body) */
protected int numShapes()
{
return 5;
}
/**
* Returns the shape by the given index. Cylinder shapes come first
* (BODY=0, TOP=1, BOTTOM=2), Cone chape come last (BODY=3, CAP=4)
*
* Here's the structure of the j3dModel in this class:
* TransformGroup j3dModel (passed in and out of getModel())
* ->TransformGroup positioning the edge model between the end points.
* ->TransformGroup a clone of the prototypical arrow you pass in the constructor)
* ->TransformGroup arrowCylinderTransformGroup
* ->Cylinder
* ->TransformGroup arrowHeadTransformGroup
* ->Cone
* ->TansformGroup startLable, endLabel TransformGroups
*
**/
protected Shape3D getShape(TransformGroup j3dModel, int shapeIndex)
{
TransformGroup endPointTG = (TransformGroup)(j3dModel.getChild(0));
TransformGroup edgeModelClone = (TransformGroup)(endPointTG.getChild(0));
int coneOffset = 3;
if(shapeIndex < coneOffset) //it's the body
{
TransformGroup arrowBody = (TransformGroup)(edgeModelClone.getChild(0));
Cylinder c = (Cylinder)arrowBody.getChild(0);
return c.getShape(shapeIndex);
}
TransformGroup arrowHead = (TransformGroup)(edgeModelClone.getChild(1));
Cone c = (Cone)arrowHead.getChild(0);
return c.getShape(shapeIndex-coneOffset);
}
protected void init(Node edgeModel)
{
super.init(edgeModel);
Arrow arrow = (Arrow)edgeModel;
arrow.setCapability(Group.ALLOW_CHILDREN_READ);
//In the future I will want to read the cylinder out of its TransformGroup
((TransformGroup)arrow.getChild(0)).setCapability(Group.ALLOW_CHILDREN_READ);
//In the future I will want to read the cone out of its TransformGroup
((TransformGroup)arrow.getChild(1)).setCapability(Group.ALLOW_CHILDREN_READ);
Cylinder body = arrow.getArrowTail();
PrimitivePortrayal3D.setShape3DFlags(body.getShape(Cylinder.BODY));
PrimitivePortrayal3D.setShape3DFlags(body.getShape(Cylinder.TOP));
PrimitivePortrayal3D.setShape3DFlags(body.getShape(Cylinder.BOTTOM));
Cone head = arrow.getArrowHead();
PrimitivePortrayal3D.setShape3DFlags(head.getShape(Cone.BODY));
PrimitivePortrayal3D.setShape3DFlags(head.getShape(Cone.CAP));
}
}