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