001/**
002 * J3DGeomVector -- A Java3D node that represents a GeomVector in a J3D scene graph.
003 * 
004 * Copyright (C) 2009-2016, Joseph A. Huwaldt. All rights reserved.
005 * 
006 * This library is free software; you can redistribute it and/or modify it under the terms
007 * of the GNU Lesser General Public License as published by the Free Software Foundation;
008 * either version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
012 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
013 * 
014 * You should have received a copy of the GNU Lesser General Public License along with
015 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place -
016 * Suite 330, Boston, MA 02111-1307, USA. Or visit: http://www.gnu.org/licenses/lgpl.html
017 */
018package geomss.j3d;
019
020import geomss.app.GeomSSCanvas3D;
021import geomss.geom.GeomPoint;
022import geomss.geom.GeomVector;
023import static java.util.Objects.requireNonNull;
024import javax.measure.quantity.Dimensionless;
025import javax.measure.unit.SI;
026import javax.media.j3d.*;
027import javax.vecmath.*;
028
029/**
030 * A Java 3D node that represents a <code>GeomVector</code> in a Java 3D scene graph.
031 *
032 * <p> Modified by: Joseph A. Huwaldt </p>
033 *
034 * @author Joseph A. Huwaldt, Date: June 14, 2009
035 * @version September 9, 2016
036 */
037public class J3DGeomVector extends J3DGeomGroup<GeomVector> {
038
039    //  The switch for main or mirrored geometry.
040    private Switch _symmSG;
041
042    /**
043     * Construct a J3DGeomVector using the specified GeomVector as a reference.
044     *
045     * @param canvas   The canvas that the geometry is being rendered into.
046     * @param geometry The GeomSS geometry to be turned into a Java3D node.
047     */
048    public J3DGeomVector(GeomSSCanvas3D canvas, GeomVector geometry) {
049        super(requireNonNull(canvas), requireNonNull(geometry));
050    }
051
052    /**
053     * Set the display of a mirrored copy of this geometry. This is called from
054     * "setDisplayed()" to turn on and off the display of mirrored geometry without
055     * changing the "mirrored state" of the object. This call does not affect the output
056     * of "isMirrored()".
057     */
058    @Override
059    protected void internalSetMirrored(boolean mirrored) {
060        if (mirrored)
061            _symmSG.setWhichChild(Switch.CHILD_ALL);
062        else
063            _symmSG.setWhichChild(0);
064    }
065
066    /**
067     * Create a new Java 3D <code>Group</code> that contains the geometry contained in
068     * this object. This method is called from <code>createSceneGraph</code>. Sub-classes
069     * must over-ride this method to provide geometry specific implementations.
070     *
071     * @return New Java 3D Group that contains the geometry in this object.
072     * @see #createSceneGraph
073     */
074    @Override
075    protected Group createGeometry() {
076
077        //      Create a line and a point array.
078        GeomVector thisVector = this.getGeomElement();
079        int nVerts = 2;
080        LineArray lineA = new LineArray(nVerts, LineArray.COORDINATES | LineArray.COLOR_4);
081        PointArray pointA = new PointArray(1, PointArray.COORDINATES | PointArray.COLOR_4);
082
083        //      Set the coordinates of the line.
084        J3DRenderingPrefs drawPrefs = getRenderingPrefs();
085        Color4f pointColor = drawPrefs.getPointColorJ3D();
086        Color4f lineColor = drawPrefs.getLineColorJ3D();
087
088        //      Get the origin point.
089        GeomPoint o = thisVector.getOrigin().to(SI.METER);      //      Convert all geometry to meters.
090        int dims = o.getPhyDimension();
091        double x = o.getValue(0);
092        double y = (dims > 1 ? o.getValue(1) : 0);
093        double z = (dims > 2 ? o.getValue(2) : 0);
094        Point3d point3d = new Point3d(x, y, z);
095
096        lineA.setCoordinate(0, point3d);                //      Store start of line segment.
097        lineA.setColor(0, lineColor);
098        pointA.setCoordinate(0, point3d);
099        pointA.setColor(0, pointColor);
100
101        //      Create a point representing the other end of the vector.
102        if (!thisVector.getUnit().equals(Dimensionless.UNIT))
103            thisVector = (GeomVector)thisVector.to(SI.METER);   //      Convert all geometry to meters.
104
105        x += thisVector.getValue(0);
106        y += (dims > 1 ? thisVector.getValue(1) : 0);
107        z += (dims > 2 ? thisVector.getValue(2) : 0);
108        point3d = new Point3d(x, y, z);
109
110        lineA.setCoordinate(1, point3d);                //      Store start of line segment.
111        lineA.setColor(1, lineColor);
112
113        //      Create a 3D shape from the line array
114        Shape3D lineShape = new GeomShape3D(thisVector, lineA);
115
116        //      Define the appearance of the line.
117        Appearance lineAppearance = new Appearance();
118        LineAttributes lineAttrib = new LineAttributes();
119        lineAttrib.setLineWidth(drawPrefs.getLineWidth());
120        lineAppearance.setLineAttributes(lineAttrib);
121        lineShape.setAppearance(lineAppearance);
122
123        //      Create a 3D shape from the point array
124        Shape3D pointShape = new GeomShape3D(thisVector, pointA);
125        Appearance appearance = new Appearance();
126        pointShape.setAppearance(appearance);
127        appearance.setPointAttributes(new PointAttributes(drawPrefs.getPointSize(), true));
128
129        //      Create a group for the main geometry (unmirrored)
130        //      that contains each part of the display properties of a GeomVector.
131        Group renderGroup = new Switch(Switch.CHILD_ALL);
132        renderGroup.setCapability(Switch.ALLOW_SWITCH_READ);
133        renderGroup.setCapability(Switch.ALLOW_SWITCH_WRITE);
134
135        //      Add the geometry to the display switch.
136        renderGroup.addChild(lineShape);
137        renderGroup.addChild(pointShape);
138
139        //      Add the basic unmirrored geometry to the symmetry switch.
140        _symmSG = new Switch();
141        _symmSG.setCapability(Switch.ALLOW_SWITCH_READ);
142        _symmSG.setCapability(Switch.ALLOW_SWITCH_WRITE);
143        _symmSG.addChild(renderGroup);
144
145        //      Clone the basic geometry to make the mirrored geometry.
146        Node mirrored = renderGroup.cloneTree();
147
148        //      Create a mirror across the XZ plane of symmetry transform.
149        Transform3D symmT = new Transform3D();
150        symmT.setScale(new Vector3d(1, -1, 1));
151        TransformGroup symmTG = new TransformGroup(symmT);
152
153        //      Add the mirrored geometry to the symmetry transform group.
154        symmTG.addChild(mirrored);
155
156        //      Add the mirrored geometry to the symmetry switch.
157        _symmSG.addChild(symmTG);
158
159        //      By default, display only the main geometry (not the mirrored).
160        _symmSG.setWhichChild(0);
161
162        return _symmSG;
163    }
164
165    /**
166     * Creates a new instance of the node. This routine is called by
167     * <code>cloneTree</code> to duplicate the current node.
168     *
169     * @param forceDuplicate when set to <code>true</code>, causes the
170     *                       <code>duplicateOnCloneTree</code> flag to be ignored. When
171     *                       <code>false</code>, the value of each node's
172     *                       <code>duplicateOnCloneTree</code> variable determines whether
173     *                       NodeComponent data is duplicated or copied.
174     * @return A new instance of this Java3D node.
175     */
176    @Override
177    public Node cloneNode(boolean forceDuplicate) {
178        J3DGeomVector node = new J3DGeomVector(this.getCanvas3D(), this.getGeomElement());
179        node.duplicateNode(this, forceDuplicate);
180        return node;
181    }
182}