All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sim.portrayal3d.network.SimpleEdgePortrayal3D Maven / Gradle / Ivy

Go to download

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
    {
    Color fromColor;
    Color toColor;
    Color labelColor;
    Font labelFont;
    //Font3D labelFont3D;     // only used if we're doing Text3D
    boolean showLabels;
        
    // A larger font size makes the label bigger but also uses much more memory
    static final int FONT_SIZE = 18;
    // A smaller scaling factor reduces the label size
    static final double SCALING_MODIFIER = 1.0 / 5.0; 
        
    double labelScale = 1.0;
    public double getLabelScale() { return labelScale; }
    public void setLabelScale(double s) { labelScale = Math.abs(s); }
        
    /** @deprecated */
    public void setShowLabels(boolean val) { showLabels = val; }

    /** @deprecated */
    public boolean getShowLabels() { return showLabels; }

    public SimpleEdgePortrayal3D()
        {
        this(Color.gray, Color.gray, Color.white, null);
        }

    public SimpleEdgePortrayal3D(Color edgeColor, Color labelColor)
        {
        this(edgeColor, edgeColor, labelColor, null);
        }

    public SimpleEdgePortrayal3D(Color edgeColor, Color labelColor, Font labelFont)
        {
        this(edgeColor, edgeColor, labelColor, labelFont);
        }

    public SimpleEdgePortrayal3D(Color fromColor, Color toColor, Color labelColor)
        {
        this(fromColor, toColor, labelColor, null);
        }

    /**
     * If fromColor == toColor, one single color line will be drawn, and if
     * labelColor 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;
        if (labelFont == null) 
            labelFont = new Font("SansSerif", Font.PLAIN, FONT_SIZE);
        this.labelFont = labelFont;
        //labelFont3D = new Font3D(labelFont, new FontExtrusion());
        showLabels = (labelColor != null);
        if (this.labelColor == null) 
            this.labelColor = Color.white;  // just in case the user turns on labels again
        }

    Transform3D transformForOffset(double x, double y, double z)
        {
        Transform3D offset = new Transform3D();
        offset.setTranslation(new Vector3d(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;
        LocationWrapper wrapper;
        Transform3D trans = null;
        
        wrapper = (LocationWrapper) object;
        Edge edge = (Edge)(wrapper.getLocation());
        field = (SpatialNetwork3D) wrapper.fieldPortrayal.getField();

        secondPoint = field.getObjectLocation(edge.to());
        firstPoint = field.getObjectLocation(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[0], middlePoint[1], middlePoint[2]);

        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(wrapper); 
            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(wrapper); 
            j3dModel.addChild(lineShape2);


            // draw the edge labels if the user wants
            if (showLabels)
                {
                String str = getLabel(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((float)(labelScale * SCALING_MODIFIER));

                //text = new Shape3D(new Text3D(labelFont3D, ""));
                                
                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);
                }
            } 
        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(edge);

                // see if the label has changed?
                if (!tg.getUserData().equals(str))
                    {
                    // 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((float)(labelScale * SCALING_MODIFIER));

                    //Shape3D text = new Shape3D(new Text3D(labelFont3D, 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);
        }
    }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy