sim.portrayal3d.network.SimpleEdgePortrayal3D Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mason Show documentation
Show all versions of mason Show documentation
MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.
The newest version!
/*
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 sim.portrayal3d.*;
import sim.portrayal.*;
import sim.util.*;
import java.awt.*;
import sim.field.network.*;
import javax.vecmath.*;
import javax.media.j3d.*;
/*
* A simple portrayal for edges in a network field.
*/
public class SimpleEdgePortrayal3D extends SimplePortrayal3D
{
public Color fromColor;
public Color toColor;
public Color labelColor;
public Font labelFont;
public boolean showLabels;
public void setShowLabels(boolean val){showLabels = val;}
public boolean getShowLabels(){return showLabels;}
public SimpleEdgePortrayal3D()
{
this(Color.gray, Color.gray, Color.white);
}
/** If fromPaint == toPaint, one single color line will be drawn, and if labelPaint is null, no label is drawn. */
public SimpleEdgePortrayal3D(Color edgeColor, Color labelColor)
{
this(edgeColor, edgeColor, labelColor, new Font("SansSerif", Font.PLAIN, 60));
}
public SimpleEdgePortrayal3D(Color fromColor, Color toColor, Color labelColor)
{
this(fromColor, toColor, labelColor, new Font("SansSerif", Font.PLAIN, 60));
}
/**
* If fromPaint == toPaint, one single color line will be drawn, and if
* labelPaint is null, no label is drawn.
*/
public SimpleEdgePortrayal3D(Color fromColor, Color toColor, Color labelColor, Font labelFont)
{
this.fromColor = fromColor;
this.toColor = toColor;
this.labelColor = labelColor;
this.labelFont = labelFont;
}
static Transform3D transformForOffset(double x, double y, double z)
{
Transform3D offset = new Transform3D();
offset.setTranslation(new Vector3d(x, y, z));
return offset;
}
static Transform3D transformForOffset(double[] xyz)
{
Transform3D offset = new Transform3D();
offset.setTranslation(new Vector3d(xyz));
return offset;
}
static Transform3D transformForOffset(float x, float y, float z)
{
Transform3D offset = new Transform3D();
offset.setTranslation(new Vector3f(x, y, z));
return offset;
}
/**
* Returns a name appropriate for the edge. By default, this returns
* (edge.info == null ? "" : "" + edge.info). Override this to make a more
* customized label to display for the edge on-screen.
*/
public String getLabel(Edge edge)
{
Object obj = edge.info;
if (obj == null)
return "";
return "" + obj;
}
double[] startPoint = new double[3];
double[] endPoint = new double[3];
double[] middlePoint = new double[3];
public TransformGroup getModel(Object object, TransformGroup j3dModel)
{
Double3D firstPoint;
Double3D secondPoint;
SpatialNetwork3D field;
EdgeWrapper drawInfo;
Transform3D trans = null;
com.sun.j3d.utils.geometry.Text2D tempText;
drawInfo = (EdgeWrapper) object;
field = (SpatialNetwork3D) drawInfo.fieldPortrayal.getField();
secondPoint = field.getObjectLocation(drawInfo.edge.to());
firstPoint = field.getObjectLocation(drawInfo.edge.from());
startPoint[0] = firstPoint.x;
startPoint[1] = firstPoint.y;
startPoint[2] = firstPoint.z;
endPoint[0] = secondPoint.x;
endPoint[1] = secondPoint.y;
endPoint[2] = secondPoint.z;
middlePoint[0] = (secondPoint.x + firstPoint.x) / 2;
middlePoint[1] = (secondPoint.y + firstPoint.y) / 2;
middlePoint[2] = (secondPoint.z + firstPoint.z) / 2;
if (showLabels)
trans = transformForOffset(middlePoint);
if (j3dModel == null)
{
// build the whole model from scratch
j3dModel = new TransformGroup();
j3dModel.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
LineArray lineGeometry1 = new LineArray(2, GeometryArray.COORDINATES);
lineGeometry1.setCoordinate(0, startPoint);
lineGeometry1.setCoordinate(1, middlePoint);
lineGeometry1.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
Shape3D lineShape1 = new Shape3D(lineGeometry1, SimplePortrayal3D.appearanceForColor(fromColor));
lineShape1.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
setPickableFlags(lineShape1);
lineShape1.setUserData(drawInfo);
j3dModel.addChild(lineShape1);
LineArray lineGeometry2 = new LineArray(2, GeometryArray.COORDINATES);
lineGeometry2.setCoordinate(0, middlePoint);
lineGeometry2.setCoordinate(1, endPoint);
lineGeometry2.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
Shape3D lineShape2 = new Shape3D(lineGeometry2, SimplePortrayal3D.appearanceForColor(toColor));
lineShape2.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
setPickableFlags(lineShape2);
lineShape2.setUserData(drawInfo);
j3dModel.addChild(lineShape2);
// draw the edge labels if the user wants
if (showLabels)
{
String str = getLabel(drawInfo.edge);
com.sun.j3d.utils.geometry.Text2D text = new com.sun.j3d.utils.geometry.Text2D(
str, new Color3f(labelColor), labelFont.getFamily(),
labelFont.getSize(), labelFont.getStyle());
text.setRectangleScaleFactor(1.0f / 16.0f);
OrientedShape3D o3d = new OrientedShape3D(text.getGeometry(),
text.getAppearance(),
OrientedShape3D.ROTATE_ABOUT_POINT,
new Point3f(0, 0, 0));
o3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); // may need
// to change
// the
// appearance
// (see
// below)
o3d.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); // may need
// to change
// the
// geometry
// (see
// below)
o3d.clearCapabilityIsFrequent(Shape3D.ALLOW_APPEARANCE_WRITE);
o3d.clearCapabilityIsFrequent(Shape3D.ALLOW_GEOMETRY_WRITE);
// make the offset TransformGroup
TransformGroup o = new TransformGroup();
o.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
o.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
o.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
o.clearCapabilityIsFrequent(TransformGroup.ALLOW_CHILDREN_READ);
o.setTransform(trans);
o.setUserData(str);
// the label shouldn't be pickable -- we'll turn this off in the
// TransformGroup
clearPickableFlags(o);
o.addChild(o3d); // Add label to the offset TransformGroup
j3dModel.addChild(o);
tempText = new com.sun.j3d.utils.geometry.Text2D("",
new Color3f(labelColor), labelFont.getFamily(),
labelFont.getSize(), labelFont.getStyle());
// tempText = new Text3D(new Font3D(labelFont, new
// FontExtrusion()), "");
tempText.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
tempText.setCapability(Appearance.ALLOW_TEXTURE_READ);
}
} else
{
Shape3D shape = (Shape3D)j3dModel.getChild(0);
LineArray geo = (LineArray)shape.getGeometry();
geo.setCoordinate(0, startPoint);
geo.setCoordinate(1, middlePoint);
shape = (Shape3D)j3dModel.getChild(1);
geo = (LineArray)shape.getGeometry();
geo.setCoordinate(0, startPoint);
geo.setCoordinate(1, endPoint);
if (showLabels)
{
TransformGroup tg = (TransformGroup) j3dModel.getChild(2);
String str = getLabel(drawInfo.edge);
// see if the label has changed?
if (!tg.getUserData().equals(str))
{
// ugh. This is really slow. Using the Shape3D results in
// huge text, so, the default
// value has to be changed in the constructor.
// make the text again
com.sun.j3d.utils.geometry.Text2D text = new com.sun.j3d.utils.geometry.Text2D(
str, new Color3f(labelColor),
labelFont.getFamily(), labelFont.getSize(),
labelFont.getStyle());
text.setRectangleScaleFactor(1.0f / 16.0f);
// Shape3D text = new Shape3D(new Text3D(new
// Font3D(labelFont, new FontExtrusion()), str));
// Grab the OrientedShape3D
OrientedShape3D o3d = (OrientedShape3D) (tg.getChild(0));
// update its geometry and appearance to reflect the new
// text.
o3d.setGeometry(text.getGeometry());
o3d.setAppearance(text.getAppearance());
// update user data to reflect the new text
tg.setUserData(str);
}
// update the position of the text
tg.setTransform(trans);
}
}
return j3dModel;
}
public String getName(LocationWrapper wrapper)
{
// indicate it's an edge
return "Edge: " + super.getName(wrapper);
}
public static class EdgeWrapper extends LocationWrapper
{
// we keep this around so we don't keep allocating MutableDoubles
// every time getObject is called -- that's wasteful, but more
// importantly,
// it causes the inspector to load its property inspector entirely
// again,
// which will cause some flashing...
MutableDouble val = null;
SpatialNetwork3D field;
public EdgeWrapper(FieldPortrayal fieldPortrayal, Edge edge)
{
super(edge.info, edge, fieldPortrayal);
this.edge = edge;
field = (SpatialNetwork3D)(fieldPortrayal.getField());
}
public String getLocationName()
{
Edge edge = (Edge)getLocation();
if (field != null && field.network != null)
{
// do I still exist in the field? Check the from() value
Bag b = field.network.getEdgesOut(edge.from());
// if (b != null) // no longer necessary
for(int x=0;x " + edge.to();
}
return "Gone. Was: " + edge.from() + " --> " + edge.to();
}
/*
public String toString()
{
return "" + edge.info;
}
public String getLocationName()
{
SpatialNetwork3D field = (SpatialNetwork3D) fieldPortrayal.getField();
if (field != null && field.network != null)
{
// do I still exist in the field? Check the from() value
Bag b = field.network.getEdgesOut(edge.from());
for (int x = 0; x < b.numObjs; x++)
if (b.objs[x] == edge)
return "" + edge.from() + " --> " + edge.to();
}
return "Gone. Was: " + edge.from() + " --> " + edge.to();
}
public Object getObject()
{
return edge;
}
*/
public Edge edge;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy