project: tool started
[tu-mathvis-ws13:matsols-tu-mathvis-ws13.git] / src / student1522 / project / ProjectViewer.java
1 package student1522.project;
2
3 import java.awt.Color;
4 import java.awt.Component;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.awt.event.KeyAdapter;
8 import java.awt.event.KeyEvent;
9 import java.io.File;
10 import java.io.IOException;
11
12 import javax.swing.Box;
13 import javax.swing.JComboBox;
14 import javax.swing.JLabel;
15 import javax.swing.SwingConstants;
16
17 import charlesgunn.anim.gui.AnimationPanel;
18 import charlesgunn.anim.jreality.SceneGraphAnimator;
19 import charlesgunn.util.TextSlider;
20 import de.jreality.math.FactoredMatrix;
21 import de.jreality.math.Matrix;
22 import de.jreality.math.MatrixBuilder;
23 import de.jreality.scene.Appearance;
24 import de.jreality.scene.Geometry;
25 import de.jreality.scene.SceneGraphComponent;
26 import de.jreality.scene.Sphere;
27 import de.jreality.scene.Viewer;
28 import de.jreality.shader.DefaultGeometryShader;
29 import de.jreality.shader.DefaultLineShader;
30 //import de.jreality.jogl.shader.DefaultPointShader;
31 import de.jreality.shader.DefaultPointShader;
32 import de.jreality.shader.DefaultPolygonShader;
33 import de.jreality.shader.RenderingHintsShader;
34 import de.jreality.shader.ShaderUtility;
35 import de.jreality.tools.RotateTool;
36 import de.jreality.util.CameraUtility;
37 import de.jreality.util.Input;
38 import de.jreality.util.SceneGraphUtility;
39
40 /**
41  * This first assignment is intended as a practice for 
42  *              1. learning about the class {@link MatrixBuilder},
43  *              2. using the animation manager, and 
44  *          3. adding parameters to the inspector associated to the application.
45  * 
46  * The program constructs a square array of scene graph components each one containing a standard geometry,
47  * by default, a colored cube.  These cubes fits together to form a large flat box.  
48  * 
49  * The assignment is equipped with an animation file which is read at start-up.
50  * The user can invoke the animation manager by dragging the top window tab labeled "Animation" onto your desktop.
51  * An animation panel should then be displayed. Click on the button labeled "Play" to play the
52  * 
53  * The animation is controlled by the method {@link ProjectViewer#setValueAtTime(double)}.  It changes the individual
54  * transformations of the scene graph components making up the array, based on the animation time and a geometry parameter,
55  * both of which take values between 0 and 1.  The parameter {@link ProjectViewer#waveDelay} controls how these two parameters are
56  * combined into a single parameter.
57  * 
58  * Your assignment is to make a copy of this class in your package.
59  * Then, extend the class in the following directions:
60  *     1.  Change the function getGeometryParameter() so that the "level sets" are not diagonal lines but rather concentric circles
61  *     2.  Change the method setValueAtTime() to assign other transformations.  
62  *         To do this, you can define other parameters and use other methods on MatrixBuilder,
63  *         for example, methods that implement translations, or non-isotropic scaling
64  *     3.  Introduce a new parameter which has to do with your animation and insert it into the inspector (in {@link ProjectViewer#getInspector()},
65  *         following the patterns of the parameters which are already present there.
66  * @author Charles Gunn
67  *
68  */
69 public class ProjectViewer extends Assignment {
70         
71         private int sizeOfArray = 8;            // make a square array this size
72         int whichGeometry = 2;                          // default is to display cube instead of sphere.
73         int numberOfFaceColors = 2;
74         double maxRadius = 1.0;         // parameters for controlling the default animation
75         double waveDelay = .2;                          // how the wave propagates through the array of geometry
76         double hole = 4.0;                                      // size of the hole of the torus
77         
78         private int currRep = 1;
79         
80         PolyaTree[]  orbits = null;
81         private transient SceneGraphComponent worldSGC, 
82                 transformationSGCArray[][] = null,
83                 geomChildren[] = null,
84                 leafChild = new SceneGraphComponent("leaf child");
85         Color[] colourVector = {
86                         Color.RED,
87                         Color.BLUE,
88                         Color.GREEN,
89                         Color.GRAY,
90                         Color.PINK,
91                         Color.WHITE,
92                         Color.LIGHT_GRAY,
93                         Color.BLACK,
94                         
95                         Color.MAGENTA,
96                         Color.YELLOW,
97                         Color.ORANGE,
98                         Color.CYAN,
99                         Color.DARK_GRAY,
100                         Color.BLUE,
101                         Color.GRAY,
102                         Color.GREEN,
103                         Color.PINK,
104                         Color.WHITE,
105                         Color.LIGHT_GRAY,
106                         Color.BLACK,
107                         
108                         Color.RED,
109                         Color.BLUE,
110                         Color.GRAY,
111                         Color.GREEN,
112                         Color.PINK,
113                         Color.WHITE     };
114         Color[] testColourVector = {
115                         Color.GREEN,
116                         Color.GREEN,
117                         Color.GREEN,
118                         Color.GREEN,
119                         Color.GREEN,
120                         
121                         Color.GREEN,
122                         Color.GREEN,
123                         Color.GREEN,
124                         
125                         
126                 
127                         Color.RED,
128                         Color.RED,
129                         
130                         Color.RED,
131                         Color.RED,
132                         Color.RED,
133                         Color.RED,
134                         Color.RED,
135                         
136                         Color.RED,
137                         Color.RED,
138                         Color.RED,
139                         Color.RED,
140                         Color.RED,
141                         
142                         
143                         Color.BLUE,
144                         Color.BLUE,
145                         Color.BLUE,
146                         Color.BLUE,
147                         Color.BLUE,
148                         
149                         Color.BLUE,
150                                 };
151         
152         private transient Geometry[] geoms = {  
153                         new Sphere(), 
154                         OurPrimitives.ourBoxFactory(colourVector).getIndexedFaceSet(),
155                         OurPrimitives.ourXAxis().getIndexedLineSet()
156                         };
157         
158         
159         @Override
160         public SceneGraphComponent getContent() {
161                 // TODO: orbits und elemente aus orbits trennen!
162                 worldSGC = SceneGraphUtility.createFullSceneGraphComponent("Assignment 1");
163                 Appearance ap = worldSGC.getAppearance();
164                 setupAppearance(ap);
165                 
166                 // create axis
167                 SceneGraphComponent xAxis = SceneGraphUtility.createFullSceneGraphComponent("x-axis");
168                 Geometry xAxisGeom = OurPrimitives.ourXAxis( ).getIndexedLineSet();
169                 xAxis.setGeometry( xAxisGeom );
170                 
171                 SceneGraphComponent yAxis = SceneGraphUtility.createFullSceneGraphComponent("y-axis");
172                 Geometry yAxisGeom = OurPrimitives.ourYAxis( ).getIndexedLineSet();
173                 yAxis.setGeometry( yAxisGeom );
174                 
175                 SceneGraphComponent zAxis = SceneGraphUtility.createFullSceneGraphComponent("z-axis");
176                 Geometry zAxisGeom = OurPrimitives.ourZAxis( ).getIndexedLineSet();
177                 zAxis.setGeometry( zAxisGeom );
178                 
179
180                 PolyaMagic magic = new PolyaMagic( whichGeometry, new int[]{1,1,numberOfFaceColors}, true);
181                 this.orbits = new PolyaTree[ magic.orbits.size() ];
182                 this.orbits =  magic.orbits.toArray( orbits );
183                 System.out.println("orbits " + orbits.length);
184                 transformationSGCArray = new SceneGraphComponent[ orbits.length ][];
185                 
186 //              geomChildren = new SceneGraphComponent[ orbits.length ];
187 //              
188 //              // do stuff for reps schleifenbeginn
189 //              
190 //              PolyaTreeNode rep = orbits[ currRep ].nodes.getFirst();
191 //              
192 //              Color[] colors = new Color[ rep.colouring.perm.length ];
193 //              for (int i = 0; i < rep.colouring.perm.length; i++) {
194 //                      colors[ i ] = colourVector[ rep.colouring.perm[ i ] ];
195 //              }
196 //              Geometry repGeom = null;
197 //              switch( whichGeometry ){
198 //              case 1: // math object = tetrahedron
199 //                      repGeom = OurPrimitives.ourTetrahedronFactory( colors ).getIndexedFaceSet();
200 //                      break;
201 //              case 2: // math object = cube
202 //                      repGeom = OurPrimitives.ourBoxFactory( colors ).getIndexedFaceSet();
203 //                      break;
204 //              case 3: // math object = octahedron
205 //                      break;
206 //              case 4: // math object = dodecahedron
207 //                      break;
208 //              }
209 //              geomChildren[ currRep ] = new SceneGraphComponent("representative " + currRep);
210 //              geomChildren[ currRep ].setGeometry( repGeom );
211 //              //geomChildren[ 0 ].addChild( leafChild );
212 //              
213 //              
214 //              PolyaTreeIterator iter = new PolyaTreeIterator( orbits[ currRep ] );
215 ////            iter.next();
216 //              for (int k = 0; k < orbits[ currRep ].getSize(); k++) {
217 //                      PolyaTreeNode currNode = iter.currNode;
218 //                      System.out.println("currNode " + currNode);
219 //                      int[] colouring = currNode.colouring.perm;
220 //                      colors = new Color[ colouring.length ];
221 //                      for (int i = 0; i < colouring.length; i++) {
222 //                              colors[ i ] = colourVector[ colouring[ i ] ];
223 //                      }
224 //                      
225 //                      Geometry currGeom = null;
226 //                      switch( whichGeometry ){
227 //                      case 1: // math object = tetrahedron
228 //                              currGeom = OurPrimitives.ourTetrahedronFactory( colors ).getIndexedFaceSet();
229 //                              break;
230 //                      case 2: // math object = cube
231 //                              currGeom = OurPrimitives.ourBoxFactory( colors ).getIndexedFaceSet();
232 //                              break;
233 //                      case 3: // math object = octahedron
234 //                              break;
235 //                      case 4: // math object = dodecahedron
236 //                              break;
237 //                      }
238 //                      SceneGraphComponent currChild = new SceneGraphComponent("node " + k);
239 //                      currChild.setGeometry( currGeom );
240 //                      
241 //                      SceneGraphComponent translated = SceneGraphUtility.createFullSceneGraphComponent("tlated"+k);
242 //                      SceneGraphComponent child = SceneGraphUtility.createFullSceneGraphComponent("child"+k);
243 ////                    child.addChild(geomChildren[ currRep ]);
244 //                      child.addChild( currChild );
245 //                      translated.addChild(child);
246 //                      MatrixBuilder.euclidean().translate(4*k, 0, 0).assignTo(translated);
247 //                      worldSGC.addChild(translated);
248 //                      iter.next();
249 //              }
250                 
251                 int numberOfOrbits = orbits.length;
252                 for (int idxOfOrbit = 0; idxOfOrbit < orbits.length; idxOfOrbit++) {
253                                 
254                         
255 //                      PolyaTreeNode rep = orbits[ idxOfOrbit ].nodes.getFirst();
256 //                      
257 //                      Color[] colors = new Color[ rep.colouring.perm.length ];
258 //                      for (int i = 0; i < rep.colouring.perm.length; i++) {
259 //                              colors[ i ] = colourVector[ rep.colouring.perm[ i ] ];
260 //                      }
261                         transformationSGCArray[ idxOfOrbit ] = new SceneGraphComponent[ orbits[ idxOfOrbit ].getSize() ];
262                         
263                         PolyaTreeIterator iter = new PolyaTreeIterator( orbits[ idxOfOrbit ] );
264                         iter.reset();
265                         // generate geometry
266                         int[] colouring = iter.currNode.colouring.perm;
267                         Color[] colors = new Color[ colouring.length ];
268                         for (int i = 0; i < colouring.length; i++) {
269                                 colors[ i ] = colourVector[ colouring[ i ] ];
270                         }
271                         Geometry rootGeom = null;
272                         switch( whichGeometry ){
273                         case 1: // math object = tetrahedron
274                                 rootGeom = OurPrimitives.ourTetrahedronFactory( colors ).getIndexedFaceSet();
275                                 break;
276                         case 2: // math object = cube
277                                 rootGeom = OurPrimitives.ourBoxFactory( colors ).getIndexedFaceSet();
278                                 break;
279                         case 3: // math object = octahedron
280                                 break;
281                         case 4: // math object = dodecahedron
282                                 break;
283                         }
284                         SceneGraphComponent currChild = new SceneGraphComponent("geometry " + idxOfOrbit);
285                         currChild.setGeometry( rootGeom );
286                         
287                         int sizeOfOrbit = orbits[ idxOfOrbit ].getSize();
288                         int rootOfSize = (int) Math.sqrt( sizeOfOrbit );
289                         for (int k = 0; k < sizeOfOrbit; k++) {
290                                 SceneGraphComponent translated = SceneGraphUtility.createFullSceneGraphComponent("tlated"+k);
291                                 SceneGraphComponent child = SceneGraphUtility.createFullSceneGraphComponent("transformation"+k);
292                                 transformationSGCArray[ idxOfOrbit ][ k ] = child;
293                                 
294                                 int xCoord = k % rootOfSize;
295                                 int yCoord = k / rootOfSize;
296                                 
297                                 if ( k > 0){
298                                         child.setVisible( false );
299 //                                      MatrixBuilder.euclidean().translate(4*xCoord, 4 * yCoord, -4 * (idxOfOrbit)).assignTo(translated);
300                                 }
301                                 else{
302                                         xCoord = idxOfOrbit % (int) Math.sqrt( numberOfOrbits );
303                                         yCoord = idxOfOrbit / (int) Math.sqrt( numberOfOrbits );
304                                         child.addTool( new ShowOrbitTool() );
305                                 }
306                                 MatrixBuilder.euclidean().translate(4*xCoord, 4 * yCoord, 0).assignTo(translated);
307                                 
308                                 
309                                 
310                                 child.addChild( currChild );
311                                 child.addChild( xAxis );
312                                 child.addChild( yAxis );
313                                 child.addChild( zAxis );
314                                 translated.addChild(child);
315                                 worldSGC.addChild(translated);
316                                 iter.next();
317                         }
318                 }
319                 
320                 // have to make sure we don't let the scene graph animator set key frames on
321                 // our scene graph, since we animate it by hand in the method setValueAtTime() below.
322                 worldSGC.getAppearance().setAttribute(SceneGraphAnimator.ANIMATED, false);
323                 return worldSGC;
324         }
325         
326
327
328
329         
330 private void setupAppearance(Appearance ap) {
331         DefaultGeometryShader dgs;
332         DefaultLineShader dls;
333         DefaultPointShader dpts;
334         RenderingHintsShader rhs;
335         DefaultPolygonShader dps;
336         dgs = ShaderUtility.createDefaultGeometryShader(ap, true);
337         dgs.setShowFaces(true);
338         dgs.setShowLines(true);
339         dgs.setShowPoints(true);
340         dls = (DefaultLineShader) dgs.createLineShader("default");
341         dls.setTubeRadius(.03);
342         dpts = (DefaultPointShader) dgs.createPointShader("default");
343         dpts.setPointRadius(.05);
344         dps = (DefaultPolygonShader) dgs.createPolygonShader("default");
345         dps.setSmoothShading(false); //allows flexible face colors
346 //      dps.setTransparency(.5);
347         rhs = ShaderUtility.createDefaultRenderingHintsShader(ap, true);
348 //      rhs.setTransparencyEnabled(true);
349         rhs.setOpaqueTubesAndSpheres(true);
350 }
351
352
353
354
355
356 //      /**
357 //       * The following method is the basic method for the animation system.  
358 //       * Here we create a wave of motion moving through the array of geometries
359 //       */
360 //      @Override
361 //      public void setValueAtTime(double time) {
362 //              // TODO Auto-generated method stub
363 //              super.setValueAtTime(time);
364 //              for (int i = 0; i<sizeOfArray; ++i)     {
365 //                      for (int j = 0; j<sizeOfArray; ++j)     {
366 //                              // diagonal varies between 0 and 1
367 //                              double geometryParameter = getGeometryParameter(i, j);
368 //                              // waveParameter varies between 0 and 1; input values less than 0 and greater than 1-waveDelay are clipped
369 //                              double waveParameter = AnimationUtility.linearInterpolation(time-waveDelay*geometryParameter, 0, 1-waveDelay, 0, 1);
370 //                              // calculate the radius from the waveParameter
371 //                              double radius = scalingFactor(waveParameter);
372 //                              // change the transformation associated to this scene graph component based on the
373 //                              // derived parameters.  
374 //                              //         radius determines the scaling, 
375 //                              //         waveParameter determines a rotation around the y-axis.
376 //                              double angle = waveParameter*2.0*Math.PI;
377 //                              //MatrixBuilder.euclidean().rotateY(angle).scale(radius, radius, radius).assignTo(childArray[i][j]);
378 //                              MatrixBuilder.euclidean().translate(Math.sin(angle),Math.sin(2*angle),Math.sin(3*angle)).rotate(angle,Math.sin(angle),Math.sin(2*angle),Math.sin(3*angle)).scale(radius,radius,radius).assignTo(childArray[i][j]);
379 //                      }
380 //              }
381 //      }
382         /**
383          * The following method is the basic method for the animation system.  
384          * Here we create a wave of motion moving through the array of geometries
385          */
386         @Override
387         public void setValueAtTime(double time) {
388                 super.setValueAtTime(time);
389                 int i = currRep;
390                 PolyaTreeIterator iter = new PolyaTreeIterator( orbits[ i ] );
391                 for (int j = 0; j< transformationSGCArray[i].length; ++j)       {
392                         PolyaTreeNode currNode = iter.currNode;
393                         PolyaTreeNode iterToRoot = currNode;
394                         // calc level( currNode )
395                         int levelInTree = 0;
396                         while ( iterToRoot.parent != null ){
397                                 levelInTree++;
398                                 iterToRoot = iterToRoot.parent;
399                         }
400
401
402                         // calc order of generators starting from currNode to root
403                         int[] idxOfGenerators = new int[ levelInTree ]; 
404                         iterToRoot = currNode;
405                         int idx = 0;
406                         while ( iterToRoot.parent != null ){
407                                 idxOfGenerators[ idx ] = iterToRoot.idxOfGenerator;
408                                 idx++;
409                                 iterToRoot = iterToRoot.parent;
410                         }
411
412
413
414                         if ( levelInTree == 0 ){
415                                 // do nothing
416                         }
417                         else{
418                                 Matrix rotation = null;
419                                 if ( whichGeometry ==1){
420 //                              case 1: // math object = tetrahedron
421                                         double[] axis3 = {1,1,1,1};
422                                         double[] axis4 = {0,1,0,1}; 
423                                         double[] plane = {0,1,0,1};
424
425                                         Matrix rotateOrder2Y = calcRotateOrder4( -Math.PI , axis4 );
426                                         Matrix rotateOrder3Diag = calcRotateOrder3( -2*Math.PI / 3., axis3 );
427                                         Matrix reflectionOrder2XZ = calcReflectionOrder2( plane );
428
429                                         rotation = MatrixBuilder.euclidean().getMatrix();
430
431                                         int numberOfCompleteTrafos = (int) (levelInTree * time);
432                                         double rest = (levelInTree * time)%1;
433                                         for (int k = 0; k < numberOfCompleteTrafos; k++) {
434                                                 if( idxOfGenerators[ k ] == 0 ){
435                                                         rotation = Matrix.times( rotation ,rotateOrder3Diag);
436                                                 }
437                                                 if( idxOfGenerators[ k ] == 1 ){
438                                                         rotation = Matrix.times( rotation, rotateOrder2Y );
439                                                 }
440                                                 if( idxOfGenerators[ k ] == 2 ){
441                                                         rotation = Matrix.times( rotation, reflectionOrder2XZ );
442                                                 }
443                                         }
444                                         iterToRoot = currNode;
445                                         for (int blu =0; blu<numberOfCompleteTrafos; blu++){
446                                                 iterToRoot=iterToRoot.parent;
447                                         }
448                                         if( iterToRoot.idxOfGenerator == 0 ){
449                                                 double angle = -2*Math.PI / 3. * rest; 
450                                                 rotation = Matrix.times( rotation, calcRotateOrder3( angle, axis3 ) );
451                                         }
452                                         if( iterToRoot.idxOfGenerator == 1 ){
453                                                 double angle = -(Math.PI ) * rest; 
454                                                 rotation = Matrix.times( rotation ,calcRotateOrder4( angle, axis4 ) ); 
455                                         }
456                                         if( iterToRoot.idxOfGenerator == 2 ){
457                                                 double radius =  -2*(rest-0.5) ;
458                                                 rotation = Matrix.times( rotation ,MatrixBuilder.euclidean().scale( 1, radius, 1 ).getMatrix() ); 
459                                         }
460 //                                      break;
461                                 }
462                                 else{
463 //                              case 2: // math object = cube
464                                         double[] axis3 = {1,1,1,1};
465                                         double[] axis4 = {0,1,0,1}; 
466                                         double[] plane = {0,1,0,1};
467
468                                         Matrix rotateOrder4Y = calcRotateOrder4( -Math.PI / 2., axis4 );
469                                         Matrix rotateOrder3Diag = calcRotateOrder3( -2*Math.PI / 3., axis3 );
470                                         Matrix reflectionOrder2XZ = calcReflectionOrder2( plane );
471
472                                         rotation = MatrixBuilder.euclidean().getMatrix();
473
474                                         int numberOfCompleteTrafos = (int) (levelInTree * time);
475                                         double rest = (levelInTree * time)%1;
476                                         for (int k = 0; k < numberOfCompleteTrafos; k++) {
477                                                 if( idxOfGenerators[ k ] == 0 ){
478                                                         rotation = Matrix.times( rotation ,rotateOrder3Diag);
479                                                 }
480                                                 if( idxOfGenerators[ k ] == 1 ){
481                                                         rotation = Matrix.times( rotation, rotateOrder4Y );
482                                                 }
483                                                 if( idxOfGenerators[ k ] == 2 ){
484                                                         rotation = Matrix.times( rotation, reflectionOrder2XZ );
485                                                 }
486                                         }
487                                         iterToRoot = currNode;
488                                         for (int blu =0; blu<numberOfCompleteTrafos; blu++){
489                                                 iterToRoot=iterToRoot.parent;
490                                         }
491                                         if( iterToRoot.idxOfGenerator == 0 ){
492                                                 double angle = -2*Math.PI / 3. * rest; 
493                                                 rotation = Matrix.times( rotation, calcRotateOrder3( angle, axis3 ) );
494                                         }
495                                         if( iterToRoot.idxOfGenerator == 1 ){
496                                                 double angle = -(Math.PI / 2.) * rest; 
497                                                 rotation = Matrix.times( rotation ,calcRotateOrder4( angle, axis4 ) ); 
498                                         }
499                                         if( iterToRoot.idxOfGenerator == 2 ){
500                                                 double radius =  -2*(rest-0.5) ;
501                                                 rotation = Matrix.times( rotation ,MatrixBuilder.euclidean().scale( 1, radius, 1 ).getMatrix() ); 
502                                         }
503                                 }
504 //                                      break;
505 //                              case 3: // math object = octahedron
506 //                                      break;
507 //                              case 4: // math object = dodecahedron
508 //                                      break;
509 //                              }
510                                 
511                                 rotation.assignTo( transformationSGCArray[i][j]);
512
513                         }
514                         iter.next();
515                 }
516         }
517 private Matrix calcRotateOrder3(double angle, double[] axis ) {
518         return MatrixBuilder.euclidean().rotate(angle, axis).getMatrix();
519 }
520
521
522
523 private Matrix calcRotateOrder4(double angle, double[] axis ) {
524         return MatrixBuilder.euclidean().rotate(angle, axis ).getMatrix();
525 }
526
527 private Matrix calcReflectionOrder2(double[] plane ) {
528         return MatrixBuilder.euclidean().scale( 1,-1,1).getMatrix();
529 }
530
531
532
533 //      }
534         
535         
536 //      PolyaTreeNode currNode = iter.currNode;
537 //      PolyaTreeNode iterToRoot = currNode;
538 //      
539 //      Matrix rotateOrder4Z = MatrixBuilder.euclidean().rotate(-Math.PI / 2., new double[]{0,0,1,1}).getMatrix();
540 //      Matrix rotateOrder3Diag = MatrixBuilder.euclidean().rotate(-2*Math.PI / 3., new double[]{1,1,1,1}).getMatrix();
541 //      Matrix rotation = MatrixBuilder.euclidean().getMatrix();
542 //      while ( iterToRoot.parent != null ){
543 //              if( iterToRoot.idxOfGenerator == 1 ){
544 //                      rotation = Matrix.times( rotation, rotateOrder4Z );
545 //              }
546 //              if( iterToRoot.idxOfGenerator == 0 ){
547 //                      rotation = Matrix.times( rotation ,rotateOrder3Diag );
548 //              }
549 //              System.out.println("idx " + iterToRoot.idxOfGenerator);
550 //              iterToRoot = iterToRoot.parent;
551 //              
552 //      }
553 //      rotation.assignTo( currChild );
554 //      System.out.println();
555
556         
557         /**
558          * This is the primary method which causes everything else to happen.  It's called 
559          * from the main() method below.
560          */
561         @Override
562         public void display() {
563                 // TODO Auto-generated method stub
564                 super.display();
565                 Viewer viewer = jrviewer.getViewer();
566                 CameraUtility.encompass(viewer);
567                 addKeyListener(viewer);
568                 // read in the animation file
569                 try {
570                         animationPlugin.getAnimationPanel().read(new Input(this.getClass().getResource("assg1-anim.xml")));
571                 } catch (IOException e) {
572                         // TODO Auto-generated catch block
573                         e.printStackTrace();
574                 }
575                 animationPlugin.getAnimationPanel();
576                 AnimationPanel.setResourceDir("src/template");
577         }
578         
579         /**
580          * This is the file where the application properties are stored.
581          * To make sure this is updated each time you run the application,
582          * use the "Quit" menu item on the "File" menu to exit.
583          */
584         @Override
585         public File getPropertyFile() {
586                 return new File("src/template/assignment1.xml");
587         }
588
589         /**
590          * Provided as an example of how to provide a key listener to an application
591          * @param viewer
592          */
593         private void addKeyListener(Viewer viewer) {
594                 Component comp = ((Component) viewer.getViewingComponent());
595                 comp.addKeyListener(new KeyAdapter() {
596                                 public void keyPressed(KeyEvent e)      { 
597                                         switch(e.getKeyCode())  {
598                                                 
599                                         case KeyEvent.VK_H:
600                                                 System.err.println("Key listener: \n\t1: toggle display of sphere");
601                                                 break;
602                 
603                                         case KeyEvent.VK_1:
604                                                 whichGeometry = (whichGeometry + 1)%geoms.length;
605                                                 leafChild.setGeometry(geoms[whichGeometry]);                                            
606                                                 break;
607                 
608                                 }
609                                 }
610                         });
611         }
612         
613         /**
614          * Currently don't have a documentation file
615          */
616         @Override
617         public String getDocumentationFile() {
618                 // TODO Auto-generated method stub
619                 return  "Assignment1.html";
620         }
621
622
623         @Override
624         public Component getInspector() {
625                 // TODO Auto-generated method stub
626                 Box vbox = Box.createVerticalBox();
627                 
628                 Box hbox = Box.createHorizontalBox();
629                 inspector.add(hbox);
630                 hbox.add(Box.createHorizontalGlue());
631                 JLabel label = new JLabel("Math Object:");
632                 hbox.add(label);
633                 hbox.add(Box.createHorizontalGlue());
634
635                 // Allow the use to choose a triangle group
636                 String[] names = {      "Tetrahedron",
637                                                         "Cube"};
638                 
639                 JComboBox styleCB = new JComboBox(names);
640                 styleCB.setSelectedIndex( whichGeometry - 1 );
641                 styleCB.addActionListener(new ActionListener() {
642
643                         @Override
644                         public void actionPerformed(ActionEvent arg0) {
645                                 currRep = 1;
646                                 
647                                 whichGeometry = ((JComboBox) arg0.getSource())
648                                                 .getSelectedIndex() + 1;
649                                 contentPlugin.setContent(getContent());
650                         }
651
652
653                 });
654                 hbox.add(styleCB);
655                 hbox.add(Box.createHorizontalGlue());
656                 vbox.add(hbox);
657                 
658                                 
659                 final TextSlider sizeSlider = new TextSlider.Integer("orbit", SwingConstants.HORIZONTAL, 1, Integer.MAX_VALUE, 1);
660                 sizeSlider.addActionListener(new ActionListener() {
661                         
662                         @Override
663                         public void actionPerformed(ActionEvent e) {
664                                 if (orbits != null){
665                                         currRep = ((TextSlider)e.getSource()).getValue().intValue()-1;
666                                         sizeSlider.setMax( orbits.length );
667                                 }
668                                 contentPlugin.setContent(getContent());
669                         }
670                 });
671                 vbox.add(sizeSlider);
672                 
673                 TextSlider faceColorsSlider = new TextSlider.Integer("# face colours", SwingConstants.HORIZONTAL, 1, 6, numberOfFaceColors);
674                 faceColorsSlider.addActionListener(new ActionListener() {
675                         
676                         @Override
677                         public void actionPerformed(ActionEvent e) {
678                                 numberOfFaceColors = ((TextSlider)e.getSource()).getValue().intValue();
679                                 contentPlugin.setContent(getContent());
680                         }
681                         
682                 });
683                 vbox.add(faceColorsSlider);
684                 TextSlider maxRSlider = new TextSlider.Double("max radius", SwingConstants.HORIZONTAL,0.05, 1.0, maxRadius);
685                 maxRSlider.addActionListener(new ActionListener() {
686                         
687                         @Override
688                         public void actionPerformed(ActionEvent e) {
689                                 maxRadius = ((TextSlider)e.getSource()).getValue().doubleValue();
690                         }
691                 });
692                 vbox.add(maxRSlider);
693                 TextSlider wavePSlider = new TextSlider.Double("wave delay", SwingConstants.HORIZONTAL,0.0,.99, waveDelay);
694                 wavePSlider.addActionListener(new ActionListener() {
695                         
696                         @Override
697                         public void actionPerformed(ActionEvent e) {
698                                 waveDelay = ((TextSlider)e.getSource()).getValue().doubleValue();
699                         }
700                 });
701                 vbox.add(wavePSlider);
702                 return vbox;
703         }
704
705         public static void main(String[] args)          {
706                 ProjectViewer theProgram = new ProjectViewer();
707                 theProgram.display();
708         }
709         
710
711
712 }