001/** 002 * Axis -- Representation of a set of axes around a origin of a coordinate system. 003 * 004 * Copyright (C) 2009-2023, by 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 * 018 * 019 * This class is based on "org.j3d.renderer.java3d.geom.Axis" which bore the following 020 * notation: J3D.org Copyright (c) 2000 Java Source This source is licensed under the GNU 021 * LGPL v2.1 022 */ 023package geomss.app; 024 025import jahuwaldt.j3d.geom.GeometryData; 026import jahuwaldt.j3d.geom.ConeGenerator; 027import jahuwaldt.j3d.geom.CoordinateUtils; 028import jahuwaldt.j3d.geom.CylinderGenerator; 029import java.util.ResourceBundle; 030import org.jogamp.java3d.*; 031import org.jogamp.vecmath.AxisAngle4f; 032import org.jogamp.vecmath.Color3f; 033 034/** 035 * Representation of a set of axes around the coordinates. 036 * <p> 037 * Each axis is color coordinated and the length can be adjusted. 038 * </p> 039 * <p> 040 * X axis: Red<br> 041 * Y axis: Green<br> 042 * Z axis: Blue 043 * </p> 044 * 045 * <p> Modified by: Joseph A.Huwaldt </p> 046 * 047 * @author Jason Taylor, based on the work by Justin Couch 048 * @version June 4, 2023 049 */ 050public class Axis extends Group { 051 052 // The resource bundle for this class. 053 private static final ResourceBundle RB 054 = ResourceBundle.getBundle("geomss.app.AxisResources", java.util.Locale.getDefault()); 055 056 /** 057 * The default length of the axis 058 */ 059 private static final float DEFAULT_AXIS_LENGTH = 5; 060 061 /** 062 * The scale to apply to the length to get the thickness for the arrows 063 */ 064 private static final float DEFAULT_X_SCALE = 0.05f; 065 066 /** 067 * Create a default axis object with each item length 5 from the origin 068 */ 069 public Axis() { 070 this(DEFAULT_AXIS_LENGTH, 0); 071 } 072 073 /** 074 * Create an axis object with the given axis length from the origin. 075 * 076 * @param length The length to use. Must be positive 077 */ 078 public Axis(float length) { 079 this(length, 0); 080 } 081 082 /** 083 * Create an axis object with the given axis length from the origin. The transparency 084 * of the axis can be controlled through the use of the second parameter. 085 * 086 * @param length The length to use. Must be positive 087 * @param transparency The amount of transparency in the axis (0=opaque, 1=fully 088 * transparent). 089 */ 090 public Axis(float length, float transparency) { 091 if (length <= 0) 092 throw new IllegalArgumentException(RB.getString("axisLengthNegative")); 093 094 // Change the thickness in propotion to the length. 095 float X_SIZE = length * DEFAULT_X_SCALE; 096 097 // Create a single item of geometry and then share/rotate as needed 098 //BoxGenerator box_gen = new BoxGenerator(X_SIZE, length, X_SIZE); 099 CylinderGenerator cyl_gen = new CylinderGenerator(length, X_SIZE, 4); 100 101 int format = GeometryArray.COORDINATES | GeometryArray.NORMALS; 102 GeometryData data = new GeometryData(); 103 data.geometryType = GeometryData.TRIANGLE_STRIPS; 104 data.geometryComponents = GeometryData.NORMAL_DATA; 105 106 cyl_gen.generate(data); 107 108 CoordinateUtils cu = new CoordinateUtils(); 109 cu.translate(data.coordinates, 110 data.vertexCount, 111 0, 112 length / 2, 113 0); 114 115 TriangleStripArray axis_array 116 = new TriangleStripArray(data.vertexCount, format, data.stripCounts); 117 118 axis_array.setCoordinates(0, data.coordinates); 119 axis_array.setNormals(0, data.normals); 120 121 ConeGenerator cone_gen = new ConeGenerator(X_SIZE * 4, X_SIZE * 2, 3); 122 data.geometryType = GeometryData.INDEXED_TRIANGLE_FANS; 123 data.vertexCount = 0; 124 data.coordinates = null; 125 data.normals = null; 126 data.stripCounts = null; 127 128 cone_gen.generate(data); 129 130 cu.translate(data.coordinates, 131 data.vertexCount, 132 0, 133 length + (X_SIZE * 2), 134 0); 135 136 IndexedTriangleStripArray cone_array 137 = new IndexedTriangleStripArray(data.vertexCount, 138 format, 139 data.indexesCount, 140 data.stripCounts); 141 142 cone_array.setCoordinates(0, data.coordinates); 143 cone_array.setNormals(0, data.normals); 144 cone_array.setCoordinateIndices(0, data.indexes); 145 cone_array.setNormalIndices(0, data.indexes); 146 147 Color3f blue = new Color3f(0, 0, 0.8f); 148 Material blue_material = new Material(); 149 blue_material.setDiffuseColor(blue); 150 blue_material.setLightingEnable(true); 151 152 Color3f red = new Color3f(0.8f, 0, 0); 153 Material red_material = new Material(); 154 red_material.setDiffuseColor(red); 155 red_material.setLightingEnable(true); 156 157 Color3f green = new Color3f(0, 0.8f, 0); 158 Material green_material = new Material(); 159 green_material.setDiffuseColor(green); 160 green_material.setLightingEnable(true); 161 162 Appearance x_app = new Appearance(); 163 x_app.setMaterial(red_material); 164 165 Appearance y_app = new Appearance(); 166 y_app.setMaterial(green_material); 167 168 Appearance z_app = new Appearance(); 169 z_app.setMaterial(blue_material); 170 171 if (transparency != 0) { 172 TransparencyAttributes attr 173 = new TransparencyAttributes(TransparencyAttributes.FASTEST, 174 transparency); 175 176 x_app.setTransparencyAttributes(attr); 177 y_app.setTransparencyAttributes(attr); 178 z_app.setTransparencyAttributes(attr); 179 } 180 181 Shape3D x_shape = new Shape3D(); 182 x_shape.setAppearance(x_app); 183 x_shape.addGeometry(axis_array); 184 x_shape.addGeometry(cone_array); 185 186 Shape3D y_shape = new Shape3D(); 187 y_shape.setAppearance(y_app); 188 y_shape.addGeometry(axis_array); 189 y_shape.addGeometry(cone_array); 190 191 Shape3D z_shape = new Shape3D(); 192 z_shape.setAppearance(z_app); 193 z_shape.addGeometry(axis_array); 194 z_shape.addGeometry(cone_array); 195 196 // The three axis values are all pointing up along the Y axis. Apply a 197 // transform to X and Z to move them to the correct position. 198 Transform3D tx = new Transform3D(); 199 AxisAngle4f angle = new AxisAngle4f(); 200 201 // X Axis first 202 angle.set(0, 0, 1, -(float)(Math.PI * 0.5f)); 203 tx.setRotation(angle); 204 205 TransformGroup x_tg = new TransformGroup(tx); 206 x_tg.addChild(x_shape); 207 208 angle.set(1, 0, 0, (float)(Math.PI * 0.5f)); 209 tx.setRotation(angle); 210 211 TransformGroup z_tg = new TransformGroup(tx); 212 z_tg.addChild(z_shape); 213 214 addChild(x_tg); 215 addChild(y_shape); 216 addChild(z_tg); 217 } 218}