1 package org.textensor.vis;
2
3
4 import java.awt.BorderLayout;
5 import java.awt.Dimension;
6 import java.awt.FlowLayout;
7 import java.awt.GraphicsConfiguration;
8 import java.awt.GraphicsEnvironment;
9 import java.awt.GridLayout;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.awt.event.InputEvent;
13 import java.awt.event.MouseEvent;
14 import java.awt.event.MouseListener;
15 import java.awt.event.MouseMotionListener;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.HashSet;
19
20 import javax.media.j3d.AmbientLight;
21 import javax.media.j3d.BoundingSphere;
22 import javax.media.j3d.BranchGroup;
23 import javax.media.j3d.Canvas3D;
24 import javax.media.j3d.DirectionalLight;
25 import javax.media.j3d.GraphicsConfigTemplate3D;
26 import javax.media.j3d.Light;
27 import javax.media.j3d.Locale;
28 import javax.media.j3d.Node;
29 import javax.media.j3d.PhysicalBody;
30 import javax.media.j3d.PhysicalEnvironment;
31 import javax.media.j3d.PickConeRay;
32 import javax.media.j3d.PickCylinderRay;
33 import javax.media.j3d.PickInfo;
34 import javax.media.j3d.PickRay;
35 import javax.media.j3d.PickShape;
36 import javax.media.j3d.RenderingAttributes;
37 import javax.media.j3d.Shape3D;
38 import javax.media.j3d.Transform3D;
39 import javax.media.j3d.TransformGroup;
40 import javax.media.j3d.View;
41 import javax.media.j3d.ViewPlatform;
42 import javax.media.j3d.VirtualUniverse;
43 import javax.swing.ButtonGroup;
44 import javax.swing.JButton;
45 import javax.swing.JCheckBox;
46 import javax.swing.JPanel;
47 import javax.swing.JRadioButton;
48 import javax.swing.JSlider;
49 import javax.swing.event.ChangeEvent;
50 import javax.swing.event.ChangeListener;
51 import javax.vecmath.AxisAngle4d;
52 import javax.vecmath.Color3f;
53 import javax.vecmath.Matrix4d;
54 import javax.vecmath.Point3d;
55 import javax.vecmath.Vector3d;
56 import javax.vecmath.Vector3f;
57
58 import org.textensor.report.E;
59
60
61 import com.sun.j3d.utils.geometry.Sphere;
62
63
64
65 public class SceneGraphViewer implements ActionListener, MouseListener, MouseMotionListener, ChangeListener {
66
67 JPanel panel;
68
69 Canvas3D canvas;
70
71 VirtualUniverse universe;
72 Locale locale;
73 View view;
74
75 int xdown;
76 int ydown;
77 boolean dragging = false;
78
79 public final static int PAN = 0;
80 public final static int ZOOM = 1;
81 public final static int ROLL = 2;
82 public final static int HIDE = 3;
83 int mode = PAN;
84
85
86 public final static int NONE = 0;
87 public final static int LEFT = 1;
88 public final static int RIGHT = 2;
89 int button = NONE;
90
91
92 Transform3D rootTransform;
93 TransformGroup rootTransformGroup;
94
95 TransformGroup decTransformGroup;
96
97 PickInfo[] lastPickInfos;
98
99 BranchGroup baseGroup;
100 ArrayList<Shape3D> shapes;
101
102
103 HashMap<String, SceneItem> sceneItemHM = new HashMap<String, SceneItem>();
104
105
106 float scale = 1.0f;
107 Transform3D downTransform;
108 Point3d wcdown;
109
110 Transform3D fcTrans = new Transform3D();
111 Transform3D tcTrans = new Transform3D();
112
113 Transform3D fwTrans = new Transform3D();
114 Transform3D twTrans = new Transform3D();
115
116
117 Transform3D fwrcTrans = new Transform3D();
118 Transform3D twrcTrans = new Transform3D();
119
120 float downscale = 0.f;
121
122
123 float brightness = 0.7f;
124
125 BranchGroup lights;
126
127 DirectionalLight directionalLight;
128 AmbientLight ambientLight;
129
130
131 int nshowing = 0;
132
133
134 public SceneGraphViewer() {
135
136 GraphicsConfiguration config = getPreferredConfiguration();
137 canvas = new Canvas3D(config);
138 canvas.setPreferredSize(new Dimension(800, 600));
139 canvas.setFocusable(true);
140
141
142 panel = new JPanel();
143
144 panel.setLayout(new BorderLayout());
145
146 JPanel jp = new JPanel();
147 jp.setLayout(new FlowLayout(FlowLayout.CENTER, 6, 0));
148
149 JRadioButton bpan = new JRadioButton("pan", true);
150 bpan.setActionCommand("pan");
151 bpan.addActionListener(this);
152
153 JRadioButton bzoom = new JRadioButton("zoom");
154 bzoom.setActionCommand("zoom");
155 bzoom.addActionListener(this);
156
157 JRadioButton broll = new JRadioButton("roll");
158 broll.setActionCommand("roll");
159 broll.addActionListener(this);
160
161 JRadioButton bhide = new JRadioButton("hide");
162 bhide.setActionCommand("hide");
163 bhide.addActionListener(this);
164
165
166
167 ButtonGroup g = new ButtonGroup();
168 g.add(bpan);
169 g.add(bzoom);
170 g.add(broll);
171 g.add(bhide);
172
173 jp.add(bpan);
174 jp.add(bzoom);
175 jp.add(broll);
176 jp.add(bhide);
177
178 JButton jbsa = new JButton("Show all");
179 jbsa.setActionCommand("showall");
180 jbsa.addActionListener(this);
181 jp.add(jbsa);
182
183
184 JCheckBox jcb = new JCheckBox("Smooth", false);
185 jcb.addActionListener(this);
186 jcb.setActionCommand("antialias");
187 jp.add(jcb);
188
189 JButton jbb = new JButton("+");
190 jbb.setActionCommand("brighter");
191 jbb.addActionListener(this);
192 jp.add(jbb);
193
194 JButton jbd = new JButton("-");
195 jbd.setActionCommand("darker");
196 jbd.addActionListener(this);
197 jp.add(jbd);
198
199
200 JPanel ptop = new JPanel();
201 ptop.setLayout(new GridLayout(2, 1, 2, 2));
202 ptop.add(jp);
203
204
205 JSlider slider = new JSlider(0, 1000, 1000);
206 slider.addChangeListener(this);
207 ptop.add(slider);
208
209
210 panel.add(ptop, BorderLayout.NORTH);
211
212
213
214 panel.add(canvas, BorderLayout.CENTER);
215
216
217
218 universe = new VirtualUniverse();
219 locale = new Locale(universe);
220
221
222 ViewPlatform platform = new ViewPlatform();
223 TransformGroup tg = new TransformGroup();
224 Transform3D wk = new Transform3D();
225 wk.setTranslation(new Vector3d(0., 0., 100.));
226 tg.setTransform(wk);
227 tg.addChild(platform);
228 BranchGroup platformBG = new BranchGroup();
229 platformBG.addChild(tg);
230
231 locale.addBranchGraph(platformBG);
232
233
234 view = new View();
235 view.setPhysicalBody(new PhysicalBody());
236 view.setPhysicalEnvironment(new PhysicalEnvironment());
237
238
239 view.setProjectionPolicy(View.PARALLEL_PROJECTION);
240 view.setFrontClipDistance(1.);
241 view.setBackClipDistance(200.);
242
243 view.addCanvas3D(canvas);
244 view.attachViewPlatform(platform);
245
246
247 lights = createLightGraph(brightness);
248
249
250 locale.addBranchGraph(lights);
251
252 BranchGroup scene = createDummySceneGraph();
253
254 setSceneGraph(scene, null);
255
256 canvas.addMouseListener(this);
257 canvas.addMouseMotionListener(this);
258 }
259
260
261
262 public void deltaLights(double d) {
263 double br = brightness;
264 br += d;
265 if (br > 1.) {
266 br = 1.;
267 }
268 if (br < 0.) {
269 br = 0.;
270 }
271 setBrightness(br);
272 }
273
274
275
276 public void setBrightness(double br) {
277 if (Math.abs(br - brightness) > 0.01) {
278 applyBrightness(br);
279 }
280 }
281
282 private void applyBrightness(double br) {
283 brightness = (float)br;
284 Color3f c3 = new Color3f(brightness, brightness, brightness);
285 ambientLight.setColor(c3);
286 directionalLight.setColor(c3);
287 }
288
289
290
291 public JPanel getPanel() {
292 return panel;
293 }
294
295
296
297 public void setSceneGraph(BranchGroup bg, ArrayList<Shape3D> sha) {
298 if (baseGroup != null) {
299 locale.removeBranchGraph(baseGroup);
300 }
301 shapes = sha;
302 if (shapes != null) {
303 nshowing = shapes.size();
304 } else {
305 nshowing = 0;
306 }
307
308 if (rootTransform == null) {
309 rootTransform= new Transform3D();
310 rootTransform.setTranslation(new Vector3d(0., 0., 0.));
311 rootTransform.setScale(0.1f);
312 }
313
314 rootTransformGroup = new TransformGroup();
315 rootTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
316 rootTransformGroup.setTransform(rootTransform);
317 rootTransformGroup.addChild(bg);
318
319 baseGroup = new BranchGroup();
320 baseGroup.addChild(rootTransformGroup);
321 baseGroup.setCapability(BranchGroup.ALLOW_DETACH);
322 baseGroup.compile();
323 locale.addBranchGraph(baseGroup);
324
325
326 if (decTransformGroup == null) {
327 decTransformGroup = new TransformGroup();
328 decTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
329 decTransformGroup.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
330 decTransformGroup.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
331 decTransformGroup.setTransform(rootTransform);
332 BranchGroup decGroup = new BranchGroup();
333 decGroup.addChild(decTransformGroup);
334 locale.addBranchGraph(decGroup);
335 }
336 }
337
338
339 private BranchGroup createDummySceneGraph() {
340 BranchGroup ret = new BranchGroup();
341
342 for (int i = 0; i < 50; i++) {
343 TransformGroup trans = new TransformGroup();
344 Transform3D pos = new Transform3D();
345 pos.setTranslation(new Vector3f((float)(-1 + 2 * Math.random()), (float)(-1 + 2 * Math.random()),
346 (float)(-0.1 + 0.2 * Math.random())));
347 trans.setTransform(pos);
348 ret.addChild(trans);
349
350 Sphere sp = new Sphere((float)(0.01 + 0.1 * Math.random()), Sphere.GENERATE_NORMALS, 50);
351 trans.addChild(sp);
352 }
353
354 return ret;
355 }
356
357
358
359
360
361
362 private BranchGroup createLightGraph(double br) {
363 float fb = (float)br;
364 BranchGroup group = new BranchGroup();
365 BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
366
367
368 Color3f light1Color = new Color3f(fb, fb, fb);
369 Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -2.0f);
370 directionalLight = new DirectionalLight(light1Color, light1Direction);
371 directionalLight.setInfluencingBounds(bounds);
372 directionalLight.setCapability(Light.ALLOW_COLOR_WRITE);
373 group.addChild(directionalLight);
374
375
376
377
378
379
380
381
382
383
384 Color3f ambientColor = new Color3f(fb, fb, fb);
385 ambientLight = new AmbientLight(ambientColor);
386 ambientLight.setCapability(Light.ALLOW_COLOR_WRITE);
387 ambientLight.setInfluencingBounds(bounds);
388 group.addChild(ambientLight);
389
390 return group;
391 }
392
393
394
395 public void actionPerformed(ActionEvent e) {
396 String s = e.getActionCommand();
397 if (s.equals("pan")) {
398 mode = PAN;
399
400 } else if (s.equals("zoom")) {
401 mode = ZOOM;
402
403 } else if (s.equals("roll")) {
404 mode = ROLL;
405
406 } else if (s.equals("hide")) {
407 mode = HIDE;
408
409 } else if (s.equals("antialias")) {
410 boolean b = ((JCheckBox)e.getSource()).isSelected();
411 setAA(b);
412
413 } else if (s.equals("brighter")) {
414 deltaLights(0.07);
415
416 } else if (s.equals("darker")) {
417 deltaLights(-0.07);
418
419 } else if (s.equals("showall")) {
420 showAll();
421
422 } else {
423 E.error("unhandled " + s);
424 }
425 }
426
427
428
429
430 void showFraction(double f) {
431 if (shapes == null) {
432 return;
433 }
434 RenderingAttributes rashow = new RenderingAttributes();
435 RenderingAttributes rahide = new RenderingAttributes();
436 rahide.setVisible(false);
437
438 int nch = shapes.size();
439 int nshow = (int)(f * nch);
440
441 if (nshowing < nshow) {
442 for (int i = nshowing; i < nshow; i++) {
443 Shape3D s = shapes.get(i);
444 s.getAppearance().setRenderingAttributes(rashow);
445 s.setUserData(new Integer(1));
446 }
447
448 } else {
449 for (int i = nshow; i < nshowing; i++) {
450 Shape3D s = shapes.get(i);
451 s.getAppearance().setRenderingAttributes(rahide);
452 s.setUserData(new Integer(0));
453 }
454 }
455
456 nshowing = nshow;
457 }
458
459
460 void showAll() {
461 if (shapes == null) {
462 return;
463 }
464 RenderingAttributes rashow = new RenderingAttributes();
465 RenderingAttributes rahide = new RenderingAttributes();
466 rahide.setVisible(false);
467
468 int nch = shapes.size();
469
470 for (int i = 0; i < nch; i++) {
471 Shape3D s = shapes.get(i);
472 s.getAppearance().setRenderingAttributes(rashow);
473 s.setUserData(new Integer(1));
474 }
475
476 nshowing = nch;
477 }
478
479
480
481 public void mouseClicked(MouseEvent e) {
482 }
483
484
485
486 public void mousePressed(MouseEvent e) {
487 dragging = false;
488 downscale = scale;
489 xdown = e.getX();
490 ydown = e.getY();
491
492
493 downTransform = new Transform3D(rootTransform);
494 Transform3D motion = new Transform3D();
495 canvas.getImagePlateToVworld(motion);
496
497 Point3d mouse_pos = new Point3d();
498 wcdown = new Point3d();
499 canvas.getPixelLocationInImagePlate(xdown, ydown, mouse_pos);
500 motion.transform(mouse_pos, wcdown);
501
502 wcdown.z = 0;
503
504 Transform3D t = new Transform3D(rootTransform);
505 t.invert();
506 Point3d cc = new Point3d();
507 t.transform(wcdown, cc);
508 Vector3d vc = new Vector3d(cc);
509
510 tcTrans = new Transform3D();
511 tcTrans.setTranslation(vc);
512
513 fcTrans = new Transform3D();
514 vc.negate();
515 fcTrans.setTranslation(vc);
516
517 Vector3d vw = new Vector3d(wcdown);
518 twTrans = new Transform3D();
519 twTrans.setTranslation(vw);
520
521 fwTrans = new Transform3D();
522 vw.negate();
523 fwTrans.setTranslation(vw);
524
525
526
527
528
529 Transform3D t3 = getPickTransform(e.getX(), e.getY());
530 if (t3 != null) {
531 Point3d p3 = new Point3d();
532 t3.transform(p3);
533 Vector3d vp = new Vector3d(p3);
534 twrcTrans = new Transform3D();
535 twrcTrans.setTranslation(vp);
536
537 fwrcTrans = new Transform3D();
538 vp.negate();
539 fwrcTrans.setTranslation(vp);
540
541
542 if (mode == HIDE) {
543 toggleHide();
544 }
545
546 } else {
547
548 fwrcTrans = fwTrans;
549 twrcTrans = twTrans;
550 }
551
552
553 button = NONE;
554 int m = e.getModifiers();
555 button = LEFT;
556
557 if ((m & InputEvent.BUTTON3_MASK) != 0) {
558 button = RIGHT;
559 } else {
560 int[] masks = {InputEvent.CTRL_MASK, InputEvent.META_MASK, InputEvent.SHIFT_MASK,
561 InputEvent.BUTTON2_MASK
562 };
563 for (int i = 0; i < masks.length; i++) {
564 if ((m & masks[i]) != 0) {
565 button = RIGHT;
566 break;
567 }
568 }
569 }
570 }
571
572
573
574 private void toggleHide() {
575 if (lastPickInfos != null) {
576 int npi = lastPickInfos.length;
577
578 for (int ipi = 0; ipi < npi; ipi++) {
579 PickInfo pi = lastPickInfos[ipi];
580 Node node = pi.getNode();
581 if (node instanceof Shape3D) {
582 Shape3D s3d = (Shape3D)node;
583 boolean hid = hideShape(s3d);
584 if (hid) {
585 break;
586 }
587
588 } else {
589
590 }
591 }
592 }
593 }
594
595
596
597 private void toggleHideShape(Shape3D s3d) {
598 if (!(s3d.getUserData() instanceof Integer)) {
599 s3d.setUserData(new Integer(1));
600 }
601 int ival = ((Integer)(s3d.getUserData())).intValue();
602 if (ival == 1) {
603 hideShape(s3d);
604 } else {
605 showShape(s3d);
606 }
607 }
608
609
610 boolean hideShape(Shape3D s) {
611 boolean hid = false;
612 if (!(s.getUserData() instanceof Integer)) {
613 s.setUserData(new Integer(1));
614 }
615
616 int ival = ((Integer)(s.getUserData())).intValue();
617 if (ival == 1) {
618 hid = true;
619 RenderingAttributes rahide = new RenderingAttributes();
620 rahide.setVisible(false);
621 s.setUserData(new Integer(0));
622 s.getAppearance().setRenderingAttributes(rahide);
623 }
624 return hid;
625 }
626
627 void showShape(Shape3D s) {
628 RenderingAttributes rashow = new RenderingAttributes();
629 s.setUserData(new Integer(1));
630 s.getAppearance().setRenderingAttributes(rashow);
631 }
632
633
634 public void mouseReleased(MouseEvent e) {
635
636 if (dragging) {
637
638 } else if (mode == ZOOM) {
639
640 } else if (mode == HIDE) {
641
642
643 } else {
644 if (button == LEFT) {
645 zoomBy(1. / 0.7);
646 } else if (button == RIGHT) {
647 zoomBy(0.7);
648
649 }
650 }
651 }
652
653
654 private void zoomBy(double d) {
655 zoomTo(scale * d);
656 }
657
658 private void zoomTo(double d) {
659 scale = (float)d;
660
661 double fscale = d / downscale;
662 Transform3D tscale = new Transform3D();
663 tscale.setScale(fscale);
664 Transform3D tnew = new Transform3D();
665
666
667
668
669
670
671
672 tnew.mul(twTrans);
673 tnew.mul(tscale);
674 tnew.mul(fwTrans);
675 tnew.mul(downTransform);
676
677 setTransform(tnew);
678 }
679
680 private void setTransform(Transform3D t3d) {
681 rootTransform = t3d;
682 rootTransformGroup.setTransform(rootTransform);
683 decTransformGroup.setTransform(rootTransform);
684 }
685
686
687
688 @SuppressWarnings("unused")
689 public void intPan(int dx, int dy, Point3d cpos) {
690
691
692 Transform3D ttrans = new Transform3D();
693 Vector3d v = new Vector3d(cpos.x - wcdown.x, cpos.y - wcdown.y, 0.);
694
695 ttrans.setTranslation(v);
696
697 Transform3D tnew = new Transform3D();
698
699 tnew.mul(ttrans);
700 tnew.mul(downTransform);
701 setTransform(tnew);
702 }
703
704
705
706 private void intRoll(int dx, int dy) {
707
708 double wdx = dx;
709 double wdy = dy;
710
711 Transform3D trot = new Transform3D();
712 double theta = 0.005 * Math.sqrt(dx * dx + dy * dy);
713 AxisAngle4d aa4d = new AxisAngle4d(wdy, wdx, 0., theta);
714 trot.setRotation(aa4d);
715
716
717 Transform3D tnew = new Transform3D();
718
719 tnew.mul(twrcTrans);
720 tnew.mul(trot);
721 tnew.mul(fwrcTrans);
722 tnew.mul(downTransform);
723
724 setTransform(tnew);
725 }
726
727
728
729
730
731
732 public void mouseDragged(MouseEvent e) {
733 int x = e.getX();
734 int y = e.getY();
735 if (!dragging && (x-xdown)*(x-xdown) + (y-ydown)*(y-ydown) > 10) {
736 dragging = true;
737 }
738 if (dragging) {
739
740 Point3d cpos = new Point3d();
741 canvas.getPixelLocationInImagePlate(x, y, cpos);
742 Transform3D motion = new Transform3D();
743 canvas.getImagePlateToVworld(motion);
744 motion.transform(cpos);
745
746 if (mode == PAN) {
747 intPan(x - xdown, y - ydown, cpos);
748
749 } else if (mode == ZOOM) {
750 double f = Math.exp(0.01 * (y - ydown));
751 zoomTo(f * downscale);
752
753 } else {
754 if (button == LEFT) {
755 intRoll(x - xdown, y - ydown);
756 } else {
757 intPan(x - xdown, y - ydown, cpos);
758 }
759 }
760 }
761
762
763 }
764
765
766
767
768
769 private Transform3D getPickTransform(int xpos, int ypos) {
770 float tolerance = 0.1f;
771
772 Transform3D motion = new Transform3D();
773 Point3d eyePosn = new Point3d();
774 Point3d mousePosn = new Point3d();
775 Vector3d mouseVec = new Vector3d();
776 boolean isParallel = false;
777 double spreadAngle = 0.0;
778
779 canvas.getCenterEyeInImagePlate(eyePosn);
780 canvas.getPixelLocationInImagePlate(xpos,ypos,mousePosn);
781
782 if ((canvas.getView() != null) &&
783 (canvas.getView().getProjectionPolicy() == View.PARALLEL_PROJECTION)) {
784
785 eyePosn.x = mousePosn.x;
786 eyePosn.y = mousePosn.y;
787 isParallel = true;
788 }
789
790
791 Vector3d eyeToCanvas = new Vector3d();
792 eyeToCanvas.sub(mousePosn, eyePosn);
793 double distanceEyeToCanvas = eyeToCanvas.length();
794
795 Point3d deltaImgPlate = new Point3d();
796 canvas.getPixelLocationInImagePlate(xpos+1, ypos, deltaImgPlate);
797
798 Vector3d ptToDelta = new Vector3d();
799 ptToDelta.sub(mousePosn, deltaImgPlate);
800 double distancePtToDelta = ptToDelta.length();
801 distancePtToDelta *= tolerance;
802
803 canvas.getImagePlateToVworld(motion);
804
805 motion.transform(eyePosn);
806 motion.transform(mousePosn);
807 mouseVec.sub(mousePosn, eyePosn);
808 mouseVec.normalize();
809
810
811 PickShape pickShape = null;
812
813 if (tolerance == 0.0) {
814 pickShape = new PickRay(eyePosn, mouseVec);
815
816 } else if (isParallel) {
817 pickShape = new PickCylinderRay(eyePosn, mouseVec, distancePtToDelta);
818
819 } else {
820
821
822 spreadAngle = Math.atan(distancePtToDelta/distanceEyeToCanvas);
823 pickShape = new PickConeRay(eyePosn, mouseVec, spreadAngle);
824 }
825
826
827 PickInfo pickInfo = baseGroup.pickClosest(PickInfo.PICK_GEOMETRY, PickInfo.LOCAL_TO_VWORLD, pickShape);
828 Transform3D ret = null;
829 if (pickInfo != null) {
830 ret = pickInfo.getLocalToVWorld();
831 }
832
833 lastPickInfos = baseGroup.pickAllSorted(PickInfo.PICK_GEOMETRY, PickInfo.NODE, pickShape);
834
835 return ret;
836 }
837
838
839
840
841 public void mouseEntered(MouseEvent e) {
842
843
844 }
845
846 public void mouseExited(MouseEvent e) {
847
848
849 }
850
851 public void mouseMoved(MouseEvent e) {
852
853
854 }
855
856 public static GraphicsConfiguration getPreferredConfiguration() {
857 GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
858
859
860 return GraphicsEnvironment.getLocalGraphicsEnvironment().
861 getDefaultScreenDevice().getBestConfiguration(template);
862 }
863
864
865
866
867 public void setDecoration(String id, BranchGroup root, boolean b) {
868 root.setCapability(BranchGroup.ALLOW_DETACH);
869 root.compile();
870 if (sceneItemHM.containsKey(id)) {
871 setDecorationVisibility(id, false);
872 sceneItemHM.remove(sceneItemHM.get(id));
873 }
874 SceneItem sit = new SceneItem(id, root);
875 sceneItemHM.put(id, sit);
876 setDecorationVisibility(id, b);
877 }
878
879
880 public void removeUnlistedDecoration(HashSet<String> keepHS) {
881 for (String s : sceneItemHM.keySet()) {
882 if (keepHS != null && keepHS.contains(s)) {
883
884 } else {
885 setDecorationVisibility(s, false);
886 sceneItemHM.remove(sceneItemHM.get(s));
887 }
888 }
889 }
890
891
892 public void removeAllDecoration() {
893 removeUnlistedDecoration(null);
894 }
895
896
897 public synchronized void setDecorationVisibility(String s, boolean b) {
898 SceneItem sit = sceneItemHM.get(s);
899 if (sit.showing) {
900 if (b) {
901
902 } else {
903 decTransformGroup.removeChild(sit.getBranchGroup());
904 sit.showing = false;
905 }
906
907 } else {
908 if (b) {
909 sit.showing = true;
910 decTransformGroup.addChild(sit.getBranchGroup());
911 } else {
912
913 }
914 }
915 }
916
917
918
919 public void setAA(boolean b) {
920 view.setSceneAntialiasingEnable(b);
921 }
922
923
924
925 public void setLightsPercent(int p) {
926 setBrightness(p / 100.);
927
928 }
929
930
931
932 public void setFourMatrix(double[] fmo) {
933 Matrix4d m4d = new Matrix4d();
934 m4d.set(fmo);
935 Transform3D t3d = new Transform3D(m4d);
936 setTransform(t3d);
937 }
938
939
940
941 public double[] getFourMatrix() {
942 double[] mtx = new double[16];
943 rootTransform.get(mtx);
944 return mtx;
945 }
946
947
948
949
950 public void stateChanged(ChangeEvent e) {
951 JSlider js = (JSlider)e.getSource();
952 int val = js.getValue();
953 double fval = val / 1000.;
954 showFraction(fval);
955 }
956
957
958
959
960 }