001 /** 002 * NDViewer.java 003 * 004 * This file is part of jndclifford package and it's distributed under the terms of the MIT license. 005 * 006 * The MIT License : 007 * ----------------- 008 * Copyright (c) 2002, 2003, 2004, 2005 Pietro Brignola 009 * 010 * Permission is hereby granted, free of charge, to any person obtaining a 011 * copy of this software and associated documentation files (the "Software"), 012 * to deal in the Software without restriction, including without limitation 013 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 014 * and/or sell copies of the Software, and to permit persons to whom the 015 * Software is furnished to do so, subject to the following conditions: 016 * The above copyright notice and this permission notice shall be included in 017 * all copies or substantial portions of the Software. 018 * 019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 022 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 023 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 024 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 025 * DEALINGS IN THE SOFTWARE. 026 */ 027 028 package jndclifford; 029 030 import javax.swing.*; 031 import java.awt.*; 032 import java.awt.event.*; 033 import java.io.*; 034 import javax.swing.event.*; 035 036 import com.sun.j3d.utils.universe.*; 037 import com.sun.j3d.utils.behaviors.vp.*; 038 039 import javax.media.j3d.*; 040 import javax.vecmath.*; 041 042 import java.awt.event.*; 043 import java.util.*; 044 045 import jclifford.*; 046 047 /** 048 * <p>NDViewer renders, interactively rotatable, traslatable, and zoomable 049 * geometric scene using Clifford Algebra in 4D Projective space.</p> 050 * @version <p>0.2</p> 051 * @author <p>Realized by <a href="mailto:vassallo@csai.unipa.it">Giorgio Vassallo</a>, <a href="mailto:pietro.brignola@libero.it">Pietro Brignola</a>, May 2003.</p> 052 */ 053 public class NDViewer extends JFrame{ 054 055 /** 056 * Creates a MVViewer Object. 057 */ 058 public NDViewer() 059 { 060 //Calling super constructor 061 super("3D Projective MultiVector Viewer"); 062 063 //Adding window listener for closing operation 064 addWindowListener( 065 new WindowAdapter(){ 066 public void windowClosing(WindowEvent e){ 067 //Exit 068 System.exit(0); 069 } 070 } 071 ); 072 073 //Creating new empty scene graph 074 draw(new LinkedList()); 075 } 076 077 /** 078 * Creates a user defined scene and attach it to the virtual universe. 079 * Axis are present in the scene and background color is black. 080 * @param drawlist list of the Clifford elements (with relative color) to draw. 081 */ 082 public void draw(LinkedList drawlist) 083 { 084 draw(drawlist, new Color3f(0.0f, 0.0f, 0.0f), true); 085 } 086 087 /** 088 * Creates a user defined scene and attach it to the virtual universe. 089 * @param drawlist list of the Clifford elements (with relative color) to draw. 090 * @param backgroundcolor the color of the background. 091 * @param axispresence specifies axis presence in the scene. 092 */ 093 public void draw(LinkedList drawlist, Color3f backgroundcolor, boolean axispresence) 094 { 095 //Finds the preferred GraphicsConfiguration object for the system 096 GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); 097 098 //Constructs and initializes a new Canvas3D using the preferred GraphicsConfiguration 099 Canvas3D canvas3D = new Canvas3D(config); 100 101 //Adding Canvas3D to the pane 102 getContentPane().removeAll(); 103 getContentPane().add("Center", canvas3D); 104 105 //Creating SimpleUniverse (Convenience Utility class) 106 //This class sets up a minimal user environment to quickly and easily get a Java 3D program 107 //up and running. 108 SimpleUniverse simpleU = new SimpleUniverse(canvas3D); 109 110 //Creating the root of the branch graph 111 BranchGroup scene = createSceneGraph(drawlist, axispresence); 112 113 //Creating scene bounds 114 BoundingSphere bounds = new BoundingSphere(new Point3d(), 1.0e6); 115 116 //Creating platform geometry 117 PlatformGeometry platformGeometry = new PlatformGeometry(); 118 119 //Adding background 120 Background background = new Background(backgroundcolor); 121 background.setApplicationBounds(bounds); 122 platformGeometry.addChild(background); 123 124 //Adding ambient light to platform geometry 125 Color3f ambientColor = new Color3f(0.4f, 0.4f, 0.4f); 126 AmbientLight ambientLight = new AmbientLight(ambientColor); 127 ambientLight.setInfluencingBounds(bounds); 128 platformGeometry.addChild(ambientLight); 129 130 //Adding directional light 1 to platform geometry 131 Color3f light1Color = new Color3f(0.7f, 0.7f, 0.7f); 132 Vector3f light1Direction = new Vector3f(-1.0f, -1.0f, -1.0f); 133 DirectionalLight light1 = new DirectionalLight(light1Color, light1Direction); 134 light1.setInfluencingBounds(bounds); 135 platformGeometry.addChild(light1); 136 137 //Adding directional light 2 to platform geometry 138 Color3f light2Color = new Color3f(0.5f, 0.5f, 0.5f); 139 Vector3f light2Direction = new Vector3f( 1.0f, -1.0f, -1.0f); 140 DirectionalLight light2 = new DirectionalLight(light2Color, light2Direction); 141 light2.setInfluencingBounds(bounds); 142 platformGeometry.addChild(light2); 143 144 //Adding directional light 3 to platform geometry 145 Color3f light3Color = new Color3f(0.4f, 0.4f, 0.4f); 146 Vector3f light3Direction = new Vector3f( 1.0f, 1.0f, -1.0f); 147 DirectionalLight light3 = new DirectionalLight(light3Color, light3Direction); 148 light3.setInfluencingBounds(bounds); 149 platformGeometry.addChild(light3); 150 151 //Adding directional light 4 to platform geometry 152 Color3f light4Color = new Color3f(0.3f, 0.3f, 0.3f); 153 Vector3f light4Direction = new Vector3f(-1.0f, 1.0f, -1.0f); 154 DirectionalLight light4 = new DirectionalLight(light4Color, light4Direction); 155 light4.setInfluencingBounds(bounds); 156 platformGeometry.addChild(light4); 157 158 //Seting platform geometry 159 simpleU.getViewingPlatform().setPlatformGeometry(platformGeometry); 160 161 //Behaviour for moving the View around a point of interest when the 162 //mouse is dragged with a mouse button pressed. 163 //Includes rotation, zoom, and translation actions. 164 OrbitBehavior orbit = new OrbitBehavior(canvas3D, OrbitBehavior.REVERSE_ALL 165 | OrbitBehavior.STOP_ZOOM ); 166 orbit.setSchedulingBounds(new BoundingSphere(new Point3d(), 1.0e6)); 167 orbit.setProportionalZoom(true); 168 orbit.setMinRadius(2.0); 169 //Transform3D T3D = new Transform3D(); 170 //T3D.setTranslation(new Vector3f( 0.0f, 0.0f, 6.0f)); 171 //orbit.setHomeTransform(T3D); 172 simpleU.getViewingPlatform().setViewPlatformBehavior(orbit); 173 174 //This will move the ViewPlatform back a bit so the objects in the scene can be viewed. 175 simpleU.getViewingPlatform().setNominalViewingTransform(); 176 177 //Setting the view model's back clip distance (model's front clip distance is 0.1 by default) 178 //simpleU.getViewer().getView().setFrontClipPolicy(View.VIRTUAL_EYE); 179 //simpleU.getViewer().getView().setBackClipPolicy(View.VIRTUAL_EYE); 180 simpleU.getViewer().getView().setBackClipDistance(100.0); 181 //simpleU.getViewingPlatform().getViewPlatform().setActivationRadius(1.0e6f); 182 183 //Used to add Nodes to the geometry side (as opposed to the view side) of the scene graph. 184 simpleU.addBranchGraph(scene); 185 186 //Setting frame title 187 setTitle("3d Projective MultiVector Viewer - Scene created on " + (new Date()).toString()); 188 189 //Setting Frame size 190 setSize(640,640); 191 } 192 193 /** 194 * Creates the specified defined scene. 195 * @param drawlist list of the Clifford elements (with relative color) to draw. 196 * @param axispresence specifies axis presence in the scene. 197 * @return the branch group of the scene graph 198 */ 199 private BranchGroup createSceneGraph(LinkedList drawlist, boolean axispresence) 200 { 201 //Creating the root of the branch graph 202 BranchGroup objRoot = new BranchGroup(); 203 204 // Create a Transformgroup to scale all objects so they appear in the scene. 205 Transform3D t3d = new Transform3D(); 206 //t3d.setScale(0.7); 207 TransformGroup objScale = new TransformGroup(); 208 //objScale.setTransform(t3d); 209 objRoot.addChild(objScale); 210 211 //Creating the transform group node and initializing it to the identity. 212 //Enabling the TRANSFORM_WRITE capability so that behavior code can modify it at runtime. 213 //Adding it to the root of the subgraph. 214 TransformGroup objTrans = new TransformGroup(); 215 objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); 216 objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); 217 objTrans.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND); 218 objTrans.setCapability(TransformGroup.ALLOW_CHILDREN_READ); 219 objTrans.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE); 220 objScale.addChild(objTrans); 221 222 //Adding axis 223 if(axispresence) 224 objTrans.addChild(new Axis()); 225 226 //Drawing 3D colored representation of all the NDElement in the list 227 Iterator it = drawlist.iterator(); 228 while(it.hasNext()) 229 addNDElementNode(objTrans, (NDElement) it.next()); 230 231 //Letting Java 3D perform optimizations on this scene graph and returning it 232 objRoot.compile(); 233 return objRoot; 234 } 235 236 /** 237 * Creates 3D representation of the NDElement element and attach it to the group. 238 * @param objTrans the group where all NDElement elements are added. 239 * @param element NDElement element to draw. 240 */ 241 private void addNDElementNode(TransformGroup objTrans, NDElement element) 242 { 243 //Temporary reference variables 244 float h1, h2, h3, x1, y1, z1, x2, y2, z2, x3, y3, z3; 245 CliffordBitSet cl1, cl2, cl3; 246 //Handling different generators number 247 int size = element.getGeneratorsSize(); 248 switch(size){ 249 case 0: 250 //Handling empty generator's list 251 return; 252 case 1: 253 //Adding point to the scene 254 cl1 = (CliffordBitSet) element.getGenerators().get(0); 255 //Handling elements with dimension outside E3 256 if(cl1.getMaxDimension() > 3) 257 return; 258 h1 = (float) (cl1.get("0")); 259 x1 = (float) (cl1.get("1") / h1); 260 y1 = (float) (cl1.get("2") / h1); 261 z1 = (float) (cl1.get("3") / h1); 262 objTrans.addChild(new PointShape(new Point3f(x1, y1, z1), element.getColor())); 263 break; 264 case 2: 265 //Adding segment to the scene 266 cl1 = (CliffordBitSet) element.getGenerators().get(0); 267 cl2 = (CliffordBitSet) element.getGenerators().get(1); 268 //Handling elements with dimension outside E3 269 if(cl1.getMaxDimension() > 3 || cl2.getMaxDimension() > 3) 270 return; 271 h1 = (float) (cl1.get("0")); 272 x1 = (float) (cl1.get("1") / h1); 273 y1 = (float) (cl1.get("2") / h1); 274 z1 = (float) (cl1.get("3") / h1); 275 h2 = (float) (cl2.get("0")); 276 x2 = (float) (cl2.get("1") / h2); 277 y2 = (float) (cl2.get("2") / h2); 278 z2 = (float) (cl2.get("3") / h2); 279 objTrans.addChild(new SegmentShape(new Point3f(x1, y1, z1), 280 new Point3f(x2, y2, z2), 281 element.getColor())); 282 break; 283 case 3: 284 //Adding triangle to the scene 285 cl1 = (CliffordBitSet) element.getGenerators().get(0); 286 cl2 = (CliffordBitSet) element.getGenerators().get(1); 287 cl3 = (CliffordBitSet) element.getGenerators().get(2); 288 //Handling elements with dimension outside E3 289 if(cl1.getMaxDimension() > 3 || cl2.getMaxDimension() > 3 || cl3.getMaxDimension() > 3) 290 return; 291 h1 = (float) (cl1.get("0")); 292 x1 = (float) (cl1.get("1") / h1); 293 y1 = (float) (cl1.get("2") / h1); 294 z1 = (float) (cl1.get("3") / h1); 295 h2 = (float) (cl2.get("0")); 296 x2 = (float) (cl2.get("1") / h2); 297 y2 = (float) (cl2.get("2") / h2); 298 z2 = (float) (cl2.get("3") / h2); 299 h3 = (float) (cl3.get("0")); 300 x3 = (float) (cl3.get("1") / h3); 301 y3 = (float) (cl3.get("2") / h3); 302 z3 = (float) (cl3.get("3") / h3); 303 objTrans.addChild(new TriangleShape(new Point3f(x1, y1, z1), 304 new Point3f(x2, y2, z2), 305 new Point3f(x3, y3, z3), 306 element.getColor())); 307 break; 308 default: 309 //Handling higher dimensionality generator's list 310 return; 311 } 312 } 313 }