aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/org')
-rw-r--r--src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java310
-rw-r--r--src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java356
-rw-r--r--src/classes/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java125
-rw-r--r--src/classes/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java508
-rw-r--r--src/classes/org/jdesktop/j3d/examples/appearance/AppearanceTest.java382
-rw-r--r--src/classes/org/jdesktop/j3d/examples/appearance/Tetrahedron.java109
-rw-r--r--src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.html15
-rw-r--r--src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.java129
-rw-r--r--src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D_plugin.html39
-rw-r--r--src/classes/org/jdesktop/j3d/examples/background/BackgroundGeometry.java238
-rw-r--r--src/classes/org/jdesktop/j3d/examples/cg_shader/ObjLoadCg.java345
-rw-r--r--src/classes/org/jdesktop/j3d/examples/cg_shader/SphereCg.java348
-rw-r--r--src/classes/org/jdesktop/j3d/examples/cg_shader/simple_fp.cg68
-rw-r--r--src/classes/org/jdesktop/j3d/examples/cg_shader/simple_vp.cg167
-rw-r--r--src/classes/org/jdesktop/j3d/examples/collision/Box.java100
-rw-r--r--src/classes/org/jdesktop/j3d/examples/collision/CollisionDetector.java92
-rw-r--r--src/classes/org/jdesktop/j3d/examples/collision/TickTockCollision.java219
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java311
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/README.txt142
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x198
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior149
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo113
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr212
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window89
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat134
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot3099
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave171
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr222
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45110
-rw-r--r--src/classes/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat135
-rw-r--r--src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form217
-rw-r--r--src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java359
-rw-r--r--src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.form25
-rw-r--r--src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.java292
-rw-r--r--src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java194
-rw-r--r--src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java210
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/BigCube.java140
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/Board.java2312
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java94
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/Cube.java133
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/Cylinder.java116
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.html15
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.java886
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour_plugin.html39
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/ID.java61
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java218
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/Poles.java82
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/Positions.java313
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/README.txt8
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/instructions.txt98
-rw-r--r--src/classes/org/jdesktop/j3d/examples/four_by_four/scores.txt20
-rw-r--r--src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java281
-rw-r--r--src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java221
-rw-r--r--src/classes/org/jdesktop/j3d/examples/gears/Gear.java399
-rw-r--r--src/classes/org/jdesktop/j3d/examples/gears/GearBox.java356
-rw-r--r--src/classes/org/jdesktop/j3d/examples/gears/GearTest.java208
-rw-r--r--src/classes/org/jdesktop/j3d/examples/gears/Shaft.java198
-rw-r--r--src/classes/org/jdesktop/j3d/examples/gears/SpurGear.java558
-rw-r--r--src/classes/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java187
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java519
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java554
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java330
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java536
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java506
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java358
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java249
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_compression/README.txt23
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_compression/cgview.java214
-rw-r--r--src/classes/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java73
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java342
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form138
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java450
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form266
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java668
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java341
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag55
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert42
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.frag61
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.vert42
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag50
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert100
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.frag98
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.vert56
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag48
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert58
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.frag62
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.vert129
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.frag34
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.vert19
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.frag66
-rw-r--r--src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.vert25
-rw-r--r--src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form36
-rw-r--r--src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java169
-rw-r--r--src/classes/org/jdesktop/j3d/examples/lightwave/README.txt321
-rw-r--r--src/classes/org/jdesktop/j3d/examples/lightwave/Viewer.java209
-rw-r--r--src/classes/org/jdesktop/j3d/examples/lod/LOD.java181
-rw-r--r--src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java176
-rw-r--r--src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java197
-rw-r--r--src/classes/org/jdesktop/j3d/examples/morphing/ColorCube.java123
-rw-r--r--src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java123
-rw-r--r--src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java125
-rw-r--r--src/classes/org/jdesktop/j3d/examples/morphing/Morphing.java262
-rw-r--r--src/classes/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java99
-rw-r--r--src/classes/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java194
-rw-r--r--src/classes/org/jdesktop/j3d/examples/objload/ObjLoad.java287
-rw-r--r--src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java105
-rw-r--r--src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form36
-rw-r--r--src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java219
-rw-r--r--src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java85
-rw-r--r--src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form82
-rw-r--r--src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java262
-rw-r--r--src/classes/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java196
-rw-r--r--src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java297
-rw-r--r--src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java305
-rw-r--r--src/classes/org/jdesktop/j3d/examples/package_info/PackageInfo.java95
-rw-r--r--src/classes/org/jdesktop/j3d/examples/package_info/QueryProperties.java150
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/BoltCG.java359
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/ColorCube.java123
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java123
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java125
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/Cube.java110
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/CubeIQA.java138
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/CubeQA.java135
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/GullCG.java578
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java180
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java177
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java253
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/IntersectTest.java235
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/MorphingBehavior.java99
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/OctahedronITFA.java115
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/OctahedronTFA.java114
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java102
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/PickTest.java416
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/PickText3DBounds.java234
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java252
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/RandomColorCube.java131
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java101
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/Tetrahedron.java112
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILA.java106
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java97
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java81
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TetrahedronITA.java104
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLA.java104
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java94
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TetrahedronPA.java71
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TetrahedronTA.java102
-rw-r--r--src/classes/org/jdesktop/j3d/examples/picking/TickTockPicking.java448
-rw-r--r--src/classes/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java200
-rw-r--r--src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java130
-rw-r--r--src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java112
-rw-r--r--src/classes/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java82
-rw-r--r--src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form74
-rw-r--r--src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java374
-rw-r--r--src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java151
-rw-r--r--src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java266
-rw-r--r--src/classes/org/jdesktop/j3d/examples/read_raster/ReadRaster.java224
-rw-r--r--src/classes/org/jdesktop/j3d/examples/sound/AudioBehaviorMoveOne.java106
-rw-r--r--src/classes/org/jdesktop/j3d/examples/sound/AudioReverberate.java171
-rw-r--r--src/classes/org/jdesktop/j3d/examples/sound/MoveAppBoundingLeaf.java389
-rw-r--r--src/classes/org/jdesktop/j3d/examples/sound/ReverberateSound.java222
-rw-r--r--src/classes/org/jdesktop/j3d/examples/sound/SimpleSounds.java294
-rw-r--r--src/classes/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java179
-rw-r--r--src/classes/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java303
-rw-r--r--src/classes/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java603
-rw-r--r--src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form82
-rw-r--r--src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java252
-rw-r--r--src/classes/org/jdesktop/j3d/examples/text2d/MoverBehavior.java141
-rw-r--r--src/classes/org/jdesktop/j3d/examples/text2d/Text2DTest.java193
-rw-r--r--src/classes/org/jdesktop/j3d/examples/text3d/Text3DLoad.java286
-rw-r--r--src/classes/org/jdesktop/j3d/examples/texture/MultiTextureTest.java320
-rw-r--r--src/classes/org/jdesktop/j3d/examples/texture/TextureImage.java180
-rw-r--r--src/classes/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java317
-rw-r--r--src/classes/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java175
-rw-r--r--src/classes/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java223
-rw-r--r--src/classes/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java532
-rw-r--r--src/classes/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java209
-rw-r--r--src/classes/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java70
-rw-r--r--src/classes/org/jdesktop/j3d/examples/virtual_input_device/README.txt195
-rw-r--r--src/classes/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java73
-rw-r--r--src/classes/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java72
-rw-r--r--src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java260
-rw-r--r--src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java136
-rw-r--r--src/classes/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java401
183 files changed, 38037 insertions, 0 deletions
diff --git a/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java
new file mode 100644
index 0000000..6f7e499
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java
@@ -0,0 +1,310 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.alternate_appearance;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.sun.j3d.utils.behaviors.mouse.*;
+
+public class AlternateAppearanceBoundsTest extends JApplet
+implements ActionListener {
+
+
+ Material mat1, altMat;
+ Appearance app, otherApp;
+ JComboBox altAppMaterialColor;
+ JComboBox appMaterialColor;
+ JCheckBox useBoundingLeaf;
+ JCheckBox override;
+ JComboBox boundsType;
+ private Group content1 = null;
+ AlternateAppearance altApp;
+ Shape3D[] shapes1;
+ boolean boundingLeafOn = false;
+ // Globally used colors
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
+ Color3f[] colors = {white, red, green, blue};
+
+ private Bounds worldBounds = new BoundingSphere(
+ new Point3d( 0.0, 0.0, 0.0 ), // Center
+ 1000.0 ); // Extent
+ private Bounds smallBounds = new BoundingSphere(
+ new Point3d( 0.0, 0.0, 0.0 ), // Center
+ 0.25 ); // Extent
+ private Bounds tinyBounds = new BoundingSphere(
+ new Point3d( 0.0, 0.0, 0.0 ), // Center
+ 0.05 ); // Extent
+ private BoundingLeaf leafBounds = null;
+ private int currentBounds = 2;
+
+ private Bounds[] allBounds = {tinyBounds, smallBounds, worldBounds};
+
+ DirectionalLight light1 = null;
+
+ // Get the current bounding leaf position
+ private int currentPosition = 0;
+ // Point3f pos = (Point3f)positions[currentPosition].value;
+
+ private SimpleUniverse u = null;
+
+ public AlternateAppearanceBoundsTest() {
+ }
+
+ public void init() {
+ Container contentPane = getContentPane();
+
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ contentPane.add("Center", c);
+
+ BranchGroup scene = createSceneGraph();
+ // SimpleUniverse is a Convenience Utility class
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+ u.addBranchGraph(scene);
+
+
+ // Create GUI
+ JPanel p = new JPanel();
+ BoxLayout boxlayout = new BoxLayout(p,
+ BoxLayout.Y_AXIS);
+ p.add(createBoundsPanel());
+ p.add(createMaterialPanel());
+ p.setLayout(boxlayout);
+
+ contentPane.add("South", p);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ BranchGroup createSceneGraph() {
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create an alternate appearance
+ otherApp = new Appearance();
+ altMat = new Material();
+ altMat.setCapability(Material.ALLOW_COMPONENT_WRITE);
+ altMat.setDiffuseColor( new Color3f( 0.0f, 1.0f, 0.0f ) );
+ otherApp.setMaterial(altMat);
+
+ altApp = new AlternateAppearance();
+ altApp.setAppearance(otherApp);
+ altApp.setCapability(AlternateAppearance.ALLOW_BOUNDS_WRITE);
+ altApp.setCapability(AlternateAppearance.ALLOW_INFLUENCING_BOUNDS_WRITE);
+ altApp.setInfluencingBounds( worldBounds );
+ objRoot.addChild(altApp);
+
+ // Build foreground geometry
+ Appearance app1 = new Appearance();
+ mat1 = new Material();
+ mat1.setCapability(Material.ALLOW_COMPONENT_WRITE);
+ mat1.setDiffuseColor( new Color3f( 1.0f, 0.0f, 0.0f ) );
+ app1.setMaterial(mat1);
+ content1 = new SphereGroup(
+ 0.05f, // radius of spheres
+ 0.15f, // x spacing
+ 0.15f, // y spacing
+ 5, // number of spheres in X
+ 5, // number of spheres in Y
+ app1, // appearance
+ true); // alt app override = true
+ objRoot.addChild( content1 );
+ shapes1 = ((SphereGroup)content1).getShapes();
+
+
+
+ // Add lights
+ light1 = new DirectionalLight( );
+ light1.setEnable( true );
+ light1.setColor( new Color3f(0.2f, 0.2f, 0.2f) );
+ light1.setDirection( new Vector3f( 1.0f, 0.0f, -1.0f ) );
+ light1.setInfluencingBounds( worldBounds );
+ light1.setCapability(
+ DirectionalLight.ALLOW_INFLUENCING_BOUNDS_WRITE );
+ light1.setCapability(
+ DirectionalLight.ALLOW_BOUNDS_WRITE );
+ objRoot.addChild( light1 );
+
+ // Add an ambient light to dimly illuminate the rest of
+ // the shapes in the scene to help illustrate that the
+ // directional lights are being scoped... otherwise it looks
+ // like we're just removing shapes from the scene
+ AmbientLight ambient = new AmbientLight( );
+ ambient.setEnable( true );
+ ambient.setColor( new Color3f(1.0f, 1.0f, 1.0f) );
+ ambient.setInfluencingBounds( worldBounds );
+ objRoot.addChild( ambient );
+
+
+ // Define a bounding leaf
+ leafBounds = new BoundingLeaf( allBounds[currentBounds] );
+ leafBounds.setCapability( BoundingLeaf.ALLOW_REGION_WRITE );
+ objRoot.addChild( leafBounds );
+ if (boundingLeafOn) {
+ altApp.setInfluencingBoundingLeaf(leafBounds);
+ }
+ else {
+ altApp.setInfluencingBounds(allBounds[currentBounds]);
+ }
+
+
+
+ return objRoot;
+ }
+ JPanel createBoundsPanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Scopes"));
+
+
+ String boundsValues[] = { "Tiny Bounds", "Small Bounds", "Big Bounds"};
+
+ boundsType = new JComboBox(boundsValues);
+ boundsType.addActionListener(this);
+ boundsType.setSelectedIndex(2);
+ panel.add(new JLabel("Bounds"));
+ panel.add(boundsType);
+
+ useBoundingLeaf = new JCheckBox("Enable BoundingLeaf",
+ boundingLeafOn);
+ useBoundingLeaf.addActionListener(this);
+ panel.add(useBoundingLeaf);
+
+ override = new JCheckBox("Enable App Override",
+ false);
+ override.addActionListener(this);
+ panel.add(override);
+
+ return panel;
+
+ }
+
+ JPanel createMaterialPanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Appearance Attributes"));
+
+ String colorVals[] = { "WHITE", "RED", "GREEN", "BLUE"};
+
+ altAppMaterialColor = new JComboBox(colorVals);
+ altAppMaterialColor.addActionListener(this);
+ altAppMaterialColor.setSelectedIndex(2);
+ panel.add(new JLabel("Alternate Appearance MaterialColor"));
+ panel.add(altAppMaterialColor);
+
+
+
+ appMaterialColor = new JComboBox(colorVals);
+ appMaterialColor.addActionListener(this);
+ appMaterialColor.setSelectedIndex(1);
+ panel.add(new JLabel("Normal Appearance MaterialColor"));
+ panel.add(appMaterialColor);
+
+ return panel;
+
+
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ int i;
+
+ Object target = e.getSource();
+ if (target == altAppMaterialColor) {
+ altMat.setDiffuseColor(colors[altAppMaterialColor.getSelectedIndex()]);
+ }
+ else if (target == useBoundingLeaf) {
+ boundingLeafOn = useBoundingLeaf.isSelected();
+ if (boundingLeafOn) {
+ leafBounds.setRegion(allBounds[currentBounds]);
+ altApp.setInfluencingBoundingLeaf( leafBounds );
+ }
+ else {
+ altApp.setInfluencingBoundingLeaf( null );
+ altApp.setInfluencingBounds(allBounds[currentBounds]);
+ }
+
+ }
+ else if (target == boundsType) {
+ currentBounds = boundsType.getSelectedIndex();
+ if (boundingLeafOn) {
+ leafBounds.setRegion(allBounds[currentBounds]);
+ altApp.setInfluencingBoundingLeaf( leafBounds );
+ }
+ else {
+ altApp.setInfluencingBoundingLeaf( null );
+ altApp.setInfluencingBounds(allBounds[currentBounds]);
+ }
+
+ }
+ else if (target == override) {
+ for (i = 0; i < shapes1.length; i++)
+ shapes1[i].setAppearanceOverrideEnable(override.isSelected());
+ }
+ else if (target == appMaterialColor) {
+ mat1.setDiffuseColor(colors[appMaterialColor.getSelectedIndex()]);
+ }
+
+ }
+
+
+ public static void main(String[] args) {
+ Frame frame = new MainFrame(new AlternateAppearanceBoundsTest(), 800, 800);
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java
new file mode 100644
index 0000000..a2bf786
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java
@@ -0,0 +1,356 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.alternate_appearance;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+
+public class AlternateAppearanceScopeTest extends JApplet
+implements ActionListener {
+
+
+ Material mat1, altMat;
+ Appearance app, otherApp;
+ JComboBox altAppMaterialColor;
+ JComboBox appMaterialColor;
+ JComboBox altAppScoping;
+ JComboBox override;
+ private Group content1 = null;
+ private Group content2 = null;
+ BoundingSphere worldBounds;
+ AlternateAppearance altApp;
+ Shape3D[] shapes1, shapes2;
+ boolean shape1Enabled = false, shape2Enabled = false;
+ // Globally used colors
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
+ Color3f[] colors = {white, red, green, blue};
+
+ private SimpleUniverse u;
+
+ public AlternateAppearanceScopeTest() {
+ }
+
+ public void init() {
+ Container contentPane = getContentPane();
+
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ contentPane.add("Center", c);
+
+ BranchGroup scene = createSceneGraph();
+ // SimpleUniverse is a Convenience Utility class
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the viewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ OrbitBehavior orbit = new OrbitBehavior(c,
+ OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
+ 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene);
+
+
+ // Create GUI
+ JPanel p = new JPanel();
+ BoxLayout boxlayout = new BoxLayout(p,
+ BoxLayout.Y_AXIS);
+ p.add(createScopingPanel());
+ p.add(createMaterialPanel());
+ p.setLayout(boxlayout);
+
+ contentPane.add("South", p);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ BranchGroup createSceneGraph() {
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create influencing bounds
+ worldBounds = new BoundingSphere(
+ new Point3d( 0.0, 0.0, 0.0 ), // Center
+ 1000.0 ); // Extent
+
+ Transform3D t = new Transform3D();
+ // move the object upwards
+ t.set(new Vector3f(0.0f, 0.1f, 0.0f));
+ // Shrink the object
+ t.setScale(0.8);
+
+ TransformGroup trans = new TransformGroup(t);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+
+
+ otherApp = new Appearance();
+ altMat = new Material();
+ altMat.setCapability(Material.ALLOW_COMPONENT_WRITE);
+ altMat.setDiffuseColor( new Color3f( 0.0f, 1.0f, 0.0f ) );
+ otherApp.setMaterial(altMat);
+
+ altApp = new AlternateAppearance();
+ altApp.setAppearance(otherApp);
+ altApp.setCapability(AlternateAppearance.ALLOW_SCOPE_WRITE);
+ altApp.setCapability(AlternateAppearance.ALLOW_SCOPE_READ);
+ altApp.setInfluencingBounds( worldBounds );
+ objRoot.addChild(altApp);
+
+ // Build foreground geometry into two groups. We'll
+ // create three directional lights below, one each with
+ // scope to cover the first geometry group only, the
+ // second geometry group only, or both geometry groups.
+ Appearance app1 = new Appearance();
+ mat1 = new Material();
+ mat1.setCapability(Material.ALLOW_COMPONENT_WRITE);
+ mat1.setDiffuseColor( new Color3f( 1.0f, 0.0f, 0.0f ) );
+ app1.setMaterial(mat1);
+ content1 = new SphereGroup(
+ 0.05f, // radius of spheres
+ 0.4f, // x spacing
+ 0.2f, // y spacing
+ 3, // number of spheres in X
+ 5, // number of spheres in Y
+ app1, // appearance
+ true); // alt app override = true
+ trans.addChild( content1 );
+ shapes1 = ((SphereGroup)content1).getShapes();
+
+ content2 = new SphereGroup(
+ 0.05f, // radius of spheres
+ .4f, // x spacing
+ 0.2f, // y spacing
+ 2, // number of spheres in X
+ 5, // number of spheres in Y
+ app1, // appearance
+ true); // alt app override = true
+ trans.addChild( content2 );
+ shapes2 = ((SphereGroup)content2).getShapes();
+
+
+ // Add lights
+ DirectionalLight light1 = null;
+ light1 = new DirectionalLight( );
+ light1.setEnable( true );
+ light1.setColor( new Color3f(0.2f, 0.2f, 0.2f) );
+ light1.setDirection( new Vector3f( 1.0f, 0.0f, -1.0f ) );
+ light1.setInfluencingBounds( worldBounds );
+ objRoot.addChild( light1 );
+
+ DirectionalLight light2 = new DirectionalLight();
+ light2.setEnable(true);
+ light2.setColor(new Color3f(0.2f, 0.2f, 0.2f));
+ light2.setDirection(new Vector3f(-1.0f, 0.0f, 1.0f));
+ light2.setInfluencingBounds(worldBounds);
+ objRoot.addChild(light2);
+
+ // Add an ambient light to dimly illuminate the rest of
+ // the shapes in the scene to help illustrate that the
+ // directional lights are being scoped... otherwise it looks
+ // like we're just removing shapes from the scene
+ AmbientLight ambient = new AmbientLight( );
+ ambient.setEnable( true );
+ ambient.setColor( new Color3f(1.0f, 1.0f, 1.0f) );
+ ambient.setInfluencingBounds( worldBounds );
+ objRoot.addChild( ambient );
+
+
+ objRoot.addChild(trans);
+
+ return objRoot;
+ }
+ JPanel createScopingPanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Scopes"));
+
+ String values[] = {"Scoped Set1", "Scoped Set2", "Universal Scope"};
+ altAppScoping = new JComboBox(values);
+ altAppScoping.addActionListener(this);
+ altAppScoping.setSelectedIndex(2);
+ panel.add(new JLabel("Scoping"));
+ panel.add(altAppScoping);
+
+
+ String enables[] = { "Enabled Set1", "Enabled Set2", "Enabled set1&2", "Disabled set1&2"};
+
+ override = new JComboBox(enables);
+ override.addActionListener(this);
+ override.setSelectedIndex(3);
+ panel.add(new JLabel("Alternate Appearance Override"));
+ panel.add(override);
+
+ return panel;
+
+ }
+
+ JPanel createMaterialPanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Appearance Attributes"));
+
+ String colorVals[] = { "WHITE", "RED", "GREEN", "BLUE"};
+
+ altAppMaterialColor = new JComboBox(colorVals);
+ altAppMaterialColor.addActionListener(this);
+ altAppMaterialColor.setSelectedIndex(2);
+ panel.add(new JLabel("Alternate Appearance MaterialColor"));
+ panel.add(altAppMaterialColor);
+
+
+
+ appMaterialColor = new JComboBox(colorVals);
+ appMaterialColor.addActionListener(this);
+ appMaterialColor.setSelectedIndex(1);
+ panel.add(new JLabel("Normal Appearance MaterialColor"));
+ panel.add(appMaterialColor);
+
+ return panel;
+
+
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object target = e.getSource();
+ if (target == altAppMaterialColor) {
+ altMat.setDiffuseColor(colors[altAppMaterialColor.getSelectedIndex()]);
+ }
+ else if (target == altAppScoping) {
+ for (int i = 0; i < altApp.numScopes(); i++) {
+ altApp.removeScope(0);
+ }
+ if (altAppScoping.getSelectedIndex() == 0) {
+ altApp.addScope(content1);
+ }
+ else if (altAppScoping.getSelectedIndex() == 1) {
+ altApp.addScope(content2);
+ }
+ }
+ else if (target == override) {
+ int i;
+ if (override.getSelectedIndex()== 0) {
+ if (!shape1Enabled) {
+ for (i = 0; i < shapes1.length; i++)
+ shapes1[i].setAppearanceOverrideEnable(true);
+ shape1Enabled = true;
+ }
+
+ if (shape2Enabled) {
+ for (i = 0; i < shapes2.length; i++)
+ shapes2[i].setAppearanceOverrideEnable(false);
+ shape2Enabled = false;
+ }
+ }
+ else if (override.getSelectedIndex() == 1) {
+ if (!shape2Enabled) {
+ for (i = 0; i < shapes2.length; i++)
+ shapes2[i].setAppearanceOverrideEnable(true);
+ shape2Enabled = true;
+ }
+
+ if (shape1Enabled) {
+ for (i = 0; i < shapes1.length; i++)
+ shapes1[i].setAppearanceOverrideEnable(false);
+ shape1Enabled = false;
+ }
+ }
+ else if (override.getSelectedIndex() == 2) {
+ if (!shape1Enabled) {
+ for (i = 0; i < shapes1.length; i++)
+ shapes1[i].setAppearanceOverrideEnable(true);
+ shape1Enabled = true;
+ }
+ if (!shape2Enabled) {
+ for (i = 0; i < shapes2.length; i++)
+ shapes2[i].setAppearanceOverrideEnable(true);
+ shape2Enabled = true;
+ }
+ }
+ else {
+ if (shape1Enabled) {
+ for (i = 0; i < shapes1.length; i++)
+ shapes1[i].setAppearanceOverrideEnable(false);
+ shape1Enabled = false;
+ }
+
+ if (shape2Enabled) {
+ for (i = 0; i < shapes2.length; i++)
+ shapes2[i].setAppearanceOverrideEnable(false);
+ shape2Enabled = false;
+ }
+ }
+
+ }
+ else if (target == appMaterialColor) {
+ mat1.setDiffuseColor(colors[appMaterialColor.getSelectedIndex()]);
+ }
+
+ }
+
+
+ public static void main(String[] args) {
+ Frame frame = new MainFrame(new AlternateAppearanceScopeTest(), 800, 800);
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java
new file mode 100644
index 0000000..5e8a421
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java
@@ -0,0 +1,125 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.alternate_appearance;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import com.sun.j3d.utils.geometry.*;
+
+public class SphereGroup
+ extends Group
+{
+ Shape3D[] shapes;
+ int numShapes = 0;
+ // Constructors
+ public SphereGroup( )
+ {
+ // radius x,y spacing x,y count appearance
+ this( 0.25f, 0.75f, 0.75f, 5, 5, null, false );
+ }
+
+ public SphereGroup( Appearance app )
+ {
+ // radius x,y spacing x,y count appearance
+ this( 0.25f, 0.75f, 0.75f, 5, 5, app, false );
+ }
+
+ public SphereGroup( float radius, float xSpacing, float ySpacing,
+ int xCount, int yCount, boolean overrideflag )
+ {
+ this( radius, xSpacing, ySpacing, xCount, yCount, null, overrideflag );
+ }
+
+ public SphereGroup( float radius, float xSpacing, float ySpacing,
+ int xCount, int yCount, Appearance app, boolean overrideflag )
+ {
+ if ( app == null )
+ {
+ app = new Appearance( );
+ Material material = new Material( );
+ material.setDiffuseColor( new Color3f( 0.8f, 0.8f, 0.8f ) );
+ material.setSpecularColor( new Color3f( 0.0f, 0.0f, 0.0f ) );
+ material.setShininess( 0.0f );
+ app.setMaterial( material );
+ }
+
+ double xStart = -xSpacing * (double)(xCount-1) / 2.0;
+ double yStart = -ySpacing * (double)(yCount-1) / 2.0;
+
+ Sphere sphere = null;
+ TransformGroup trans = null;
+ Transform3D t3d = new Transform3D( );
+ Vector3d vec = new Vector3d( );
+ double x, y = yStart, z = 0.0;
+ shapes = new Shape3D[xCount * yCount];
+ for ( int i = 0; i < yCount; i++ )
+ {
+ x = xStart;
+ for ( int j = 0; j < xCount; j++ ) {
+ vec.set( x, y, z );
+ t3d.setTranslation( vec );
+ trans = new TransformGroup( t3d );
+ addChild( trans );
+
+ sphere = new Sphere(
+ radius, // sphere radius
+ Primitive.GENERATE_NORMALS, // generate normals
+ 16, // 16 divisions radially
+ app ); // it's appearance
+ trans.addChild( sphere );
+ x += xSpacing;
+ shapes[numShapes] = sphere.getShape();
+ if (overrideflag)
+ shapes[numShapes].setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE);
+ numShapes++;
+ }
+ y += ySpacing;
+ }
+ }
+ Shape3D[] getShapes() {
+ return shapes;
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java b/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java
new file mode 100644
index 0000000..578401e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java
@@ -0,0 +1,508 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.appearance;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.GraphicsConfiguration;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import com.sun.j3d.utils.geometry.ColorCube;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class AppearanceMixed extends Applet {
+
+ private java.net.URL bgImage;
+ private java.net.URL texImage;
+
+ private SimpleUniverse u = null;
+
+ static class MyCanvas3D extends Canvas3D {
+ private GraphicsContext3D gc;
+
+ private static final int vertIndices[] = { 0, 1, 2, 0, 2, 3 };
+ private static final int normalIndices[] = { 0, 0, 0, 1, 1, 1 };
+ private IndexedTriangleArray tri =
+ new IndexedTriangleArray(4, IndexedTriangleArray.COORDINATES |
+ IndexedTriangleArray.NORMALS, 6);
+
+ private Point3f vert[] = {
+ new Point3f(-0.12f, -0.12f, 0.0f),
+ new Point3f( 0.12f, -0.12f, 0.0f),
+ new Point3f( 0.12f, 0.12f, 0.0f),
+ new Point3f(-0.12f, 0.12f, 0.0f),
+ };
+
+ private Point3f min[] = {
+ new Point3f(-0.24f, -0.24f, -0.20f),
+ new Point3f( 0.04f, -0.28f, -0.24f),
+ new Point3f( 0.00f, 0.00f, -0.24f),
+ new Point3f(-0.32f, 0.08f, -0.20f),
+ };
+
+ private Point3f max[] = {
+ new Point3f(-0.04f, -0.04f, 0.12f),
+ new Point3f( 0.32f, -0.04f, 0.16f),
+ new Point3f( 0.36f, 0.28f, 0.20f),
+ new Point3f(-0.04f, 0.24f, 0.16f),
+ };
+
+ private Point3f delta[] = {
+ new Point3f(-0.0021f, -0.0017f, 0.0014f),
+ new Point3f( 0.0025f, -0.0013f, -0.0018f),
+ new Point3f( 0.0021f, 0.0017f, 0.0018f),
+ new Point3f(-0.0025f, 0.0013f, -0.0014f),
+ };
+
+ private Vector3f normals[];
+ private Vector3f v01 = new Vector3f();
+ private Vector3f v02 = new Vector3f();
+ private Vector3f v03 = new Vector3f();
+
+ public void renderField(int fieldDesc) {
+ computeVert();
+ computeNormals();
+ gc.draw(tri);
+ }
+
+ private void computeVert() {
+ for (int i = 0; i < 4; i++) {
+ vert[i].add(delta[i]);
+ if (vert[i].x > max[i].x) {
+ vert[i].x = max[i].x;
+ delta[i].x *= -1.0f;
+ }
+ if (vert[i].x < min[i].x) {
+ vert[i].x = min[i].x;
+ delta[i].x *= -1.0f;
+ }
+ if (vert[i].y > max[i].y) {
+ vert[i].y = max[i].y;
+ delta[i].y *= -1.0f;
+ }
+ if (vert[i].y < min[i].y) {
+ vert[i].y = min[i].y;
+ delta[i].y *= -1.0f;
+ }
+ if (vert[i].z > max[i].z) {
+ vert[i].z = max[i].z;
+ delta[i].z *= -1.0f;
+ }
+ if (vert[i].z < min[i].z) {
+ vert[i].z = min[i].z;
+ delta[i].z *= -1.0f;
+ }
+ }
+ tri.setCoordinates(0, vert);
+ }
+
+ private void computeNormals() {
+ v01.sub(vert[1], vert[0]);
+ v02.sub(vert[2], vert[0]);
+ v03.sub(vert[3], vert[0]);
+ normals[0].cross(v01, v02);
+ normals[0].normalize();
+ normals[1].cross(v02, v03);
+ normals[1].normalize();
+ tri.setNormals(0, normals);
+ }
+
+ public MyCanvas3D(GraphicsConfiguration gcfg) {
+ super(gcfg);
+
+ // Allocate memory for normals
+ normals = new Vector3f[2];
+ normals[0] = new Vector3f();
+ normals[1] = new Vector3f();
+
+ // Set up the indices
+ tri.setCoordinateIndices(0, vertIndices);
+ tri.setNormalIndices(0, normalIndices);
+
+ // Set up the graphics context
+ gc = getGraphicsContext3D();
+
+ // Create the appearance for the triangle fan
+ Appearance app = new Appearance();
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f objColor = new Color3f(0.0f, 0.0f, 0.8f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ white, 80.0f));
+ gc.setAppearance(app);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+ gc.addLight(new AmbientLight(alColor));
+ gc.addLight(new DirectionalLight(lColor1, lDir1));
+ }
+ }
+
+
+ private BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ TextureLoader bgTexture = new TextureLoader(bgImage, this);
+ Background bg = new Background(bgTexture.getImage());
+ bg.setApplicationBounds(bounds);
+ objRoot.addChild(bg);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objRoot.addChild(aLgt);
+ objRoot.addChild(lgt1);
+
+ // Create a bunch of objects with a behavior and add them
+ // into the scene graph.
+
+ int row, col;
+ Appearance[][] app = new Appearance[3][3];
+
+ for (row = 0; row < 3; row++)
+ for (col = 0; col < 3; col++)
+ app[row][col] = createAppearance(row * 3 + col);
+
+ for (int i = 0; i < 3; i++) {
+ double ypos = (double)(i - 1) * 0.6;
+ for (int j = 0; j < 3; j++) {
+ double xpos = (double)(j - 1) * 0.6;
+ objRoot.addChild(createObject(app[i][j], 0.12, xpos, ypos));
+ }
+ }
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+
+ private Appearance createAppearance(int idx) {
+ Appearance app = new Appearance();
+
+ // Globally used colors
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+
+ switch (idx) {
+ // Unlit solid
+ case 0:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(1.0f, 0.2f, 0.4f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+ break;
+ }
+
+
+ // Unlit wire frame
+ case 1:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(0.5f, 0.0f, 0.2f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(pa.POLYGON_LINE);
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+ break;
+ }
+
+ // Unlit points
+ case 2:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(0.2f, 0.2f, 1.0f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(pa.POLYGON_POINT);
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+
+ // Set up point attributes
+ PointAttributes pta = new PointAttributes();
+ pta.setPointSize(5.0f);
+ app.setPointAttributes(pta);
+ break;
+ }
+
+ // Lit solid
+ case 3:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ white, 80.0f));
+ break;
+ }
+
+ // Texture mapped, lit solid
+ case 4:
+ {
+ // Set up the texture map
+ TextureLoader tex = new TextureLoader(texImage, this);
+ app.setTexture(tex.getTexture());
+
+ TextureAttributes texAttr = new TextureAttributes();
+ texAttr.setTextureMode(TextureAttributes.MODULATE);
+ app.setTextureAttributes(texAttr);
+
+
+ // Set up the material properties
+ app.setMaterial(new Material(white, black, white, black, 1.0f));
+ break;
+ }
+
+ // Transparent, lit solid
+ case 5:
+ {
+ // Set up the transparency properties
+ TransparencyAttributes ta = new TransparencyAttributes();
+ ta.setTransparencyMode(ta.BLENDED);
+ ta.setTransparency(0.6f);
+ app.setTransparencyAttributes(ta);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.7f, 0.8f, 1.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ black, 1.0f));
+ break;
+ }
+
+ // Lit solid, no specular
+ case 6:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ black, 80.0f));
+ break;
+ }
+
+ // Lit solid, specular only
+ case 7:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(black, black, black,
+ white, 80.0f));
+ break;
+ }
+
+ // Another lit solid with a different color
+ case 8:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.8f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ white, 80.0f));
+ break;
+ }
+
+ default:
+ {
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(new Color3f(0.0f, 1.0f, 0.0f));
+ app.setColoringAttributes(ca);
+ }
+ }
+
+ return app;
+ }
+
+
+ private Group createObject(Appearance app, double scale,
+ double xpos, double ypos) {
+
+ // Create a transform group node to scale and position the object.
+ Transform3D t = new Transform3D();
+ t.set(scale, new Vector3d(xpos, ypos, 0.0));
+ TransformGroup objTrans = new TransformGroup(t);
+
+ // Create a second transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime.
+ TransformGroup spinTg = new TransformGroup();
+ spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+
+ // Create a simple shape leaf node and set the appearance
+ Shape3D shape = new Tetrahedron();
+ shape.setAppearance(app);
+
+ // add it to the scene graph.
+ spinTg.addChild(shape);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 5000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, spinTg, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ rotator.setSchedulingBounds(bounds);
+
+ // Add the behavior and the transform group to the object
+ objTrans.addChild(rotator);
+ objTrans.addChild(spinTg);
+
+ return objTrans;
+ }
+
+
+ public AppearanceMixed() {
+ }
+
+ public AppearanceMixed(java.net.URL bgurl, java.net.URL texurl) {
+ bgImage = bgurl;
+ texImage = texurl;
+ }
+ public void init() {
+ if (bgImage == null) {
+ // the path to the image for an applet
+ try {
+ bgImage = new java.net.URL(getCodeBase().toString() +
+ "../images/bg.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ if (texImage == null) {
+ // the path to the image for an applet
+ try {
+ texImage = new java.net.URL(getCodeBase().toString() +
+ "../images/apimage.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ MyCanvas3D c = new MyCanvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+ //
+ // The following allows AppearanceMixed to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ // the path to the image file for an application
+ java.net.URL bgurl = null;
+ java.net.URL texurl = null;
+ try {
+ bgurl = new java.net.URL("file:../images/bg.jpg");
+ texurl = new java.net.URL("file:../images/apimage.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ new MainFrame(new AppearanceMixed(bgurl, texurl), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceTest.java b/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceTest.java
new file mode 100644
index 0000000..8d57c48
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceTest.java
@@ -0,0 +1,382 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.appearance;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class AppearanceTest extends Applet {
+
+ private java.net.URL texImage = null;
+ private java.net.URL bgImage = null;
+
+ private SimpleUniverse u = null;
+
+ private BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ TextureLoader bgTexture = new TextureLoader(bgImage, this);
+ Background bg = new Background(bgTexture.getImage());
+ bg.setApplicationBounds(bounds);
+ objRoot.addChild(bg);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objRoot.addChild(aLgt);
+ objRoot.addChild(lgt1);
+
+ // Create a bunch of objects with a behavior and add them
+ // into the scene graph.
+
+ int row, col;
+ Appearance[][] app = new Appearance[3][3];
+
+ for (row = 0; row < 3; row++)
+ for (col = 0; col < 3; col++)
+ app[row][col] = createAppearance(row * 3 + col);
+
+ for (int i = 0; i < 3; i++) {
+ double ypos = (double)(i - 1) * 0.6;
+ for (int j = 0; j < 3; j++) {
+ double xpos = (double)(j - 1) * 0.6;
+ objRoot.addChild(createObject(app[i][j], 0.12, xpos, ypos));
+ }
+ }
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+
+ private Appearance createAppearance(int idx) {
+ Appearance app = new Appearance();
+
+ // Globally used colors
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+
+ switch (idx) {
+ // Unlit solid
+ case 0:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(1.0f, 0.2f, 0.4f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+ break;
+ }
+
+
+ // Unlit wire frame
+ case 1:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(0.5f, 0.0f, 0.2f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(pa.POLYGON_LINE);
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+ break;
+ }
+
+ // Unlit points
+ case 2:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(0.2f, 0.2f, 1.0f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(pa.POLYGON_POINT);
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+
+ // Set up point attributes
+ PointAttributes pta = new PointAttributes();
+ pta.setPointSize(5.0f);
+ app.setPointAttributes(pta);
+ break;
+ }
+
+ // Lit solid
+ case 3:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ white, 80.0f));
+ break;
+ }
+
+ // Texture mapped, lit solid
+ case 4:
+ {
+ // Set up the texture map
+ TextureLoader tex = new TextureLoader(texImage, this);
+ app.setTexture(tex.getTexture());
+
+ TextureAttributes texAttr = new TextureAttributes();
+ texAttr.setTextureMode(TextureAttributes.MODULATE);
+ app.setTextureAttributes(texAttr);
+
+ // Set up the material properties
+ app.setMaterial(new Material(white, black, white, black, 1.0f));
+ break;
+ }
+
+ // Transparent, lit solid
+ case 5:
+ {
+ // Set up the transparency properties
+ TransparencyAttributes ta = new TransparencyAttributes();
+ ta.setTransparencyMode(ta.BLENDED);
+ ta.setTransparency(0.6f);
+ app.setTransparencyAttributes(ta);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.7f, 0.8f, 1.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ black, 1.0f));
+ break;
+ }
+
+ // Lit solid, no specular
+ case 6:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ black, 80.0f));
+ break;
+ }
+
+ // Lit solid, specular only
+ case 7:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(black, black, black,
+ white, 80.0f));
+ break;
+ }
+
+ // Another lit solid with a different color
+ case 8:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.8f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ white, 80.0f));
+ break;
+ }
+
+ default:
+ {
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(new Color3f(0.0f, 1.0f, 0.0f));
+ app.setColoringAttributes(ca);
+ }
+ }
+
+ return app;
+ }
+
+
+ private Group createObject(Appearance app, double scale,
+ double xpos, double ypos) {
+
+ // Create a transform group node to scale and position the object.
+ Transform3D t = new Transform3D();
+ t.set(scale, new Vector3d(xpos, ypos, 0.0));
+ TransformGroup objTrans = new TransformGroup(t);
+
+ // Create a second transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime.
+ TransformGroup spinTg = new TransformGroup();
+ spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+
+ // Create a simple shape leaf node and set the appearance
+ Shape3D shape = new Tetrahedron();
+ shape.setAppearance(app);
+
+ // add it to the scene graph.
+ spinTg.addChild(shape);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 5000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, spinTg, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ rotator.setSchedulingBounds(bounds);
+
+ // Add the behavior and the transform group to the object
+ objTrans.addChild(rotator);
+ objTrans.addChild(spinTg);
+
+ return objTrans;
+ }
+
+
+ public AppearanceTest() {
+ }
+
+ public AppearanceTest(java.net.URL bgurl, java.net.URL texurl) {
+ bgImage = bgurl;
+ texImage = texurl;
+ }
+
+ public void init() {
+ if (bgImage == null) {
+ // the path to the image for an applet
+ try {
+ bgImage = new java.net.URL(getCodeBase().toString() +
+ "../images/bg.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ if (texImage == null) {
+ // the path to the image for an applet
+ try {
+ texImage = new java.net.URL(getCodeBase().toString() +
+ "../images/apimage.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+ //
+ // The following allows AppearanceTest to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ // the path to the image file for an application
+ java.net.URL bgurl = null;
+ java.net.URL texurl = null;
+ try {
+ bgurl = new java.net.URL("file:../images/bg.jpg");
+ texurl = new java.net.URL("file:../images/apimage.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ new MainFrame(new AppearanceTest(bgurl, texurl), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/appearance/Tetrahedron.java b/src/classes/org/jdesktop/j3d/examples/appearance/Tetrahedron.java
new file mode 100644
index 0000000..af67321
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/appearance/Tetrahedron.java
@@ -0,0 +1,109 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.appearance;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Tetrahedron extends Shape3D {
+ private static final float sqrt3 = (float) Math.sqrt(3.0);
+ private static final float sqrt3_3 = sqrt3 / 3.0f;
+ private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;
+
+ private static final float ycenter = 0.5f * sqrt24_3;
+ private static final float zcenter = -sqrt3_3;
+
+ private static final Point3f p1 = new Point3f(-1.0f, -ycenter, -zcenter);
+ private static final Point3f p2 = new Point3f(1.0f, -ycenter, -zcenter);
+ private static final Point3f p3 =
+ new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
+ private static final Point3f p4 =
+ new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);
+
+ private static final Point3f[] verts = {
+ p1, p2, p4, // front face
+ p1, p4, p3, // left, back face
+ p2, p3, p4, // right, back face
+ p1, p3, p2, // bottom face
+ };
+
+ private TexCoord2f texCoord[] = {
+ new TexCoord2f(0.0f, 0.0f),
+ new TexCoord2f(1.0f, 0.0f),
+ new TexCoord2f(0.5f, sqrt3 / 2.0f),
+ };
+
+ public Tetrahedron() {
+ int i;
+
+ TriangleArray tetra = new TriangleArray(12, TriangleArray.COORDINATES |
+ TriangleArray.NORMALS | TriangleArray.TEXTURE_COORDINATE_2);
+
+ tetra.setCoordinates(0, verts);
+ for (i = 0; i < 12; i++) {
+ tetra.setTextureCoordinate(0, i, texCoord[i%3]);
+ }
+
+ int face;
+ Vector3f normal = new Vector3f();
+ Vector3f v1 = new Vector3f();
+ Vector3f v2 = new Vector3f();
+ Point3f [] pts = new Point3f[3];
+ for (i = 0; i < 3; i++) pts[i] = new Point3f();
+
+ for (face = 0; face < 4; face++) {
+ tetra.getCoordinates(face*3, pts);
+ v1.sub(pts[1], pts[0]);
+ v2.sub(pts[2], pts[0]);
+ normal.cross(v1, v2);
+ normal.normalize();
+ for (i = 0; i < 3; i++) {
+ tetra.setNormal((face * 3 + i), normal);
+ }
+ }
+ this.setGeometry(tetra);
+ this.setAppearance(new Appearance());
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.html b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.html
new file mode 100644
index 0000000..8ab3a5d
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.html
@@ -0,0 +1,15 @@
+<HTML>
+<HEAD>
+<TITLE>Hello, Universe</TITLE>
+</HEAD>
+<BODY BGCOLOR="#000000">
+<applet align=middle code="Applet3D.class" width=256 height=256>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Applet3D instead of this paragraph.
+<hr>
+</blockquote>
+</applet>
+</BODY>
+</HTML>
diff --git a/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.java b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.java
new file mode 100644
index 0000000..9abecd9
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.java
@@ -0,0 +1,129 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.applet3d;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.event.*;
+import java.awt.GraphicsConfiguration;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Applet3D extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create the TransformGroup node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at run time. Add it to
+ // the root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // Create a simple Shape3D node; add it to the scene graph.
+ objTrans.addChild(new ColorCube(0.4));
+
+ // Create a new Behavior object that will perform the
+ // desired operation on the specified transform and add
+ // it into the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, 4000);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objRoot.addChild(rotator);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public Applet3D() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows Applet3D to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new Applet3D(), 256, 256);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D_plugin.html b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D_plugin.html
new file mode 100644
index 0000000..e47eecc
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D_plugin.html
@@ -0,0 +1,39 @@
+<HTML>
+<HEAD>
+<TITLE>Hello, Universe!</TITLE>
+</HEAD>
+<BODY BGCOLOR="#000000">
+<!--"CONVERTED_APPLET"-->
+<!-- CONVERTER VERSION 1.3 -->
+<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+WIDTH = 256 HEIGHT = 256 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
+<PARAM NAME = CODE VALUE = "Applet3D.class" >
+
+<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2">
+<PARAM NAME="scriptable" VALUE="false">
+<COMMENT>
+<EMBED type="application/x-java-applet;version=1.2.2" CODE = "Applet3D.class" WIDTH = 256 HEIGHT = 256 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+</NOEMBED></EMBED>
+</OBJECT>
+
+<!--
+<APPLET CODE = "Applet3D.class" WIDTH = 256 HEIGHT = 256 ALIGN = middle>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+
+</APPLET>
+-->
+<!--"END_CONVERTED_APPLET"-->
+
+</BODY>
+</HTML>
diff --git a/src/classes/org/jdesktop/j3d/examples/background/BackgroundGeometry.java b/src/classes/org/jdesktop/j3d/examples/background/BackgroundGeometry.java
new file mode 100644
index 0000000..e6ea23c
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/background/BackgroundGeometry.java
@@ -0,0 +1,238 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.background;
+
+import com.sun.j3d.utils.image.TextureLoader;
+import com.sun.j3d.utils.behaviors.mouse.*;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class BackgroundGeometry extends Applet {
+
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ private java.net.URL bgImage = null;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime.
+ TransformGroup objTrans = new TransformGroup();
+ objScale.addChild(objTrans);
+
+ Background bg = new Background();
+ bg.setApplicationBounds(bounds);
+ BranchGroup backGeoBranch = new BranchGroup();
+ Sphere sphereObj = new Sphere(1.0f, Sphere.GENERATE_NORMALS |
+ Sphere.GENERATE_NORMALS_INWARD |
+ Sphere.GENERATE_TEXTURE_COORDS, 45);
+ Appearance backgroundApp = sphereObj.getAppearance();
+ backGeoBranch.addChild(sphereObj);
+ bg.setGeometry(backGeoBranch);
+ objTrans.addChild(bg);
+
+ TextureLoader tex = new TextureLoader(bgImage,
+ new String("RGB"), this);
+ if (tex != null)
+ backgroundApp.setTexture(tex.getTexture());
+
+ Vector3f tranlation = new Vector3f(2.0f, 0.0f, 0.0f);
+ Transform3D modelTransform = new Transform3D();
+ Transform3D tmpTransform = new Transform3D();
+ double angleInc = Math.PI/8.0;
+ double angle = 0.0;
+ int numBoxes = 16;
+
+ float scaleX[] = {0.1f, 0.2f, 0.2f, 0.3f,
+ 0.2f, 0.1f, 0.2f, 0.3f,
+ 0.1f, 0.3f, 0.2f, 0.3f,
+ 0.1f, 0.3f, 0.2f, 0.3f};
+
+ float scaleY[] = {0.3f, 0.4f, 0.3f, 0.4f,
+ 0.3f, 0.4f, 0.3f, 0.4f,
+ 0.3f, 0.3f, 0.3f, 0.3f,
+ 0.3f, 0.3f, 0.3f, 0.4f};
+
+ float scaleZ[] = {0.3f, 0.2f, 0.1f, 0.1f,
+ 0.3f, 0.2f, 0.1f, 0.3f,
+ 0.3f, 0.2f, 0.1f, 0.3f,
+ 0.3f, 0.2f, 0.1f, 0.2f};
+
+ Appearance a1 = new Appearance();
+ Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f sColor = new Color3f(0.5f, 0.5f, 1.0f);
+ Color3f oColor = new Color3f(0.5f, 0.5f, 0.3f);
+
+ Material m = new Material(oColor, eColor, oColor, sColor, 100.0f);
+ m.setLightingEnable(true);
+ a1.setMaterial(m);
+
+ for (int i=0; i<numBoxes; i++, angle += angleInc) {
+ modelTransform.rotY(angle);
+ tmpTransform.set(tranlation);
+ modelTransform.mul(tmpTransform);
+
+ TransformGroup tgroup = new TransformGroup(modelTransform);
+ objTrans.addChild(tgroup);
+
+ tgroup.addChild( new Box(scaleX[i],scaleY[i],scaleZ[i],
+ Box.GENERATE_NORMALS,a1));
+ }
+
+
+ // Shine it with two lights.
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Color3f lColor2 = new Color3f(0.2f, 0.2f, 0.1f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Vector3f lDir2 = new Vector3f(0.0f, 0.0f, -1.0f);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+ objScale.addChild(lgt1);
+ objScale.addChild(lgt2);
+
+
+ return objRoot;
+ }
+
+ public BackgroundGeometry (){
+ }
+
+ public BackgroundGeometry(java.net.URL bgurl) {
+ bgImage = bgurl;
+ }
+
+ public void init() {
+
+ if (bgImage == null) {
+ // the path to the image for an applet
+ try {
+ bgImage = new java.net.URL(getCodeBase().toString() +
+ "../images/bg.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ TransformGroup viewTrans =
+ u.getViewingPlatform().getViewPlatformTransform();
+
+ // Create the rotate behavior node
+ MouseRotate behavior1 = new MouseRotate(viewTrans);
+ scene.addChild(behavior1);
+ behavior1.setSchedulingBounds(bounds);
+
+ // Create the zoom behavior node
+ MouseZoom behavior2 = new MouseZoom(viewTrans);
+ scene.addChild(behavior2);
+ behavior2.setSchedulingBounds(bounds);
+
+ // Create the translate behavior node
+ MouseTranslate behavior3 = new MouseTranslate(viewTrans);
+ scene.addChild(behavior3);
+ behavior3.setSchedulingBounds(bounds);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ scene.compile();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public static void main(String argv[]) {
+ System.out.println("Usage: mouse buttons to rotate, zoom or translate the view platform transform");
+ System.out.println(" Note that the background geometry only changes with rotation");
+ // the path to the image file for an application
+ java.net.URL bgurl = null;
+ try {
+ bgurl = new java.net.URL("file:../images/bg.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ new MainFrame(new BackgroundGeometry(bgurl), 750, 750);
+ }
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/cg_shader/ObjLoadCg.java b/src/classes/org/jdesktop/j3d/examples/cg_shader/ObjLoadCg.java
new file mode 100644
index 0000000..02d02a1
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/cg_shader/ObjLoadCg.java
@@ -0,0 +1,345 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.cg_shader;
+
+import com.sun.j3d.loaders.objectfile.ObjectFile;
+import com.sun.j3d.loaders.ParsingErrorException;
+import com.sun.j3d.loaders.IncorrectFormatException;
+import com.sun.j3d.loaders.Scene;
+import com.sun.j3d.utils.shader.StringIO;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+import java.io.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+public class ObjLoadCg extends Applet {
+
+ private boolean spin = false;
+ private boolean noTriangulate = false;
+ private boolean noStripify = false;
+ private double creaseAngle = 60.0;
+ private URL filename = null;
+ private SimpleUniverse u;
+ private BoundingSphere bounds;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.7);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(objTrans);
+
+ int flags = ObjectFile.RESIZE;
+ if (!noTriangulate) flags |= ObjectFile.TRIANGULATE;
+ if (!noStripify) flags |= ObjectFile.STRIPIFY;
+ ObjectFile f = new ObjectFile(flags,
+ (float)(creaseAngle * Math.PI / 180.0));
+ Scene s = null;
+ try {
+ s = f.load(filename);
+ }
+ catch (FileNotFoundException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ catch (ParsingErrorException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ catch (IncorrectFormatException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ // Set vertex and fragment shader program for all Shape3D nodes in scene
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try {
+ vertexProgram = StringIO.readFully("./simple_vp.cg");
+ fragmentProgram = StringIO.readFully("./simple_fp.cg");
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_CG,
+ Shader.SHADER_TYPE_VERTEX,
+ vertexProgram);
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_CG,
+ Shader.SHADER_TYPE_FRAGMENT,
+ fragmentProgram);
+ ShaderProgram shaderProgram = new CgShaderProgram();
+ shaderProgram.setShaders(shaders);
+ setShaderProgram(s.getSceneGroup(), shaderProgram);
+
+ objTrans.addChild(s.getSceneGroup());
+
+ bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ if (spin) {
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+ }
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objRoot.addChild(bgNode);
+
+ return objRoot;
+ }
+
+ private void usage()
+ {
+ System.out.println(
+ "Usage: java ObjLoadCg [-s] [-n] [-t] [-c degrees] <.obj file>");
+ System.out.println(" -s Spin (no user interaction)");
+ System.out.println(" -n No triangulation");
+ System.out.println(" -t No stripification");
+ System.out.println(
+ " -c Set crease angle for normal generation (default is 60 without");
+ System.out.println(
+ " smoothing group info, otherwise 180 within smoothing groups)");
+ System.exit(0);
+ } // End of usage
+
+
+
+ public void init() {
+ if (filename == null) {
+ // Applet
+ try {
+ URL path = getCodeBase();
+ filename = new URL(path.toString() + "./galleon.obj");
+ }
+ catch (MalformedURLException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ PlatformGeometry pg = new PlatformGeometry();
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ pg.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 0.2f, 0.4f);
+ Vector3f light1Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light2Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ pg.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ pg.addChild(light2);
+
+ viewingPlatform.setPlatformGeometry( pg );
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ if (!spin) {
+ OrbitBehavior orbit = new OrbitBehavior(c,
+ OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+ }
+
+ /*
+ // Limit the frame rate to 100 Hz
+ u.getViewer().getView().setMinimumFrameCycleTime(10);
+ */
+
+ u.addBranchGraph(scene);
+ }
+
+ // Set shader program for all nodes in specified branch graph
+ private void setShaderProgram(BranchGroup g, ShaderProgram shaderProgram) {
+ ShaderAppearance myApp = new ShaderAppearance();
+ Material mat = new Material();
+ Texture2D tex2d = new Texture2D();
+ myApp.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
+ myApp.setShaderProgram(shaderProgram);
+ myApp.setMaterial(mat);
+ myApp.setTexture(tex2d);
+ setShaderProgram(g, myApp);
+ }
+
+ // Recursively set shader program for all children of specified group
+ private void setShaderProgram(Group g,
+ ShaderAppearance myApp) {
+
+ Enumeration e = g.getAllChildren();
+ while (e.hasMoreElements()) {
+ Node n = (Node)(e.nextElement());
+ if (n instanceof Group) {
+ setShaderProgram((Group)n, myApp);
+ }
+ else if (n instanceof Shape3D) {
+ Shape3D s = (Shape3D)n;
+ s.setAppearance(myApp);
+ }
+ }
+ }
+
+ // Caled if running as a program
+ public ObjLoadCg(String[] args) {
+ if (args.length != 0) {
+ for (int i = 0 ; i < args.length ; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].equals("-s")) {
+ spin = true;
+ } else if (args[i].equals("-n")) {
+ noTriangulate = true;
+ } else if (args[i].equals("-t")) {
+ noStripify = true;
+ } else if (args[i].equals("-c")) {
+ if (i < args.length - 1) {
+ creaseAngle = (new Double(args[++i])).doubleValue();
+ } else usage();
+ } else {
+ usage();
+ }
+ } else {
+ try {
+ if ((args[i].indexOf("file:") == 0) ||
+ (args[i].indexOf("http") == 0)) {
+ filename = new URL(args[i]);
+ }
+ else if (args[i].charAt(0) != '/') {
+ filename = new URL("file:./" + args[i]);
+ }
+ else {
+ filename = new URL("file:" + args[i]);
+ }
+ }
+ catch (MalformedURLException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ // Running as an applet
+ public ObjLoadCg() {
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+
+ //
+ // The following allows ObjLoadCg to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new ObjLoadCg(args), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/cg_shader/SphereCg.java b/src/classes/org/jdesktop/j3d/examples/cg_shader/SphereCg.java
new file mode 100644
index 0000000..2757006
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/cg_shader/SphereCg.java
@@ -0,0 +1,348 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.cg_shader;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.io.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.shader.StringIO;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+/**
+ * Simple CG Shader test program
+ */
+public class SphereCg extends Applet {
+
+ // Constants for type of light to use
+ private static final int DIRECTIONAL_LIGHT = 0;
+ private static final int POINT_LIGHT = 1;
+ private static final int SPOT_LIGHT = 2;
+
+ // Flag indicates type of lights: directional, point, or spot
+ // lights. This flag is set based on command line argument
+ private static int lightType = DIRECTIONAL_LIGHT;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(SimpleUniverse u) {
+ Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f);
+ Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+
+ Transform3D t;
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ // Create a Sphere object, generate one copy of the sphere,
+ // and add it into the scene graph.
+ ShaderAppearance a = new ShaderAppearance();
+ Material m = new Material(objColor, eColor, objColor, sColor, 100.0f);
+ m.setLightingEnable(true);
+ Texture t2d = new Texture2D();
+ a.setTexture(t2d);
+ a.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
+
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try {
+ vertexProgram = StringIO.readFully("./simple_vp.cg");
+ fragmentProgram = StringIO.readFully("./simple_fp.cg");
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_CG,
+ Shader.SHADER_TYPE_VERTEX,
+ vertexProgram);
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_CG,
+ Shader.SHADER_TYPE_FRAGMENT,
+ fragmentProgram);
+ ShaderProgram shaderProgram = new CgShaderProgram();
+ shaderProgram.setShaders(shaders);
+
+ a.setShaderProgram(shaderProgram);
+ a.setMaterial(m);
+ Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS, 200, a);
+ objScale.addChild(sph);
+
+ // Create the transform group node for the each light and initialize
+ // it to the identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add them to the root
+ // of the subgraph.
+ TransformGroup l1RotTrans = new TransformGroup();
+ l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(l1RotTrans);
+
+ TransformGroup l2RotTrans = new TransformGroup();
+ l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(l2RotTrans);
+
+ // Create transformations for the positional lights
+ t = new Transform3D();
+ Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0);
+ t.set(lPos1);
+ TransformGroup l1Trans = new TransformGroup(t);
+ l1RotTrans.addChild(l1Trans);
+
+ t = new Transform3D();
+ Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0);
+ t.set(lPos2);
+ TransformGroup l2Trans = new TransformGroup(t);
+ l2RotTrans.addChild(l2Trans);
+
+ /*
+ // Create Geometry for point lights
+ ColoringAttributes caL1 = new ColoringAttributes();
+ ColoringAttributes caL2 = new ColoringAttributes();
+ caL1.setColor(lColor1);
+ caL2.setColor(lColor2);
+ Appearance appL1 = new Appearance();
+ Appearance appL2 = new Appearance();
+ appL1.setColoringAttributes(caL1);
+ appL2.setColoringAttributes(caL2);
+ l1Trans.addChild(new Sphere(0.05f, appL1));
+ l2Trans.addChild(new Sphere(0.05f, appL2));
+ */
+
+ // Create lights
+ AmbientLight aLgt = new AmbientLight(alColor);
+
+ Light lgt1 = null;
+ Light lgt2 = null;
+
+ Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f atten = new Point3f(1.0f, 0.0f, 0.0f);
+ Vector3f lDirect1 = new Vector3f(lPos1);
+ Vector3f lDirect2 = new Vector3f(lPos2);
+ lDirect1.negate();
+ lDirect2.negate();
+
+ switch (lightType) {
+ case DIRECTIONAL_LIGHT:
+ lgt1 = new DirectionalLight(lColor1, lDirect1);
+ lgt2 = new DirectionalLight(lColor2, lDirect2);
+ break;
+ case POINT_LIGHT:
+ lgt1 = new PointLight(lColor1, lPoint, atten);
+ lgt2 = new PointLight(lColor2, lPoint, atten);
+ break;
+ case SPOT_LIGHT:
+ lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1,
+ 25.0f * (float)Math.PI / 180.0f, 10.0f);
+ lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2,
+ 25.0f * (float)Math.PI / 180.0f, 10.0f);
+ break;
+ }
+
+ // Set the influencing bounds
+ aLgt.setInfluencingBounds(bounds);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+
+ // Add the lights into the scene graph
+ objScale.addChild(aLgt);
+ l1Trans.addChild(lgt1);
+ l2Trans.addChild(lgt2);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator1 =
+ new RotationInterpolator(rotor1Alpha,
+ l1RotTrans,
+ yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator1.setSchedulingBounds(bounds);
+ l1RotTrans.addChild(rotator1);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Alpha rotor2Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 1000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator2 =
+ new RotationInterpolator(rotor2Alpha,
+ l2RotTrans,
+ yAxis,
+ 0.0f, 0.0f);
+ bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator2.setSchedulingBounds(bounds);
+ l2RotTrans.addChild(rotator2);
+
+ // Create a position interpolator and attach it to the view
+ // platform
+ TransformGroup vpTrans =
+ u.getViewingPlatform().getViewPlatformTransform();
+ Transform3D axisOfTranslation = new Transform3D();
+ Alpha transAlpha = new Alpha(-1,
+ Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 5000, 0, 0,
+ 5000, 0, 0);
+ axisOfTranslation.rotY(-Math.PI/2.0);
+ PositionInterpolator translator =
+ new PositionInterpolator(transAlpha,
+ vpTrans,
+ axisOfTranslation,
+ 2.0f, 3.5f);
+ translator.setSchedulingBounds(bounds);
+ objScale.addChild(translator);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public SphereCg() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ u = new SimpleUniverse(c);
+ BranchGroup scene = createSceneGraph(u);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ /*
+ // Limit the frame rate to 100 Hz
+ u.getViewer().getView().setMinimumFrameCycleTime(10);
+ */
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows SphereCg to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ // Parse the Input Arguments
+ String usage = "Usage: java SphereCg [-point | -spot | -dir]";
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].equals("-point")) {
+ /*
+ System.out.println("Using point lights");
+ lightType = POINT_LIGHT;
+ */
+ System.out.println("Point lights not yet implemented, option ignored");
+ }
+ else if (args[i].equals("-spot")) {
+ /*
+ System.out.println("Using spot lights");
+ lightType = SPOT_LIGHT;
+ */
+ System.out.println("Spot lights not yet implemented, option ignored");
+ }
+ else if (args[i].equals("-dir")) {
+ System.out.println("Using directional lights");
+ lightType = DIRECTIONAL_LIGHT;
+ }
+ else {
+ System.out.println(usage);
+ System.exit(0);
+ }
+ }
+ else {
+ System.out.println(usage);
+ System.exit(0);
+ }
+ }
+
+ new MainFrame(new SphereCg(), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_fp.cg b/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_fp.cg
new file mode 100644
index 0000000..e9cd44b
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_fp.cg
@@ -0,0 +1,68 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+// Simple fragment program to attenuate the input fragment color as a
+// function of the distance of the fragment position from the center
+// of the window
+
+// define inputs from vertex shader to fragment shader
+struct vertin
+{
+ float4 HPosition : POSITION;
+ float4 FragPos : TEXCOORD0;
+ float4 Color0 : COLOR0;
+};
+
+float4 main(vertin IN) : COLOR
+{
+ // Compute distance from center in range [0.0, 1.0]
+ float2 dist = min(abs(IN.FragPos.xy), 1.0f);
+ float2 invDist = 1.0f - dist;
+
+ // Compute attenuation
+ float atten = invDist.x * invDist.y;
+ float4 outcolor = float4(IN.Color0 * atten);
+
+ return outcolor;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_vp.cg b/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_vp.cg
new file mode 100644
index 0000000..d030818
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_vp.cg
@@ -0,0 +1,167 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*********************************************************************NVMH3****
+Path: NVSDK\Common\media\programs
+File: simple.cg
+
+Copyright NVIDIA Corporation 2002
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
+BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
+WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
+BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
+ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+Comments:
+
+******************************************************************************/
+
+// Simple vertex shader, derived from NVIDIA's simple.cg sample
+// shader, that modulates the lit color with a noise pattern based on
+// vertex position.
+
+// define inputs from application
+struct appin
+{
+ float4 Position : POSITION;
+ float4 Normal : NORMAL;
+};
+
+// define outputs from vertex shader
+struct vertout
+{
+ float4 HPosition : POSITION;
+ float4 FragPos : TEXCOORD0;
+ float4 Color0 : COLOR0;
+};
+
+vertout main(appin IN,
+ uniform float4x4 ModelViewProj,
+ uniform float4x4 ModelViewIT,
+ uniform float4 LightVec,
+ uniform float4 LightColor,
+ uniform float4 DiffuseMaterial,
+ uniform float4 SpecularMaterial)
+{
+ vertout OUT;
+
+// Assume that the profile is PROFILE_ARBVP1...
+// #ifdef PROFILE_ARBVP1
+ ModelViewProj = glstate.matrix.mvp;
+ ModelViewIT = glstate.matrix.invtrans.modelview[0];
+ LightVec = glstate.light[0].position;
+ LightColor = glstate.light[0].diffuse;
+ DiffuseMaterial = glstate.material.front.diffuse;
+ SpecularMaterial = glstate.material.front.specular;
+// #endif
+
+ // transform vertex position into homogenous clip-space
+ OUT.HPosition = mul(ModelViewProj, IN.Position);
+
+ // Output the post-perspective-divide position as FragPos
+ float invW = 1.0f / OUT.HPosition.w;
+ OUT.FragPos = OUT.HPosition * invW;
+
+ // transform normal from model-space to view-space
+ float3 normalVec = normalize(mul(ModelViewIT, IN.Normal).xyz);
+
+ // store normalized light vector
+ float3 lightVec = normalize(LightVec.xyz);
+
+ // calculate half angle vector
+ float3 eyeVec = float3(0.0, 0.0, 1.0);
+ float3 halfVec = normalize(lightVec + eyeVec);
+
+ // calculate diffuse component
+ float diffuse = dot(normalVec, lightVec);
+
+ // calculate specular component
+ float specular = dot(normalVec, halfVec);
+
+ // The lit() function is a handy function in the standard library that
+ // can be used to accelerate your lighting calculations.
+ //
+ // This function return a vector containing these values:
+ // result.x = 1.0;
+ // result.y = max(diffuse, 0);
+ // result.z = if (result.y > 0.0) then pow(specular, 32) else 0.0
+ // result.w = 1.0;
+
+ // Use the lit function to compute lighting vector from diffuse and
+ // specular values
+ float4 lighting = lit(diffuse, specular, 32);
+
+ // combine diffuse and specular contributions
+ float3 color0 = (lighting.y * DiffuseMaterial.xyz * LightColor.xyz) +
+ (lighting.z * SpecularMaterial.xyz);
+
+ // Generate a pseudo-random noise pattern
+// float3 xyz = clamp((normalVec.xyz + 1.0) * 0.5, 0.0, 1.0);
+ float3 xyz = clamp((OUT.HPosition.xyz + 1.0) * 0.5, 0.0, 1.0);
+
+ xyz = frac(xyz * 262144.0);
+ float randSeed = frac(3.0 * xyz.x + 5.0 * xyz.y + 7.0 * xyz.z);
+
+ float3 altColor;
+
+ randSeed = frac(37.0 * randSeed);
+ altColor.x = randSeed * 0.5 + 0.5;
+ randSeed = frac(37.0 * randSeed);
+ altColor.y = randSeed * 0.5 + 0.5;
+ randSeed = frac(37.0 * randSeed);
+ altColor.z = randSeed * 0.5 + 0.5;
+ randSeed = frac(37.0 * randSeed);
+ float altAlpha = randSeed * 0.5;
+
+ // Apply noise and output final vertex color
+ OUT.Color0.rgb = lerp(color0, altColor, altAlpha);
+ OUT.Color0.a = 1.0;
+
+ return OUT;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/collision/Box.java b/src/classes/org/jdesktop/j3d/examples/collision/Box.java
new file mode 100644
index 0000000..db39e1d
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/collision/Box.java
@@ -0,0 +1,100 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.collision;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Box extends Shape3D {
+
+ public Box(double xsize, double ysize, double zsize) {
+ super();
+ double xmin = -xsize/2.0;
+ double xmax = xsize/2.0;
+ double ymin = -ysize/2.0;
+ double ymax = ysize/2.0;
+ double zmin = -zsize/2.0;
+ double zmax = zsize/2.0;
+
+ QuadArray box = new QuadArray(24, QuadArray.COORDINATES);
+
+ Point3d verts[] = new Point3d[24];
+
+ // front face
+ verts[0] = new Point3d(xmax, ymin, zmax);
+ verts[1] = new Point3d(xmax, ymax, zmax);
+ verts[2] = new Point3d(xmin, ymax, zmax);
+ verts[3] = new Point3d(xmin, ymin, zmax);
+ // back face
+ verts[4] = new Point3d(xmin, ymin, zmin);
+ verts[5] = new Point3d(xmin, ymax, zmin);
+ verts[6] = new Point3d(xmax, ymax, zmin);
+ verts[7] = new Point3d(xmax, ymin, zmin);
+ // right face
+ verts[8] = new Point3d(xmax, ymin, zmin);
+ verts[9] = new Point3d(xmax, ymax, zmin);
+ verts[10] = new Point3d(xmax, ymax, zmax);
+ verts[11] = new Point3d(xmax, ymin, zmax);
+ // left face
+ verts[12] = new Point3d(xmin, ymin, zmax);
+ verts[13] = new Point3d(xmin, ymax, zmax);
+ verts[14] = new Point3d(xmin, ymax, zmin);
+ verts[15] = new Point3d(xmin, ymin, zmin);
+ // top face
+ verts[16] = new Point3d(xmax, ymax, zmax);
+ verts[17] = new Point3d(xmax, ymax, zmin);
+ verts[18] = new Point3d(xmin, ymax, zmin);
+ verts[19] = new Point3d(xmin, ymax, zmax);
+ // bottom face
+ verts[20] = new Point3d(xmin, ymin, zmax);
+ verts[21] = new Point3d(xmin, ymin, zmin);
+ verts[22] = new Point3d(xmax, ymin, zmin);
+ verts[23] = new Point3d(xmax, ymin, zmax);
+
+ box.setCoordinates(0, verts);
+ setGeometry(box);
+ setAppearance(new Appearance());
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/collision/CollisionDetector.java b/src/classes/org/jdesktop/j3d/examples/collision/CollisionDetector.java
new file mode 100644
index 0000000..935b146
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/collision/CollisionDetector.java
@@ -0,0 +1,92 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.collision;
+
+import java.util.Enumeration;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class CollisionDetector extends Behavior {
+ private static final Color3f highlightColor =
+ new Color3f(0.0f, 1.0f, 0.0f);
+ private static final ColoringAttributes highlight =
+ new ColoringAttributes(highlightColor,
+ ColoringAttributes.SHADE_GOURAUD);
+
+ private boolean inCollision = false;
+ private Shape3D shape;
+ private ColoringAttributes shapeColoring;
+ private Appearance shapeAppearance;
+
+ private WakeupOnCollisionEntry wEnter;
+ private WakeupOnCollisionExit wExit;
+
+
+ public CollisionDetector(Shape3D s) {
+ shape = s;
+ shapeAppearance = shape.getAppearance();
+ shapeColoring = shapeAppearance.getColoringAttributes();
+ inCollision = false;
+ }
+
+ public void initialize() {
+ wEnter = new WakeupOnCollisionEntry(shape);
+ wExit = new WakeupOnCollisionExit(shape);
+ wakeupOn(wEnter);
+ }
+
+ public void processStimulus(Enumeration criteria) {
+ inCollision = !inCollision;
+
+ if (inCollision) {
+ shapeAppearance.setColoringAttributes(highlight);
+ wakeupOn(wExit);
+ }
+ else {
+ shapeAppearance.setColoringAttributes(shapeColoring);
+ wakeupOn(wEnter);
+ }
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/collision/TickTockCollision.java b/src/classes/org/jdesktop/j3d/examples/collision/TickTockCollision.java
new file mode 100644
index 0000000..731dff7
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/collision/TickTockCollision.java
@@ -0,0 +1,219 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.collision;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class TickTockCollision extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and behaviors
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ // Create a pair of transform group nodes and initialize them to
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behaviors can modify them at runtime. Add them to the
+ // root of the subgraph.
+ TransformGroup objTrans1 = new TransformGroup();
+ objTrans1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(objTrans1);
+
+ TransformGroup objTrans2 = new TransformGroup();
+ objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans1.addChild(objTrans2);
+
+ // Create the positioning and scaling transform group node.
+ Transform3D t = new Transform3D();
+ t.set(0.3, new Vector3d(0.0, -1.5, 0.0));
+ TransformGroup objTrans3 = new TransformGroup(t);
+ objTrans2.addChild(objTrans3);
+
+ // Create a simple shape leaf node, add it to the scene graph.
+ objTrans3.addChild(new ColorCube());
+
+ // Create a new Behavior object that will perform the desired
+ // rotation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis1 = new Transform3D();
+ yAxis1.rotX(Math.PI/2.0);
+ Alpha tickTockAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 5000, 2500, 200,
+ 5000, 2500, 200);
+
+ RotationInterpolator tickTock =
+ new RotationInterpolator(tickTockAlpha, objTrans1, yAxis1,
+ -(float) Math.PI/2.0f,
+ (float) Math.PI/2.0f);
+ tickTock.setSchedulingBounds(bounds);
+ objTrans2.addChild(tickTock);
+
+ // Create a new Behavior object that will perform the desired
+ // rotation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis2 = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans2, yAxis2,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans2.addChild(rotator);
+
+ // Now create a pair of rectangular boxes, each with a collision
+ // detection behavior attached. The behavior will highlight the
+ // object when it is in a state of collision.
+
+ Group box1 = createBox(0.3, new Vector3d(-1.3, 0.0, 0.0));
+ Group box2 = createBox(0.3, new Vector3d( 1.3, 0.0, 0.0));
+
+ objScale.addChild(box1);
+ objScale.addChild(box2);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+
+ private Group createBox(double scale, Vector3d pos) {
+ // Create a transform group node to scale and position the object.
+ Transform3D t = new Transform3D();
+ t.set(scale, pos);
+ TransformGroup objTrans = new TransformGroup(t);
+
+ // Create a simple shape leaf node and add it to the scene graph
+ Shape3D shape = new Box(0.5, 5.0, 1.0);
+ objTrans.addChild(shape);
+
+ // Create a new ColoringAttributes object for the shape's
+ // appearance and make it writable at runtime.
+ Appearance app = shape.getAppearance();
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(0.6f, 0.3f, 0.0f);
+ app.setCapability(app.ALLOW_COLORING_ATTRIBUTES_WRITE);
+ app.setColoringAttributes(ca);
+
+ // Create a new Behavior object that will perform the collision
+ // detection on the specified object, and add it into
+ // the scene graph.
+ CollisionDetector cd = new CollisionDetector(shape);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ cd.setSchedulingBounds(bounds);
+
+ // Add the behavior to the scene graph
+ objTrans.addChild(cd);
+
+ return objTrans;
+ }
+
+
+ public TickTockCollision() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows TickTockCollision to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new TickTockCollision(), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java b/src/classes/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java
new file mode 100644
index 0000000..f96b2ed
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java
@@ -0,0 +1,311 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.configured_universe;
+
+import com.sun.j3d.loaders.objectfile.ObjectFile;
+import com.sun.j3d.loaders.ParsingErrorException;
+import com.sun.j3d.loaders.IncorrectFormatException;
+import com.sun.j3d.loaders.Scene;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.io.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+import com.sun.j3d.utils.behaviors.sensor.Mouse6DPointerBehavior;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+public class ConfigObjLoad {
+
+ private boolean spin = false;
+ private boolean noTriangulate = false;
+ private boolean noStripify = false;
+ private double creaseAngle = 60.0;
+ private URL filename = null;
+
+ private ConfiguredUniverse u;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.7);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(objTrans);
+
+ int flags = ObjectFile.RESIZE;
+ if (!noTriangulate) flags |= ObjectFile.TRIANGULATE;
+ if (!noStripify) flags |= ObjectFile.STRIPIFY;
+ ObjectFile f = new ObjectFile(flags,
+ (float)(creaseAngle * Math.PI / 180.0));
+ Scene s = null;
+ try {
+ s = f.load(filename);
+ }
+ catch (FileNotFoundException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ catch (ParsingErrorException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ catch (IncorrectFormatException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+
+ objTrans.addChild(s.getSceneGroup());
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ if (spin) {
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+ }
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objRoot.addChild(bgNode);
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ objRoot.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f);
+ Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ objRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ objRoot.addChild(light2);
+
+ return objRoot;
+ }
+
+ private void usage()
+ {
+ System.out.println(
+ "Usage: java ObjLoad [-s] [-n] [-t] [-c degrees] <.obj file>");
+ System.out.println(" -s Spin (no user interaction)");
+ System.out.println(" -n No triangulation");
+ System.out.println(" -t No stripification");
+ System.out.println(
+ " -c Set crease angle for normal generation (default is 60 without");
+ System.out.println(
+ " smoothing group info, otherwise 180 within smoothing groups)");
+ System.exit(0);
+ } // End of usage
+
+
+ public void init() {
+ if (filename == null) {
+ try {
+ filename = new URL("file:../geometry/galleon.obj");
+ }
+ catch (MalformedURLException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+
+ // Get the config file URL from the j3d.configURL property or use the
+ // default config file "j3d1x1-window" in the current directory.
+ URL configURL = ConfiguredUniverse.getConfigURL("file:j3d1x1-window");
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new ConfiguredUniverse(configURL);
+
+ // Get the ViewingPlatform.
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the objects in the
+ // scene can be viewed. This will only have an effect if the config
+ // file sets the window eyepoint policy to something other than
+ // RELATIVE_TO_COEXISTENCE, which is the default eyepoint policy
+ // applied by ConfiguredUniverse.
+ //
+ // The default view attach policy for ConfiguredUniverse applications
+ // is NOMINAL_SCREEN. This sets the view platform origin in the
+ // physical world to the center of coexistence, which allows eye
+ // positions expressed relative to coexistence to see the appropriate
+ // field of view automatically.
+ viewingPlatform.setNominalViewingTransform();
+
+ // Add a ViewPlatformBehavior if not specified in the config file.
+ if (!spin && viewingPlatform.getViewPlatformBehavior() == null) {
+ OrbitBehavior orbit = new OrbitBehavior(u.getCanvas(),
+ OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+ }
+
+ // See if there's a 6 degree of freedom mouse in the environment.
+ // We look for one named "mouse6d".
+ Map sensorMap = null;
+ sensorMap = u.getNamedSensors();
+ if (sensorMap != null) {
+ Sensor mouse6d = (Sensor)sensorMap.get("mouse6d");
+ if (mouse6d != null) {
+ Mouse6DPointerBehavior behavior =
+ new Mouse6DPointerBehavior(mouse6d, 1.0, true);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ behavior.setSchedulingBounds(bounds);
+
+ scene.addChild(behavior);
+ scene.addChild(behavior.getEcho());
+ }
+ }
+
+ // Listen for a typed "q", "Q", or "Escape" key on each canvas to
+ // allow a convenient exit from full screen configurations.
+ Canvas3D[] canvases;
+ canvases = u.getViewer().getCanvas3Ds();
+
+ class QuitListener extends KeyAdapter {
+ public void keyTyped(KeyEvent e) {
+ char c = e.getKeyChar();
+ if (c == 'q' || c == 'Q' || c == 27)
+ System.exit(0);
+ }
+ }
+
+ QuitListener quitListener = new QuitListener();
+ for (int i = 0; i < canvases.length; i++)
+ canvases[i].addKeyListener(quitListener);
+
+ // Make the scenegraph live.
+ u.addBranchGraph(scene);
+ }
+
+ public ConfigObjLoad(String[] args) {
+ if (args.length != 0) {
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].equals("-s")) {
+ spin = true;
+ } else if (args[i].equals("-n")) {
+ noTriangulate = true;
+ } else if (args[i].equals("-t")) {
+ noStripify = true;
+ } else if (args[i].equals("-c")) {
+ if (i < args.length - 1) {
+ creaseAngle = (new Double(args[++i])).doubleValue();
+ } else usage();
+ } else {
+ usage();
+ }
+ } else {
+ try {
+ if ((args[i].indexOf("file:") == 0) ||
+ (args[i].indexOf("http") == 0)) {
+ filename = new URL(args[i]);
+ }
+ else if (args[i].charAt(0) != '/') {
+ filename = new URL("file:./" + args[i]);
+ }
+ else {
+ filename = new URL("file:" + args[i]);
+ }
+ }
+ catch (MalformedURLException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+ }
+ }
+ init();
+ }
+
+ public static void main(String[] args) {
+ new ConfigObjLoad(args);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/README.txt b/src/classes/org/jdesktop/j3d/examples/configured_universe/README.txt
new file mode 100644
index 0000000..fd2af8e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/README.txt
@@ -0,0 +1,142 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+This directory contains a simple example application that demonstrates the
+ConfiguredUniverse utility class available in the com.sun.j3d.utils.universe
+package. J3DFly, available separately, is a fully featured application that
+also uses ConfiguredUniverse.
+
+ConfiguredUniverse is an extension of SimpleUniverse that can set up an
+interactive viewing environment based upon the contents of a site-specific
+configuration file. This is useful when an application needs to run without
+change across a broad range of viewing configurations and locally available
+input and audio devices. InputDevice implementations can be instantiated by
+ConfiguredUniverse and their Sensors can be retrieved by applications along
+with the names bound to them in the configuration file.
+
+Supported viewing configurations include windows on conventional desktops,
+stereo-enabled views, fullscreen immersive displays on single or multiple
+screens, and virtual reality installations such as cave and head-mounted
+displays incorporating 6-degree-of-freedom sensor devices.
+
+The ConfigObjLoad application is a modified version of the ObjLoad example
+program which uses the ConfiguredUniverse utility instead of SimpleUniverse.
+It also differs in the following other respects:
+
+ It is an application and cannot be run in a browser. ConfiguredUniverse
+ creates a JFrame, JPanel, and Canvas3D itself for each screen and is
+ oriented towards multiple fullscreen viewing environments, although
+ conventional windowed displays are also supported. The components
+ created are easily accessable so applications can still incorporate them
+ into their own user interfaces.
+
+ The configuration file to load is specified by the j3d.configURL
+ property. If one is not specified, it will load the file j3d1x1-window
+ in this directory.
+
+ Alternative custom view platform behaviors other than OrbitBehavior can
+ be used by specifying the behavior in the configuration file.
+
+ It can retrieve a 6DOF Sensor specified in the configuration file and
+ use it to demonstrate the Mouse6DPointerBehavior class.
+
+ Typing a "q" or the Escape key will terminate the example program. This
+ is useful for fullscreen configurations.
+
+To load a specific configuration file, set the j3d.configURL property on the
+command line:
+
+ java -Dj3d.configURL=<URL string> ConfigObjLoad <args> <obj file>
+
+For example, to load j3d1x2-rot30 in the current directory, run
+
+ java -Dj3d.configURL=file:j3d1x2-rot30 ConfigObjLoad <args> <obj file>
+
+This directory includes the following sample configuration files. Normally
+a configuration file is site-specific but many of these can used as-is.
+Others may need customization for screen sizes, available input devices, and
+PhysicalBody parameters.
+
+ j3d1x1: single fullscreen desktop configuration.
+
+ j3d1x1-behavior: single fullscreen desktop configuration with a
+ configurable view platform behavior.
+
+ j3d1x1-stereo: single fullscreen desktop configuration with stereo
+ viewing.
+
+ j3d1x1-vr: single fullscreen desktop configuration with stereo viewing,
+ head tracker, and 6DOF mouse.
+
+ j3d1x1-window: single screen windowed desktop configuration.
+
+ j3d1x2-flat: dual-screen flat desktop configuration.
+
+ j3d1x2-rot30: dual-screen desktop configuration with each screen rotated
+ toward the other by 30 degrees about Y.
+
+ j3d1x3-cave: 3-projector configuration with screens to the left, front,
+ and right of the user.
+
+ j3d1x3-cave-vr: 3-projector configuration with screens to the left,
+ front, and right of the user. Includes head tracking and stereo
+ viewing.
+
+ j3d1x3-rot45: 3-screen desktop configuration with left and right screens
+ angled by 45 degrees from the center screen.
+
+ j3d2x2-flat: 4-screen projector configuration arranged in a 2x2 power
+ wall.
+
+Note: JDK 1.4 or newer is required when configuring multiple screens if the
+X11 Xinerama extension is being used to create a single virtual screen.
+This is due to a limitation of the getScreenDevices() method in the JDK 1.3
+version of GraphicsConfiguration which returns only a single GraphicsDevice
+from a virtual screen. ConfiguredUniverse will report this condition as an
+error in specifying more screens than are available.
+
+Also: Graphics performance may be degraded in some environments when using a
+virtual screen device. See the description of the j3d.disableXinerama
+property for possible performance improvements when using Xinerama.
+
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1 b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1
new file mode 100644
index 0000000..41173e3
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1
@@ -0,0 +1,98 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for a single fullscreen desktop configuration.
+ *
+ ************************************************************************
+ */
+
+// Create a new screen object and associate it with a logical name and a
+// number. This number is used as an index to retrieve the AWT GraphicsDevice
+// from the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen center 0)
+
+// Create a fullscreen window
+//
+(ScreenAttribute center WindowSize NoBorderFullScreen)
+
+// Set the available image area for the full screen. This is important when an
+// explicit ScreenScale view attribute is defined for precise scaling between
+// objects in the virtual world and their projections into the physical world.
+// The defaults are 0.365 meters for width and 0.292 meters for height.
+//
+(ScreenAttribute center PhysicalScreenWidth 0.360)
+(ScreenAttribute center PhysicalScreenHeight 0.288)
+
+// Set the TrackerBaseToImagePlate transform for this screen. The coexistence
+// to tracker base transform is identity by default, so the tracker base origin
+// and orientation will also set the origin and orientation of coexistence
+// coordinates in the physical world. This is the primary purpose of setting
+// this transform when neither head tracking nor multiple screens are being
+// used.
+//
+// The tracker base and center of coexistence are set here to the middle of the
+// screen's image plate. Their basis vectors are aligned with the image plate
+// basis vectors. The physical eyepoint position will be set relative to
+// coexistence coordinates below.
+//
+(ScreenAttribute center TrackerBaseToImagePlate
+ (Translate 0.180 0.144 0.000))
+
+// Create a view using the defined screen.
+//
+(NewView view0)
+(ViewAttribute view0 Screen center)
+
+// Set the eyepoint relative to coexistence coordinates. Here it is set 45cm
+// toward the user along +Z. Skewed projections can be created by offsetting
+// the eyepoint along X and/or Y.
+//
+(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45))
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior
new file mode 100644
index 0000000..d291913
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior
@@ -0,0 +1,149 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for single fullscreen desktop configuration.
+ * A view platform behavior is created and configured here as well.
+ *
+ ************************************************************************
+ */
+
+// Create a new screen object and associate it with a logical name and a
+// number. This number is used as an index to retrieve the AWT GraphicsDevice
+// from the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen center 0)
+
+// Create a fullscreen window
+//
+(ScreenAttribute center WindowSize NoBorderFullScreen)
+
+// Set the available image area for the full screen.
+//
+(ScreenAttribute center PhysicalScreenWidth 0.360)
+(ScreenAttribute center PhysicalScreenHeight 0.288)
+
+// Set the TrackerBaseToImagePlate transform for this screen. The coexistence
+// to tracker base transform is identity by default, so the tracker base origin
+// and orientation will also set the origin and orientation of coexistence
+// coordinates in the physical world. This is the primary purpose of setting
+// this transform when neither head tracking nor multiple screens are being
+// used.
+//
+// The tracker base and center of coexistence are set here to the middle of the
+// screen's image plate. Their basis vectors are aligned with the image plate
+// basis vectors. The physical eyepoint position will be set relative to
+// coexistence coordinates below.
+//
+(ScreenAttribute center TrackerBaseToImagePlate
+ (Translate 0.180 0.144 0.000))
+
+// Create a view using the defined screen.
+//
+(NewView view0)
+(ViewAttribute view0 Screen center)
+
+// Set the eyepoint relative to coexistence coordinates. Here it is set 45cm
+// toward the user along +Z. Skewed projections can be set by by offsetting
+// the eyepoint along X and Y.
+//
+(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45))
+
+// Create a view platform behavior. Here we use OrbitBehavior, although any
+// concrete subclass of the abstract ViewPlatformBehavior with a parameterless
+// constructor could be used. The logical name to assign to this behavior is
+// specified by the 2nd argument to the NewViewPlatformBehavior command, while
+// the 3rd argument is the name of the ViewPlatformBehavior subclass. It is
+// instantiated through introspection.
+//
+// Attributes defined by the abstract ViewPlatformBehavior superclass itself
+// can be set directly with the ViewPlatformBehaviorAttribute command. The
+// details of the subclass implementation are not known to ConfiguredUniverse,
+// so any configuration information needed by such a subclass is set by the
+// ViewPlatformBehaviorProperty command. The property name specified by that
+// command is taken to be a method name of the subclass and invoked through
+// introspection.
+//
+// View platform behaviors often need sensors or canvases as event sources to
+// drive the behavior action. An implementation of ViewPlatformBehavior always
+// gets the current ViewingPlatform through the setViewingPlatform() method.
+// The canvases used by the ViewingPlatform can be retrieved by calling its
+// getViewers() method and then calling each Viewer's getCanvas3Ds()
+// method. Sensors can be retrived by calling the ViewingPlatform method
+// getUniverse(), checking to see if the returned SimpleUniverse is a
+// ConfiguredUniverse, and then calling its getNamedSensors() method.
+//
+(NewViewPlatformBehavior vpb com.sun.j3d.utils.behaviors.vp.OrbitBehavior)
+
+// Set the scheduling bounds to be a BoundingSphere with its center at
+// (0.0 0.0 0.0) and a radius of 100 meters.
+//
+(ViewPlatformBehaviorAttribute vpb SchedulingBounds
+ (BoundingSphere (0.0 0.0 0.0) 100.0))
+
+// Set properties specific to OrbitBehavior. All arguments following the
+// method name are wrapped and passed to the specified method as an array of
+// Objects. Strings "true" and "false" get turned into Boolean, and number
+// strings get turned into Double. Constructs such as (0.0 1.0 2.0) and
+// ((0.0 1.0 2.0 0.5) (3.0 4.0 5.0 1.0) (6.0 7.0 8.0 0.0)) get converted to
+// Point3d and Matrix4d respectively. Note that last row of a Matrix4d doesn't
+// need to be specified; it is implicitly (0.0 0.0 0.0 1.0).
+//
+// The REVERSE_ALL flags are usually passed to the OrbitBehavior constructor.
+// Since it is being instantiated with its parameterless constructor the
+// reverse flags are set here explicitly.
+//
+(ViewPlatformBehaviorProperty vpb ReverseTranslate true)
+(ViewPlatformBehaviorProperty vpb ReverseRotate true)
+(ViewPlatformBehaviorProperty vpb ReverseZoom true)
+
+// Create a new view platform and set the view platform behavior.
+//
+(NewViewPlatform vp)
+(ViewPlatformAttribute vp ViewPlatformBehavior vpb)
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo
new file mode 100644
index 0000000..3db4070
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo
@@ -0,0 +1,113 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for single fullscreen stereo desktop
+ * configuration with no head tracking.
+ *
+ ************************************************************************
+ */
+
+// Create a new screen object and associate it with a logical name and a
+// number. This number is used as an index to retrieve the AWT GraphicsDevice
+// from the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen center 0)
+
+// Create a fullscreen window
+//
+(ScreenAttribute center WindowSize NoBorderFullScreen)
+
+// Set the available image area for the full screen.
+//
+(ScreenAttribute center PhysicalScreenWidth 0.360)
+(ScreenAttribute center PhysicalScreenHeight 0.288)
+
+// Set the TrackerBaseToImagePlate transform for this screen. The coexistence
+// to tracker base transform is identity by default, so the tracker base origin
+// and orientation will also set the origin and orientation of coexistence
+// coordinates in the physical world. This is the primary purpose of setting
+// this transform when neither head tracking nor multiple screens are being
+// used.
+//
+// The tracker base and center of coexistence are set here to the middle of the
+// screen's image plate. Their basis vectors are aligned with the image plate
+// basis vectors. The physical eyepoint position will be set relative to
+// coexistence coordinates below.
+//
+(ScreenAttribute center TrackerBaseToImagePlate
+ (Translate 0.180 0.144 0.000))
+
+// Define the physical body.
+//
+// The head origin is halfway between the eyes, with X extending to the right,
+// Y up, and positive Z extending into the skull.
+//
+(NewPhysicalBody SiteUser)
+
+// Set the interpupilary distance. This sets the LeftEyePosition and
+// RightEyePosition to offsets of half this distance along both directions of
+// the X axis.
+//
+(PhysicalBodyAttribute SiteUser StereoEyeSeparation 0.066)
+
+// Create a view using the defined screen and physical body.
+//
+(NewView view0)
+(ViewAttribute view0 Screen center)
+(ViewAttribute view0 PhysicalBody SiteUser)
+
+// Set the eyepoint relative to coexistence coordinates. Here it is set 45cm
+// toward the user along +Z.
+//
+(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45))
+
+// Enable stereo viewing.
+//
+(ViewAttribute view0 StereoEnable true)
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr
new file mode 100644
index 0000000..587f481
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr
@@ -0,0 +1,212 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for a single screen stereo desktop display
+ * using a head tracker and 6DOF mouse.
+ *
+ ************************************************************************
+ */
+
+// Configure the head tracker. The NewDevice command binds a logical name
+// (the 2nd argument) to an InputDevice implementation whose class name is
+// specified in the 3rd argument. The InputDevice implementation for a head
+// tracker must generate position and orientation data relative to a fixed
+// frame of reference in the physical world, the "tracker base" of the Java
+// 3D view model.
+//
+// The InputDevice is instantiated through introspection of the class name.
+// Available InputDevice implementations are site-specific, so substitute
+// the class name in a NewDevice command below with one that is available at
+// the local site.
+//
+// Note that properties are used to configure an InputDevice instead of
+// attributes. The details of an InputDevice implementation are not known to
+// ConfiguredUniverse, so the property name is invoked as a method through
+// introspection. The example properties below must be replaced with the ones
+// needed, if any, by specific InputDevice implementations.
+//
+// All property arguments following the method name are wrapped and passed to
+// the specified method as an array of Objects. Strings "true" and "false"
+// get wrapped into Boolean, and number strings get wrapped into Double.
+// Construct such as (0.0 1.0 2.0) and ((0.0 1.0 2.0 0.5) (3.0 4.0 5.0 1.0)
+// (6.0 7.0 8.0 0.0)) get converted to Point3d and Matrix4d respectively.
+// Note that last row of a Matrix4d doesn't need to be specified; it is
+// implicitly (0.0 0.0 0.0 1.0).
+//
+(NewDevice glasses LogitechRedBarron)
+(DeviceProperty glasses SerialPort "/dev/ttya") // Unix paths need quoting.
+(DeviceProperty glasses ReceiverBaseline 0.1450)
+(DeviceProperty glasses ReceiverLeftLeg 0.0875)
+(DeviceProperty glasses ReceiverHeight 0.0470)
+(DeviceProperty glasses ReceiverTopOffset 0.0000)
+
+// Configure an InputDevice to use for a 6 degree of freedom mouse if
+// required. In some implementations the same InputDevice instance can be
+// used both for head tracking and multiple peripheral sensing devices.
+// This example assumes an implementation that requires multiple instances,
+// one for each sensor, sharing the same physical hardware used for the
+// tracker base. In either case all the sensors must generate position and
+// orientation relative to the same fixed tracker base frame of reference.
+//
+(NewDevice wand LogitechRedBarron)
+(DeviceProperty wand SerialPort "/dev/ttyb")
+(DeviceProperty wand ReceiverBaseline 0.0700)
+(DeviceProperty wand ReceiverLeftLeg 0.0625)
+(DeviceProperty wand ReceiverHeight 0.0510)
+(DeviceProperty wand ReceiverTopOffset 0.0000)
+
+// Create logical names for the available sensors in the specified input
+// devices. The last argument is the sensor's index in the input device.
+//
+(NewSensor head glasses 0)
+(NewSensor mouse6d wand 0)
+
+// Set the 6DOF mouse sensor hotspot in the local sensor coordinate system.
+// The hotspot is simply the "active" point relative to the sensor origin
+// which interacts with the virtual world, such as the point used for picking
+// or grabbing an object. Its interpretation is up to the sensor behavior.
+//
+// It is set here to 10 centimeters from the base to allow reaching into the
+// screen without bumping the device into the glass, and to prevent the device
+// itself from obscuring the pointer echo.
+//
+(SensorAttribute mouse6d Hotspot (0.0 0.0 -0.10))
+
+
+// Create a new screen object and associate it with a logical name and a
+// number. This number is used as an index to retrieve the AWT GraphicsDevice
+// from the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen center 0)
+
+// Set the actual available image area. This measured as 0.350 meters in
+// width and 0.245 meters in height for the monitor in the sample setup when
+// running in stereo resolution.
+//
+(ScreenAttribute center PhysicalScreenWidth 0.350)
+(ScreenAttribute center PhysicalScreenHeight 0.245)
+(ScreenAttribute center WindowSize NoBorderFullScreen)
+
+// Set the TrackerBaseToImagePlate transform for this screen. This transforms
+// points in tracker base coordinates to image plate coordinates.
+//
+// For this sample setup the tracker base is leaning at 50 degrees about its
+// X-axis over the top edge of the monitor. The middle of the tracker base
+// (its origin) is offset by (0.175, 0.345, 0.020) from the lower left
+// corner of the screen (origin of the image plate).
+//
+(ScreenAttribute center TrackerBaseToImagePlate
+ (RotateTranslate (Rotate 50.000 0.000 0.000)
+ (Translate 0.175 0.345 0.020)))
+
+
+// Create a physical environment. This contains the available input devices,
+// audio devices, and sensors, and defines the coexistence coordinate system.
+//
+(NewPhysicalEnvironment SampleSite)
+
+// Register the input devices defined in this file.
+//
+(PhysicalEnvironmentAttribute SampleSite InputDevice glasses)
+(PhysicalEnvironmentAttribute SampleSite InputDevice wand)
+
+// Register the sensor which will drive head tracking.
+//
+(PhysicalEnvironmentAttribute SampleSite HeadTracker head)
+
+// Define coexistence coordinates.
+//
+// Coexistence coordinates are defined relative to the tracker base to simplify
+// calibration measurements, just as the tracker base is used as the common
+// reference frame for the TrackerBaseToImagePlate calibration.
+//
+// Here the coexistence origin is set to the middle of the center screen, using
+// the same basis vectors as its image plate. This will put the tracker base
+// origin at (0.0 0.220 0.020) relative to the coexistence origin along its
+// basis vectors.
+//
+(PhysicalEnvironmentAttribute SampleSite CoexistenceToTrackerBase
+ (TranslateRotate (Translate 0.0 -0.220 -0.020)
+ (Rotate -50.0 0.0 0.0)))
+
+// Define the physical body.
+//
+// The head origin is halfway between the eyes, with X extending to the right,
+// Y up, and positive Z extending into the skull.
+//
+(NewPhysicalBody SiteUser)
+
+// Set the interpupilary distance. This sets the LeftEyePosition and
+// RightEyePosition to offsets of half this distance along both directions of
+// the X axis.
+//
+(PhysicalBodyAttribute SiteUser StereoEyeSeparation 0.066)
+
+// Define the position and orientation of the head relative to the tracker
+// mounted on the head.
+//
+(PhysicalBodyAttribute SiteUser HeadToHeadTracker ((1.0 0.0 0.0 0.000)
+ (0.0 1.0 0.0 0.020)
+ (0.0 0.0 1.0 0.018)))
+
+
+// Create a view using the defined screens, PhysicalEnvironment, and
+// PhysicalBody.
+//
+(NewView view0)
+(ViewAttribute view0 Screen center)
+(ViewAttribute view0 PhysicalEnvironment SampleSite)
+(ViewAttribute view0 PhysicalBody SiteUser)
+
+// Enable stereo viewing. Enable head tracking to get the position of the eyes
+// with respect to coexistence.
+//
+(ViewAttribute view0 StereoEnable true)
+(ViewAttribute view0 TrackingEnable True)
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window
new file mode 100644
index 0000000..eec0e31
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window
@@ -0,0 +1,89 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for a conventional single screen, windowed
+ * desktop configuration.
+ *
+ ************************************************************************
+ */
+
+// Create a new screen object and associate it with a logical name and a
+// number. This number is used as an index to retrieve the AWT GraphicsDevice
+// from the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen center 0)
+
+// Create a 700x700 pixel window on the screen.
+//
+(ScreenAttribute center WindowSize (700.0 700.0))
+
+// Create a view using the defined screen.
+//
+(NewView view0)
+(ViewAttribute view0 Screen center)
+
+// ConfiguredUniverse is oriented toward multi-screen viewing environments, so
+// it sets the following attributes to those listed. For a conventional window
+// on a single screen desktop configuration we need to set them back to their
+// normal defaults.
+//
+// View.windowEyePointPolicy RELATIVE_TO_COEXISTENCE
+// View.windowMovementPolicy VIRTUAL_WORLD
+// View.windowResizePolicy VIRTUAL_WORLD
+// View.coexistenceCenteringEnable false
+// ViewPlatform.viewAttachPolicy NOMINAL_SCREEN
+//
+(ViewAttribute view0 WindowEyepointPolicy RELATIVE_TO_FIELD_OF_VIEW)
+(ViewAttribute view0 WindowMovementPolicy PHYSICAL_WORLD)
+(ViewAttribute view0 WindowResizePolicy PHYSICAL_WORLD)
+(ViewAttribute view0 CoexistenceCenteringEnable true)
+
+(NewViewPlatform vp)
+(ViewPlatformAttribute vp ViewAttachPolicy NOMINAL_HEAD)
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat
new file mode 100644
index 0000000..667ea52
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat
@@ -0,0 +1,134 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for dual-screen (flat) desktop configuration
+ * with no head tracking.
+ *
+ ************************************************************************
+ */
+
+// Create new screen objects and associate them with logical names and numbers.
+// These numbers are used as indices to retrieve the AWT GraphicsDevice from
+// the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen left 0)
+(NewScreen right 1)
+
+// Set the screen dimensions.
+//
+(ScreenAttribute left PhysicalScreenWidth 0.360)
+(ScreenAttribute left PhysicalScreenHeight 0.288)
+
+(ScreenAttribute right PhysicalScreenWidth 0.360)
+(ScreenAttribute right PhysicalScreenHeight 0.288)
+
+// Specify full screen windows.
+//
+(ScreenAttribute left WindowSize NoBorderFullScreen)
+(ScreenAttribute right WindowSize NoBorderFullScreen)
+
+// Set the TrackerBaseToImagePlate transforms for these screens. This
+// transforms points in tracker base coordinates to each screen's image plate
+// coordinates, where the origin of the image plate is defined to be the lower
+// left corner of the screen with X increasing to the right, Y increasing to
+// the top, and Z increasing away from the screen.
+//
+// Without head or sensor tracking the tracker base is still needed as a fixed
+// frame of reference for describing the orientation and position of each
+// screen to the others. The coexistence to tracker base transform is set to
+// identity by default, so the tracker base origin and orientation will also
+// set the origin and orientation of coexistence coordinates in the physical
+// world.
+//
+// The tracker base and center of coexistence is set here to the middle of the
+// edge shared by the two screens.
+//
+(ScreenAttribute left TrackerBaseToImagePlate
+ (Translate 0.360 0.144 0.0))
+(ScreenAttribute right TrackerBaseToImagePlate
+ (Translate 0.000 0.144 0.0))
+
+// Sometimes it is desirable to include the bevels in between the monitors in
+// the TrackerBaseToImagePlate transforms, so that the abutting bevels obscure
+// the view of the virtual world instead of stretching it out between the
+// monitors. For a bevel width of 4.5 cm on each monitor, the above commands
+// would become the following:
+//
+// (ScreenAttribute left TrackerBaseToImagePlate
+// (Translate 0.405 0.144 0.0))
+// (ScreenAttribute right TrackerBaseToImagePlate
+// (Translate -0.045 0.144 0.0))
+//
+// Conversely, a similar technique may be used to include overlap between the
+// screens. This is useful for projection systems which use edge blending
+// to provide seamless integration between screens.
+
+
+// Create a view using the defined screens.
+//
+(NewView view0)
+(ViewAttribute view0 Screen left)
+(ViewAttribute view0 Screen right)
+
+// Set the eyepoint relative to coexistence coordinates. Here it is set 45cm
+// toward the user along Z, extending out from the midpoint of the edge shared
+// by the two screens. This will create the appropriate skewed projection
+// frustums for each image plate.
+//
+// If a planar display surface is all that is required, the same effect could
+// be achieved in a virtual screen enviroment such as Xinerama by simply
+// creating a canvas that spans both screens. In some display environments the
+// use of a canvas that spans multiple physical screens may cause significant
+// performance degradation, however.
+//
+// See j3d1x2-rot30 for an example of a non-planar configuration that cannot be
+// achieved through a single canvas spanning both screens.
+//
+(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45))
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30 b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30
new file mode 100644
index 0000000..68f4a6e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30
@@ -0,0 +1,99 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for a dual-screen desktop configuration
+ * with each screen rotated toward the other by 30 degrees about Y from
+ * planar. The inside angle between them is 120 degrees.
+ *
+ ************************************************************************
+ */
+
+// Create new screen objects and associate them with logical names and numbers.
+// These numbers are used as indices to retrieve the AWT GraphicsDevice from
+// the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen left 0)
+(NewScreen right 1)
+
+// Set the available image areas for full screens.
+//
+(ScreenAttribute left PhysicalScreenWidth 0.360)
+(ScreenAttribute left PhysicalScreenHeight 0.288)
+
+(ScreenAttribute right PhysicalScreenWidth 0.360)
+(ScreenAttribute right PhysicalScreenHeight 0.288)
+
+// Specify full screen windows.
+//
+(ScreenAttribute left WindowSize NoBorderFullScreen)
+(ScreenAttribute right WindowSize NoBorderFullScreen)
+
+// Set the TrackerBaseToImagePlate transforms for these screens.
+//
+// The tracker base is set here to the middle of the edge shared by the two
+// screens. Each screen is rotated 30 degrees toward the other about the
+// tracker base +Y axis, so that the tracker base +Z is centered between the
+// two screens.
+//
+(ScreenAttribute left TrackerBaseToImagePlate
+ (RotateTranslate (Rotate 0.000 -30.000 0.0)
+ (Translate 0.360 0.144 0.0)))
+
+(ScreenAttribute right TrackerBaseToImagePlate
+ (RotateTranslate (Rotate 0.000 30.000 0.0)
+ (Translate 0.000 0.144 0.0)))
+
+
+// Create a view using the defined screens.
+//
+(NewView view0)
+(ViewAttribute view0 Screen left)
+(ViewAttribute view0 Screen right)
+(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45))
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave
new file mode 100644
index 0000000..afc532c
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave
@@ -0,0 +1,171 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for a cave environment. This cave
+ * consists of 3 projectors with 3 screens to the left, front, and right
+ * of the user, all at 90 degrees to each other.
+ *
+ * The projectors in the VirtualPortal sample site are actually turned
+ * on their sides to get more height. Screen 0 is rotated 90 degrees
+ * counter-clockwise, while screens 1 and 2 are rotated 90 degrees
+ * clockwise.
+ *
+ ************************************************************************
+ */
+
+// Create new screen objects and associate them with logical names and numbers.
+// These numbers are used as indices to retrieve the AWT GraphicsDevice from
+// the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen left 0)
+(NewScreen center 1)
+(NewScreen right 2)
+
+
+// Set the available image areas as well as their positition and orientation
+// relative to the tracker base. Although this config file doesn't enable
+// head tracking, the tracker base is still needed as a point of reference to
+// describe the position and orientation of the screens relative to the
+// environment.
+//
+// From the orientation of a user standing within this VirtualPortal site and
+// facing the center screen, the tracker base is along the vertical midline of
+// the screen, 0.248 meters down from the top edge, and 1.340 meters in front
+// of it. The tracker base is oriented so that its +X axis points to the left,
+// its +Y axis points toward the screen, and its +Z axis points toward the
+// floor.
+//
+(ScreenAttribute left PhysicalScreenWidth 2.480)
+(ScreenAttribute left PhysicalScreenHeight 1.705)
+(ScreenAttribute left WindowSize NoBorderFullScreen)
+(ScreenAttribute left TrackerBaseToImagePlate
+ (( 0.0 0.0 -1.0 2.230)
+ ( 0.0 -1.0 0.0 1.340)
+ (-1.0 0.0 0.0 0.885)))
+
+(ScreenAttribute center PhysicalScreenWidth 2.485)
+(ScreenAttribute center PhysicalScreenHeight 1.745)
+(ScreenAttribute center WindowSize NoBorderFullScreen)
+(ScreenAttribute center TrackerBaseToImagePlate
+ (( 0.0 0.0 1.0 0.248)
+ (-1.0 0.0 0.0 0.885)
+ ( 0.0 -1.0 0.0 1.340)))
+
+(ScreenAttribute right PhysicalScreenWidth 2.480)
+(ScreenAttribute right PhysicalScreenHeight 1.775)
+(ScreenAttribute right WindowSize NoBorderFullScreen)
+(ScreenAttribute right TrackerBaseToImagePlate
+ (( 0.0 0.0 1.0 0.2488)
+ ( 0.0 -1.0 0.0 1.340)
+ ( 1.0 0.0 0.0 0.860)))
+
+// Set the location of the center of coexistence relative to the tracker base.
+// Here it set to the center of the center screen. This config file will set
+// the location of the user's eyes relative to this point. The default view
+// attach policy of NOMINAL_SCREEN used by ConfiguredUniverse will place the
+// origin of the view platform in coexistence coordinates at the center of
+// coexistence.
+//
+(NewPhysicalEnvironment VirtualPortal)
+(PhysicalEnvironmentAttribute VirtualPortal
+ CoexistenceToTrackerBase
+ ((-1.0 0.0 0.0 0.000)
+ ( 0.0 0.0 -1.0 1.340)
+ ( 0.0 -1.0 0.0 0.994)))
+
+// The above center of coexistence is appropriate for the sample geometry
+// files available in the programs/examples directory. Often a more
+// immersive point of view is required for larger virtual worlds. This can be
+// achieved by placing the center of coexistence closer to the nominal position
+// of the user's head, so that the view platform origin in coexistence
+// coordinates will map there as well.
+//
+// Here we set the location of the center of coexistence 0.5 meters along the
+// tracker base +Z axis, 1.737 meters from the floor (about 5 ft 8.4 inches).
+//
+// (PhysicalEnvironmentAttribute VirtualPortal
+// CoexistenceToTrackerBase
+// ((-1.0 0.0 0.0 0.0)
+// ( 0.0 0.0 -1.0 0.0)
+// ( 0.0 -1.0 0.0 0.5)))
+
+
+// Now define the view.
+//
+(NewView view0)
+(ViewAttribute view0 Screen left)
+(ViewAttribute view0 Screen center)
+(ViewAttribute view0 Screen right)
+(ViewAttribute view0 PhysicalEnvironment VirtualPortal)
+
+// Set the user eye position in the display environment. It is set here to
+// 1.340 meters back from the center screen (directly under the tracker), and
+// 1.737 meters from the floor (about 5 ft 8.4 inches).
+//
+(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.494 1.340))
+
+// Here is an alternative center eye position to use with the immersive
+// coexistence coordinate system defined in comments above.
+//
+// (ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.0))
+
+// Set the screen scale. This is scale factor from virtual to physical
+// coordinates.
+//
+(ViewAttribute view0 ScreenScalePolicy SCALE_SCREEN_SIZE)
+
+// Alternative for explict scaling.
+//
+// (ViewAttribute view0 ScreenScalePolicy SCALE_EXPLICIT)
+// (ViewAttribute view0 ScreenScale 5.00)
+
+// No stereo viewing for this configuration.
+//
+(ViewAttribute view0 StereoEnable False)
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr
new file mode 100644
index 0000000..029decf
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr
@@ -0,0 +1,222 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for a cave environment with head tracking and
+ * stereo viewing. This cave consists of 3 projectors with 3 screens to the
+ * left, front, and right of the user, all at 90 degrees to each other.
+ *
+ * The projectors in the VirtualPortal sample site are actually turned
+ * on their sides to get more height. Screen 0 is rotated 90 degrees
+ * counter-clockwise, while screens 1 and 2 are rotated 90 degrees
+ * clockwise.
+ *
+ ************************************************************************
+ */
+
+// Configure the head tracker. The NewDevice command binds a logical name
+// (the 2nd argument) to an InputDevice implementation whose class name is
+// specified in the 3rd argument. The InputDevice implementation for a head
+// tracker must generate position and orientation data relative to a fixed
+// frame of reference in the physical world, the "tracker base" of the Java
+// 3D view model.
+//
+// The InputDevice is instantiated through introspection of the class name.
+// Available InputDevice implementations are site-specific, so substitute
+// the class name in a NewDevice command below with one that is available at
+// the local site.
+//
+// Note that properties are used to configure an InputDevice instead of
+// attributes. The details of an InputDevice implementation are not known to
+// ConfiguredUniverse, so the property name is invoked as a method through
+// introspection. The example properties below must be replaced with the ones
+// needed, if any, by specific InputDevice implementations. All arguments
+// following the method name are wrapped and passed to the specified method as
+// an array of Objects.
+//
+// All property arguments following the method name are wrapped and passed to
+// the specified method as an array of Objects. Strings "true" and "false"
+// get wrapped into Boolean, and number strings get wrapped into Double.
+// Construct such as (0.0 1.0 2.0) and ((0.0 1.0 2.0 0.5) (3.0 4.0 5.0 1.0)
+// (6.0 7.0 8.0 0.0)) get converted to Point3d and Matrix4d respectively.
+// Note that last row of a Matrix4d doesn't need to be specified; it is
+// implicitly (0.0 0.0 0.0 1.0).
+//
+(NewDevice glasses LogitechRedBarron)
+(DeviceProperty glasses SerialPort "/dev/ttya") // Unix paths need quoting.
+(DeviceProperty glasses TransmitterBaseline 0.4600)
+(DeviceProperty glasses TransmitterLeftLeg 0.4400)
+(DeviceProperty glasses TransmitterCalibrationDistance 0.4120)
+
+// Create a logical name for the head tracker sensor. The last argument is
+// the sensor's index in the input device.
+//
+(NewSensor head glasses 0)
+
+// Create new screen objects and associate them with logical names and numbers.
+// These numbers are used as indices to retrieve the AWT GraphicsDevice from
+// the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen left 0)
+(NewScreen center 1)
+(NewScreen right 2)
+
+
+// Set the available image areas as well as their positition and orientation
+// relative to the tracker base. From the orientation of a user standing
+// within this VirtualPortal site and facing the center screen, the tracker
+// base is along the vertical midline of the screen, 0.248 meters down from
+// the top edge, and 1.340 meters in front of it. The tracker base is
+// oriented so that its +X axis points to the left, its +Y axis points toward
+// the screen, and its +Z axis points toward the floor.
+//
+(ScreenAttribute left PhysicalScreenWidth 2.480)
+(ScreenAttribute left PhysicalScreenHeight 1.705)
+(ScreenAttribute left WindowSize NoBorderFullScreen)
+(ScreenAttribute left TrackerBaseToImagePlate
+ (( 0.0 0.0 -1.0 2.230)
+ ( 0.0 -1.0 0.0 1.340)
+ (-1.0 0.0 0.0 0.885)))
+
+(ScreenAttribute center PhysicalScreenWidth 2.485)
+(ScreenAttribute center PhysicalScreenHeight 1.745)
+(ScreenAttribute center WindowSize NoBorderFullScreen)
+(ScreenAttribute center TrackerBaseToImagePlate
+ (( 0.0 0.0 1.0 0.248)
+ (-1.0 0.0 0.0 0.885)
+ ( 0.0 -1.0 0.0 1.340)))
+
+(ScreenAttribute right PhysicalScreenWidth 2.480)
+(ScreenAttribute right PhysicalScreenHeight 1.775)
+(ScreenAttribute right WindowSize NoBorderFullScreen)
+(ScreenAttribute right TrackerBaseToImagePlate
+ (( 0.0 0.0 1.0 0.2488)
+ ( 0.0 -1.0 0.0 1.340)
+ ( 1.0 0.0 0.0 0.860)))
+
+// Create a physical environment. This contains the available input devices,
+// audio devices, and sensors, and defines the coexistence coordinate system
+// for mapping between the virtual and physical worlds.
+//
+(NewPhysicalEnvironment VirtualPortal)
+
+// Register the input device defined in this file and the sensor which will
+// drive head tracking.
+//
+(PhysicalEnvironmentAttribute VirtualPortal InputDevice glasses)
+(PhysicalEnvironmentAttribute VirtualPortal HeadTracker head)
+
+// Set the location of the center of coexistence relative to the tracker base.
+// Here it set to the center of the center screen. The default view attach
+// policy of NOMINAL_SCREEN used by ConfiguredUniverse will place the origin of
+// the view platform in coexistence coordinates at the center of coexistence.
+//
+(PhysicalEnvironmentAttribute VirtualPortal
+ CoexistenceToTrackerBase
+ ((-1.0 0.0 0.0 0.000)
+ ( 0.0 0.0 -1.0 1.340)
+ ( 0.0 -1.0 0.0 0.994)))
+
+// The above center of coexistence is appropriate for the sample geometry
+// files available in the programs/examples directory. Often a more
+// immersive point of view is required for larger virtual worlds. This can be
+// achieved by placing the center of coexistence closer to the nominal position
+// of the user's head, so that the view platform origin in coexistence
+// coordinates will map there as well.
+//
+// Here we set the location of the center of coexistence 0.5 meters along the
+// tracker base +Z axis, 1.737 meters from the floor (about 5 ft 8.4 inches).
+//
+// (PhysicalEnvironmentAttribute VirtualPortal
+// CoexistenceToTrackerBase
+// ((-1.0 0.0 0.0 0.0)
+// ( 0.0 0.0 -1.0 0.0)
+// ( 0.0 -1.0 0.0 0.5)))
+
+
+// Define the physical body.
+//
+// The head origin is halfway between the eyes, with X extending to the right,
+// Y up, and positive Z extending into the skull.
+//
+(NewPhysicalBody LabRat)
+(PhysicalBodyAttribute LabRat StereoEyeSeparation .07)
+
+// Define the position and orientation of the head relative to the tracker
+// mounted on the head.
+//
+(PhysicalBodyAttribute LabRat HeadToHeadTracker
+ ((-1.0 0.0 0.0 0.00)
+ ( 0.0 0.0 -1.0 0.05)
+ ( 0.0 -1.0 0.0 0.11)))
+// Now define the view.
+//
+(NewView view0)
+(ViewAttribute view0 Screen left)
+(ViewAttribute view0 Screen center)
+(ViewAttribute view0 Screen right)
+(ViewAttribute view0 PhysicalBody LabRat)
+(ViewAttribute view0 PhysicalEnvironment VirtualPortal)
+
+// Set the screen scale. This is scale factor from virtual to physical
+// coordinates.
+//
+(ViewAttribute view0 ScreenScalePolicy SCALE_SCREEN_SIZE)
+
+// Alternative for explict scaling.
+//
+//(ViewAttribute view0 ScreenScalePolicy SCALE_EXPLICIT)
+//(ViewAttribute view0 ScreenScale 5.00)
+
+// Enable stereo viewing. Enable head tracking to get the position of the eyes
+// with respect to coexistence. Boolean values may be specified as either
+// true, True, false, or False.
+//
+(ViewAttribute view0 StereoEnable true)
+(ViewAttribute view0 TrackingEnable True)
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45 b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45
new file mode 100644
index 0000000..d221e74
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45
@@ -0,0 +1,110 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for 3 screens. Left and right screens are
+ * rotated 45 degrees from the center screen.
+ *
+ ************************************************************************
+ */
+
+// Create new screen objects and associate them with logical names and numbers.
+// These numbers are used as indices to retrieve the AWT GraphicsDevice from
+// the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen left 0)
+(NewScreen center 1)
+(NewScreen right 2)
+
+// Set the available image areas for full screens.
+//
+(ScreenAttribute left PhysicalScreenWidth 0.360)
+(ScreenAttribute left PhysicalScreenHeight 0.288)
+
+(ScreenAttribute center PhysicalScreenWidth 0.360)
+(ScreenAttribute center PhysicalScreenHeight 0.288)
+
+(ScreenAttribute right PhysicalScreenWidth 0.360)
+(ScreenAttribute right PhysicalScreenHeight 0.288)
+
+// Specify full screen windows.
+//
+(ScreenAttribute left WindowSize NoBorderFullScreen)
+(ScreenAttribute center WindowSize NoBorderFullScreen)
+(ScreenAttribute right WindowSize NoBorderFullScreen)
+
+// Set the TrackerBaseToImagePlate transforms for these screens.
+//
+// The tracker base and center of coexistence are set here to the middle of the
+// center screen. The basis vectors are aligned with the center screen image
+// plate. The left and right screens are rotated 45 degrees toward each other
+// about their shared edges with the center screen.
+//
+(ScreenAttribute center TrackerBaseToImagePlate
+ (Translate 0.180000 0.144000 0.000000))
+
+// cos(45) * 0.360 * 0.5 = 0.127279; 0.360 + 0.127279 = 0.487279
+(ScreenAttribute left TrackerBaseToImagePlate
+ (RotateTranslate
+ (Rotate 0.000000 -45.000000 0.000000)
+ (Translate 0.487279 0.144000 0.127279)))
+
+// cos(45) * 0.360 * 0.5 = 0.127279
+(ScreenAttribute right TrackerBaseToImagePlate
+ (RotateTranslate
+ (Rotate 0.000000 45.000000 0.000000)
+ (Translate -0.127279 0.144000 0.127279)))
+
+// Create a view using the defined screens.
+//
+(NewView view0)
+(ViewAttribute view0 Screen left)
+(ViewAttribute view0 Screen center)
+(ViewAttribute view0 Screen right)
+(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.5))
diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat
new file mode 100644
index 0000000..46df9a3
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat
@@ -0,0 +1,135 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+/*
+ ************************************************************************
+ *
+ * Java 3D configuration file for 4 screen projection configuration
+ * arranged in a 2x2 power wall.
+ *
+ ************************************************************************
+ */
+
+// Create new screen objects and associate them with logical names and numbers.
+// These numbers are used as indices to retrieve the AWT GraphicsDevice from
+// the array that GraphicsEnvironment.getScreenDevices() returns.
+//
+// NOTE: The GraphicsDevice order in the array is specific to the local
+// site and display system.
+//
+(NewScreen topleft 0)
+(NewScreen topright 1)
+(NewScreen bottomleft 3)
+(NewScreen bottomright 2)
+
+// Set the available image areas for full screens. This is important when
+// precise scaling between objects in the virtual world and their projections
+// into the physical world is desired through use of explicit ScreenScale view
+// attributes. The defaults are 0.365 meters for width and 0.292 meters for
+// height.
+//
+(ScreenAttribute topleft PhysicalScreenWidth 0.912)
+(ScreenAttribute topleft PhysicalScreenHeight 0.680)
+
+(ScreenAttribute topright PhysicalScreenWidth 0.912)
+(ScreenAttribute topright PhysicalScreenHeight 0.680)
+
+(ScreenAttribute bottomleft PhysicalScreenWidth 0.912)
+(ScreenAttribute bottomleft PhysicalScreenHeight 0.685)
+
+(ScreenAttribute bottomright PhysicalScreenWidth 0.912)
+(ScreenAttribute bottomright PhysicalScreenHeight 0.685)
+
+
+// Specify full screen windows.
+//
+(ScreenAttribute topleft WindowSize NoBorderFullScreen)
+(ScreenAttribute topright WindowSize NoBorderFullScreen)
+(ScreenAttribute bottomleft WindowSize NoBorderFullScreen)
+(ScreenAttribute bottomright WindowSize NoBorderFullScreen)
+
+// Set the TrackerBaseToImagePlate transforms for these screens. This
+// transforms points in tracker base coordinates to each screen's image plate
+// coordinates, where the origin of the image plate is defined to be the lower
+// left corner of the screen with X increasing to the right, Y increasing to
+// the top, and Z increasing away from the screen.
+//
+// Without head or sensor tracking the tracker base is still needed as a point
+// of reference for describing the orientation and position of each screen to
+// the others. The coexistence to tracker base transform is set to identity by
+// default, so the tracker base origin and orientation will also set the origin
+// and orientation of coexistence coordinates in the physical world.
+//
+// The tracker base and center of coexistence are set here to the center of the
+// 2x2 array with its basis vectors aligned to image plate coordinates.
+//
+(ScreenAttribute topleft TrackerBaseToImagePlate
+ (Translate 0.912 0.000 0.0))
+(ScreenAttribute topright TrackerBaseToImagePlate
+ (Translate 0.000 0.000 0.0))
+(ScreenAttribute bottomleft TrackerBaseToImagePlate
+ (Translate 0.912 0.685 0.0))
+(ScreenAttribute bottomright TrackerBaseToImagePlate
+ (Translate 0.000 0.685 0.0))
+
+// Create a view using the defined screens.
+//
+(NewView view0)
+(ViewAttribute view0 Screen topleft)
+(ViewAttribute view0 Screen topright)
+(ViewAttribute view0 Screen bottomleft)
+(ViewAttribute view0 Screen bottomright)
+
+// Set the screen scale. This is scale factor from virtual to physical
+// coordinates. The default policy of SCALE_SCREEN_SIZE doesn't work well here
+// since in the 2x2 arrangement the individual screens are too small. The
+// explicit scale factor below assumes a normalized range of object coordinates
+// of [-1.0 .. +1.0].
+//
+(ViewAttribute view0 ScreenScalePolicy SCALE_EXPLICIT)
+(ViewAttribute view0 ScreenScale 0.912)
+
+// Set the user eye position in the display environment.
+//
+(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 1.0))
diff --git a/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form b/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form
new file mode 100644
index 0000000..b7d1376
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.2" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <Properties>
+ <Property name="defaultCloseOperation" type="int" value="3"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-16,0,0,1,-109"/>
+ <SyntheticProperty name="formPosition" type="java.awt.Point" value="-84,-19,0,5,115,114,0,14,106,97,118,97,46,97,119,116,46,80,111,105,110,116,-74,-60,-118,114,52,126,-56,38,2,0,2,73,0,1,120,73,0,1,121,120,112,0,0,0,0,0,0,0,0"/>
+ <SyntheticProperty name="formSizePolicy" type="int" value="0"/>
+ <SyntheticProperty name="generatePosition" type="boolean" value="true"/>
+ <SyntheticProperty name="generateSize" type="boolean" value="true"/>
+ <SyntheticProperty name="generateCenter" type="boolean" value="false"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-40,0,0,1,-117"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="jPanel1">
+ <Properties>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+ <TitledBorder title="WireFrame Object"/>
+ </Border>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JLabel" name="jLabel1">
+ <Properties>
+ <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+ <Font name="Dialog" size="12" style="0"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Depth function"/>
+ <Property name="toolTipText" type="java.lang.String" value="Mode for normal object"/>
+ </Properties>
+ <AccessibilityProperties>
+ <Property name="AccessibleContext.accessibleParent" type="javax.accessibility.Accessible" editor="org.netbeans.modules.form.RADVisualComponent$AccessibleParentEditor">
+ <ComponentRef name="shadedComboBox"/>
+ </Property>
+ </AccessibilityProperties>
+ </Component>
+ <Component class="javax.swing.JComboBox" name="normalComboBox">
+ <Properties>
+ <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+ <Font name="Dialog" size="12" style="0"/>
+ </Property>
+ <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+ <StringArray count="8">
+ <StringItem index="0" value="ALWAYS"/>
+ <StringItem index="1" value="NEVER"/>
+ <StringItem index="2" value="EQUAL"/>
+ <StringItem index="3" value="NOT_EQUAL"/>
+ <StringItem index="4" value="LESS"/>
+ <StringItem index="5" value="LESS_OR_EQUAL"/>
+ <StringItem index="6" value="GREATER"/>
+ <StringItem index="7" value="GREATER_OR_EQUAL"/>
+ </StringArray>
+ </Property>
+ <Property name="selectedIndex" type="int" value="6"/>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[150, 22]"/>
+ </Property>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="normalComboBoxActionPerformed"/>
+ </Events>
+ </Component>
+ <Component class="javax.swing.JCheckBox" name="wfCheckBox">
+ <Properties>
+ <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+ <Font name="Dialog" size="12" style="0"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Write Depth Buffer"/>
+ <Property name="toolTipText" type="java.lang.String" value="Depth will be written for the object, if selected"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="wfCheckBoxActionPerformed"/>
+ </Events>
+ </Component>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JPanel" name="jPanel2">
+ <Properties>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+ <TitledBorder title="Shaded Object"/>
+ </Border>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JLabel" name="jLabel3">
+ <Properties>
+ <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+ <Font name="Dialog" size="12" style="0"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Depth Function"/>
+ <Property name="toolTipText" type="java.lang.String" value="Mode of shaded object"/>
+ </Properties>
+ </Component>
+ <Component class="javax.swing.JComboBox" name="shadedComboBox">
+ <Properties>
+ <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+ <Font name="Dialog" size="12" style="0"/>
+ </Property>
+ <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+ <StringArray count="8">
+ <StringItem index="0" value="ALWAYS"/>
+ <StringItem index="1" value="NEVER"/>
+ <StringItem index="2" value="EQUAL"/>
+ <StringItem index="3" value="NOT_EQUAL"/>
+ <StringItem index="4" value="LESS"/>
+ <StringItem index="5" value="LESS_OR_EQUAL"/>
+ <StringItem index="6" value="GREATER"/>
+ <StringItem index="7" value="GREATER_OR_EQUAL"/>
+ </StringArray>
+ </Property>
+ <Property name="selectedIndex" type="int" value="4"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="shadedComboBoxActionPerformed"/>
+ </Events>
+ </Component>
+ <Component class="javax.swing.JCheckBox" name="shadedCheckBox">
+ <Properties>
+ <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+ <Font name="Dialog" size="12" style="0"/>
+ </Property>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String" value="Write Depth Buffer"/>
+ <Property name="toolTipText" type="java.lang.String" value="Depth will be written for the object, if selected"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="shadedCheckBoxActionPerformed"/>
+ </Events>
+ </Component>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JPanel" name="jPanel3">
+ <Properties>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+ <TitledBorder title="Rotating Cube"/>
+ </Border>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JLabel" name="jLabel4">
+ <Properties>
+ <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+ <Font name="Dialog" size="12" style="0"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Raster Operator"/>
+ <Property name="toolTipText" type="java.lang.String" value="Raster mode of rotating object (try NOOP)"/>
+ </Properties>
+ </Component>
+ <Component class="javax.swing.JComboBox" name="rotatingComboBox">
+ <Properties>
+ <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+ <Font name="Dialog" size="12" style="0"/>
+ </Property>
+ <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+ <StringArray count="16">
+ <StringItem index="0" value="CLEAR"/>
+ <StringItem index="1" value="AND"/>
+ <StringItem index="2" value="AND_REVERSE"/>
+ <StringItem index="3" value="COPY"/>
+ <StringItem index="4" value="AND_INVERTED"/>
+ <StringItem index="5" value="NOOP"/>
+ <StringItem index="6" value="XOR"/>
+ <StringItem index="7" value="OR"/>
+ <StringItem index="8" value="NOR"/>
+ <StringItem index="9" value="EQUIV"/>
+ <StringItem index="10" value="INVERT"/>
+ <StringItem index="11" value="OR_REVERSE"/>
+ <StringItem index="12" value="COPY_INVERTED"/>
+ <StringItem index="13" value="OR_INVERTED"/>
+ <StringItem index="14" value="NAND"/>
+ <StringItem index="15" value="SET"/>
+ </StringArray>
+ </Property>
+ <Property name="selectedIndex" type="int" value="3"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rotatingComboBoxActionPerformed"/>
+ </Events>
+ </Component>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java b/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java
new file mode 100644
index 0000000..8485823
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java
@@ -0,0 +1,359 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.depth_func;
+
+import javax.media.j3d.*;
+
+
+/**
+ *The goal of that example is to show the use of different ZBuffer comparison modes.
+ */
+public class DepthFuncTest extends javax.swing.JFrame
+{
+
+ RenderFrame rf;
+
+ /**
+ * Creates new form DepthFuncTest
+ */
+ public DepthFuncTest(){
+ initComponents();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents()
+ {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ jPanel1 = new javax.swing.JPanel();
+ jLabel1 = new javax.swing.JLabel();
+ normalComboBox = new javax.swing.JComboBox();
+ wfCheckBox = new javax.swing.JCheckBox();
+ jPanel2 = new javax.swing.JPanel();
+ jLabel3 = new javax.swing.JLabel();
+ shadedComboBox = new javax.swing.JComboBox();
+ shadedCheckBox = new javax.swing.JCheckBox();
+ jPanel3 = new javax.swing.JPanel();
+ jLabel4 = new javax.swing.JLabel();
+ rotatingComboBox = new javax.swing.JComboBox();
+
+ getContentPane().setLayout(new java.awt.GridBagLayout());
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ jPanel1.setBorder(new javax.swing.border.TitledBorder("WireFrame Object"));
+ jLabel1.setFont(new java.awt.Font("Dialog", 0, 12));
+ jLabel1.setText("Depth function");
+ jLabel1.setToolTipText("Mode for normal object");
+ jPanel1.add(jLabel1);
+ jLabel1.getAccessibleContext().setAccessibleParent(shadedComboBox);
+
+ normalComboBox.setFont(new java.awt.Font("Dialog", 0, 12));
+ normalComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "ALWAYS", "NEVER", "EQUAL", "NOT_EQUAL", "LESS", "LESS_OR_EQUAL", "GREATER", "GREATER_OR_EQUAL" }));
+ normalComboBox.setSelectedIndex(6);
+ normalComboBox.setPreferredSize(new java.awt.Dimension(150, 22));
+ normalComboBox.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ normalComboBoxActionPerformed(evt);
+ }
+ });
+
+ jPanel1.add(normalComboBox);
+
+ wfCheckBox.setFont(new java.awt.Font("Dialog", 0, 12));
+ wfCheckBox.setText("Write Depth Buffer");
+ wfCheckBox.setToolTipText("Depth will be written for the object, if selected");
+ wfCheckBox.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ wfCheckBoxActionPerformed(evt);
+ }
+ });
+
+ jPanel1.add(wfCheckBox);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ getContentPane().add(jPanel1, gridBagConstraints);
+
+ jPanel2.setBorder(new javax.swing.border.TitledBorder("Shaded Object"));
+ jLabel3.setFont(new java.awt.Font("Dialog", 0, 12));
+ jLabel3.setText("Depth Function");
+ jLabel3.setToolTipText("Mode of shaded object");
+ jPanel2.add(jLabel3);
+
+ shadedComboBox.setFont(new java.awt.Font("Dialog", 0, 12));
+ shadedComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "ALWAYS", "NEVER", "EQUAL", "NOT_EQUAL", "LESS", "LESS_OR_EQUAL", "GREATER", "GREATER_OR_EQUAL" }));
+ shadedComboBox.setSelectedIndex(4);
+ shadedComboBox.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ shadedComboBoxActionPerformed(evt);
+ }
+ });
+
+ jPanel2.add(shadedComboBox);
+
+ shadedCheckBox.setFont(new java.awt.Font("Dialog", 0, 12));
+ shadedCheckBox.setSelected(true);
+ shadedCheckBox.setText("Write Depth Buffer");
+ shadedCheckBox.setToolTipText("Depth will be written for the object, if selected");
+ shadedCheckBox.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ shadedCheckBoxActionPerformed(evt);
+ }
+ });
+
+ jPanel2.add(shadedCheckBox);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ getContentPane().add(jPanel2, gridBagConstraints);
+
+ jPanel3.setBorder(new javax.swing.border.TitledBorder("Rotating Cube"));
+ jLabel4.setFont(new java.awt.Font("Dialog", 0, 12));
+ jLabel4.setText("Raster Operator");
+ jLabel4.setToolTipText("Raster mode of rotating object (try NOOP)");
+ jPanel3.add(jLabel4);
+
+ rotatingComboBox.setFont(new java.awt.Font("Dialog", 0, 12));
+ rotatingComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "CLEAR", "AND", "AND_REVERSE", "COPY", "AND_INVERTED", "NOOP", "XOR", "OR", "NOR", "EQUIV", "INVERT", "OR_REVERSE", "COPY_INVERTED", "OR_INVERTED", "NAND", "SET" }));
+ rotatingComboBox.setSelectedIndex(3);
+ rotatingComboBox.addActionListener(new java.awt.event.ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ rotatingComboBoxActionPerformed(evt);
+ }
+ });
+
+ jPanel3.add(rotatingComboBox);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ getContentPane().add(jPanel3, gridBagConstraints);
+
+ setBounds(0, 0, 403, 240);
+ }
+ // </editor-fold>//GEN-END:initComponents
+
+ private void rotatingComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_rotatingComboBoxActionPerformed
+ {//GEN-HEADEREND:event_rotatingComboBoxActionPerformed
+ String selectedItem = rotatingComboBox.getSelectedItem().toString(); // how to avoid a cast and all that goes with it. (lazyness)
+ int mode = RenderingAttributes.ROP_COPY;
+ if ( "CLEAR".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_CLEAR;
+ }
+ else if ( "AND".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_AND;
+ }
+ else if ( "AND_REVERSE".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_AND_REVERSE;
+ }
+ else if ( "COPY".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_COPY;
+ }
+ else if ( "AND_INVERTED".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_AND_INVERTED;
+ }
+ else if ( "NOOP".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_NOOP;
+ }
+ else if ( "XOR".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_XOR;
+ }
+ else if ( "OR".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_OR;
+ }
+ else if ( "NOR".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_NOR;
+ }
+ else if ( "EQUIV".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_EQUIV;
+ }
+ else if ( "INVERT".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_INVERT;
+ }
+ else if ( "OR_REVERSE".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_OR_REVERSE;
+ }
+ else if ( "COPY_INVERTED".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_COPY_INVERTED;
+ }
+ else if ( "OR_INVERTED".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_OR_INVERTED;
+ }
+ else if ( "NAND".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_NAND;
+ }
+ else if ( "SET".equals(selectedItem) )
+ {
+ mode = RenderingAttributes.ROP_SET;
+ }
+ else
+ {
+ System.out.println("oops. wrong mode in ROP combo: "+selectedItem);
+ }
+ rf.setRotatingObjectROPMode( mode );
+ }//GEN-LAST:event_rotatingComboBoxActionPerformed
+
+ private void shadedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_shadedCheckBoxActionPerformed
+ rf.setStaticObjectDBWriteStatus( shadedCheckBox.isSelected() );
+ }//GEN-LAST:event_shadedCheckBoxActionPerformed
+
+ private void wfCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_wfCheckBoxActionPerformed
+ rf.setStaticWFObjectDBWriteStatus( wfCheckBox.isSelected() );
+ }//GEN-LAST:event_wfCheckBoxActionPerformed
+
+ private void shadedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_shadedComboBoxActionPerformed
+ int func = RenderingAttributes.LESS_OR_EQUAL;
+ String selectedItem = shadedComboBox.getSelectedItem().toString(); // how to avoid a cast and all that goes with it. (lazyness)
+ rf.setStaticObjectTestFunc( getID( selectedItem ) );
+ }//GEN-LAST:event_shadedComboBoxActionPerformed
+
+ private void normalComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_normalComboBoxActionPerformed
+ int func = RenderingAttributes.LESS_OR_EQUAL;
+ String selectedItem = normalComboBox.getSelectedItem().toString(); // how to avoid a cast and all that goes with it. (lazyness)
+ rf.setStaticWFObjectTestFunc( getID( selectedItem ) );
+ }//GEN-LAST:event_normalComboBoxActionPerformed
+
+ int getID( String selectedItem )
+ {
+ int func = RenderingAttributes.LESS_OR_EQUAL;
+ if ( "LESS_OR_EQUAL".equals(selectedItem) )
+ {
+ func = RenderingAttributes.LESS_OR_EQUAL;
+ }
+ else if ( "NEVER".equals(selectedItem) )
+ {
+ func = RenderingAttributes.NEVER;
+ }
+ else if ( "ALWAYS".equals(selectedItem) )
+ {
+ func = RenderingAttributes.ALWAYS;
+ }
+ else if ( "GREATER".equals(selectedItem) )
+ {
+ func = RenderingAttributes.GREATER;
+ }
+ else if ( "GREATER_OR_EQUAL".equals(selectedItem) )
+ {
+ func = RenderingAttributes.GREATER_OR_EQUAL;
+ }
+ else if ( "LESS".equals(selectedItem) )
+ {
+ func = RenderingAttributes.LESS;
+ }
+ else if ( "EQUAL".equals(selectedItem) )
+ {
+ func = RenderingAttributes.EQUAL;
+ }
+ else if ( "NOT_EQUAL".equals(selectedItem) )
+ {
+ func = RenderingAttributes.NOT_EQUAL;
+ }
+ return func;
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ DepthFuncTest dpt = new DepthFuncTest();
+ dpt.rf = new RenderFrame( dpt );
+ dpt.setVisible(true);
+ dpt.rf.setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JLabel jLabel3;
+ private javax.swing.JLabel jLabel4;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JPanel jPanel3;
+ private javax.swing.JComboBox normalComboBox;
+ private javax.swing.JComboBox rotatingComboBox;
+ private javax.swing.JCheckBox shadedCheckBox;
+ private javax.swing.JComboBox shadedComboBox;
+ private javax.swing.JCheckBox wfCheckBox;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.form b/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.form
new file mode 100644
index 0000000..2edc4bb
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.form
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <Properties>
+ <Property name="defaultCloseOperation" type="int" value="3"/>
+ <Property name="title" type="java.lang.String" value="J3D frame"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="formSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-32,0,0,2,-128"/>
+ <SyntheticProperty name="formPosition" type="java.awt.Point" value="-84,-19,0,5,115,114,0,14,106,97,118,97,46,97,119,116,46,80,111,105,110,116,-74,-60,-118,114,52,126,-56,38,2,0,2,73,0,1,120,73,0,1,121,120,112,0,0,1,-112,0,0,0,0"/>
+ <SyntheticProperty name="formSizePolicy" type="int" value="0"/>
+ <SyntheticProperty name="generatePosition" type="boolean" value="true"/>
+ <SyntheticProperty name="generateSize" type="boolean" value="true"/>
+ <SyntheticProperty name="generateCenter" type="boolean" value="false"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-56,0,0,2,120"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.java b/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.java
new file mode 100644
index 0000000..5edc79d
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.java
@@ -0,0 +1,292 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.depth_func;
+
+import com.sun.j3d.utils.behaviors.mouse.*;
+import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
+import java.awt.GraphicsConfiguration;
+import javax.media.j3d.*;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.geometry.*;
+import javax.vecmath.*;
+
+
+public class RenderFrame extends javax.swing.JFrame {
+
+ DepthFuncTest dpt;
+
+ SimpleUniverse su;
+
+ RenderingAttributes staticWFBoxRA;
+ RenderingAttributes staticBoxRA;
+
+ RenderingAttributes rotatingBoxRA;
+
+ /** Creates new form RenderFrame */
+ public RenderFrame( DepthFuncTest _dpt) {
+ dpt = _dpt;
+ initComponents();
+ initUniverse();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents()
+ {
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("J3D frame");
+ setBounds(400, 0, 640, 480);
+ }
+ // </editor-fold>//GEN-END:initComponents
+
+ void initUniverse() {
+ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+ su = new SimpleUniverse(c);
+ su.addBranchGraph( createScene() );
+ c.getView().setMinimumFrameCycleTime( 10 );
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ // End of variables declaration//GEN-END:variables
+
+ BranchGroup createScene() {
+ BoundingSphere bounds = new BoundingSphere( new Point3d( 0.0, 0.0, 0.0 ), 100.0 );
+
+ BranchGroup globalBG = new BranchGroup();
+ BranchGroup rotObjectBG = new BranchGroup();
+ OrderedGroup staticObjectOG = new OrderedGroup();
+ BranchGroup lampsBG = new BranchGroup();
+ OrderedGroup oGroup = new OrderedGroup();
+ TransformGroup staticBoxRotTG = new TransformGroup();
+ staticBoxRotTG.addChild( staticObjectOG );
+ TransformGroup objectsTGRot = new TransformGroup();
+ TransformGroup objectsTGTrans = new TransformGroup();
+ Transform3D objectsTGTransT3d = new Transform3D();
+ objectsTGTransT3d.setTranslation( new Vector3f( 0.0f, 0.0f, -10.0f ) );
+ objectsTGTrans.setTransform( objectsTGTransT3d );
+ objectsTGRot.addChild( oGroup );
+ objectsTGTrans.addChild( objectsTGRot );
+ lampsBG.addChild( objectsTGTrans );
+
+ //adding a sphere as backgroung so there is something else than flat black, and cut cube removal as an other implication. (seeing through)
+ Appearance globalSphereAppearance = new Appearance();
+ PolygonAttributes globalSpherePA = new PolygonAttributes();
+ globalSpherePA.setCullFace( globalSpherePA.CULL_FRONT );// so that interior of the sphere is visible.
+ Material globalSphereMaterial = new Material();
+ globalSphereMaterial.setEmissiveColor( .25f ,.3f ,.35f );
+ globalSphereAppearance.setMaterial( globalSphereMaterial );
+ globalSphereAppearance.setPolygonAttributes( globalSpherePA );
+ Sphere globalSphere = new Sphere( 6.0f );
+ globalSphere.setAppearance( globalSphereAppearance );
+ globalSphere.setBounds( bounds );
+ oGroup.addChild( globalSphere );
+
+ globalBG.addChild( lampsBG );
+
+ // adding lamps.
+ PointLight frontLamp = new PointLight( new Color3f( 1.0f, 1.0f, 1.0f ), new Point3f( 20, 20, 20 ), new Point3f( 0.0f, .0f, 0.f ) );
+ lampsBG.addChild( frontLamp );
+ frontLamp.setBounds( bounds );
+ frontLamp.setInfluencingBounds( bounds );
+ PointLight backLamp = new PointLight( new Color3f( 1.0f, .0f, .0f ), new Point3f( -20, -20, -20 ), new Point3f( 0.0f, .0f, 0.f ) );
+ lampsBG.addChild( backLamp );
+ backLamp.setBounds( bounds );
+ backLamp.setInfluencingBounds( bounds );
+
+ //adding shapes.
+ {
+ //adding rotating and scaling cube
+ //doing the rotation
+ TransformGroup rotBoxTGRot = new TransformGroup();
+ rotBoxTGRot.setCapability( rotBoxTGRot.ALLOW_TRANSFORM_WRITE );
+ RotationInterpolator rotBoxRotInt = new RotationInterpolator( new Alpha( -1, 20000 ) , rotBoxTGRot );
+ rotBoxRotInt.setSchedulingBounds( bounds );
+ rotBoxRotInt.setBounds( bounds );
+
+ //doing the scaling
+ Transform3D scaleBoxt3d = new Transform3D();
+ TransformGroup rotBoxTGScale = new TransformGroup();
+ rotBoxTGScale.setCapability( rotBoxTGScale.ALLOW_TRANSFORM_WRITE );
+ ScaleInterpolator rotBoxScaleInt = new ScaleInterpolator( new Alpha( -1, Alpha.INCREASING_ENABLE|Alpha.DECREASING_ENABLE, 0, 0, 3000, 1500, 0, 3000, 1500, 0 ) , rotBoxTGScale, new Transform3D(), 0.7f, 1.6f );
+ rotBoxScaleInt.setSchedulingBounds( bounds );
+ rotBoxScaleInt.setBounds( bounds );
+
+ Appearance rotBoxApp = new Appearance();
+ Material rotBoxMat = new Material();
+ rotBoxMat.setDiffuseColor( .4f, .4f, .4f );
+ rotBoxApp.setMaterial( rotBoxMat );
+ Box rotBox = new Box( 1.1f, 1.1f, 1.1f, rotBoxApp );
+ rotBoxTGScale.addChild( rotBox );
+ rotBoxTGRot.addChild( rotBoxTGScale );
+ TransformGroup rotBoxTG = new TransformGroup();
+ rotBoxTG.addChild( rotBoxTGRot );
+ rotObjectBG.addChild( rotBoxTG );
+ rotObjectBG.addChild( rotBoxScaleInt );
+ rotObjectBG.addChild( rotBoxRotInt );
+ rotBox.setBounds( bounds );
+
+ rotatingBoxRA = new RenderingAttributes();
+ rotatingBoxRA.setRasterOpEnable( true );
+ rotatingBoxRA.setCapability( staticBoxRA.ALLOW_RASTER_OP_WRITE );
+// rotatingBoxRA.setRasterOp( rotatingBoxRA.ROP_XOR );
+ rotBoxApp.setRenderingAttributes( rotatingBoxRA );
+
+
+ rotBox.setAppearance( rotBoxApp );
+ }
+
+ //adding static back face wireframe cube
+ {
+ Box staticWFBoxBack = new Box( );
+ Appearance staticWFBoxApp = new Appearance();
+ Material staticWFBoxMat = new Material();
+ staticWFBoxMat.setDiffuseColor( 0.f, 0.f, 0.f );
+ staticWFBoxMat.setEmissiveColor( 0.f, .4f, 0.f );
+ staticWFBoxApp.setMaterial( staticWFBoxMat );
+ PolygonAttributes staticWFBoxPABack = new PolygonAttributes( PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_FRONT, 0.0f );
+ staticWFBoxApp.setPolygonAttributes( staticWFBoxPABack );
+ staticWFBoxRA = new RenderingAttributes();
+ staticWFBoxRA.setCapability( staticWFBoxRA.ALLOW_DEPTH_TEST_FUNCTION_WRITE );
+ staticWFBoxRA.setCapability( staticWFBoxRA.ALLOW_DEPTH_ENABLE_WRITE );
+ staticWFBoxRA.setDepthTestFunction( staticWFBoxRA.GREATER );
+ staticWFBoxRA.setDepthBufferWriteEnable( false );
+ staticWFBoxApp.setRenderingAttributes( staticWFBoxRA );
+ staticWFBoxBack.setAppearance( staticWFBoxApp );
+ staticWFBoxBack.setBounds( bounds );
+ staticObjectOG.addChild( staticWFBoxBack );
+ }
+
+ //adding static front face wireframe cube
+ {
+ Box staticWFBox = new Box( );
+ Appearance staticWFBoxApp = new Appearance();
+ Material staticWFBoxMat = new Material();
+ staticWFBoxMat.setDiffuseColor( 0.f, 0.f, 0.f );
+ staticWFBoxMat.setEmissiveColor( 0.f, 1.f, 0.f );
+ staticWFBoxApp.setMaterial( staticWFBoxMat );
+ PolygonAttributes staticWFBoxPA = new PolygonAttributes( PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_BACK, 0.0f );
+ staticWFBoxApp.setPolygonAttributes( staticWFBoxPA );
+ staticWFBoxApp.setRenderingAttributes( staticWFBoxRA );
+ staticWFBox.setAppearance( staticWFBoxApp );
+ staticWFBox.setBounds( bounds );
+ staticObjectOG.addChild( staticWFBox );
+ }
+
+
+ {// rotating the static cubes
+ Transform3D boxt3d = new Transform3D();
+ Transform3D tempt3d = new Transform3D();
+ boxt3d.rotZ( Math.PI/4.0f );
+ tempt3d.rotX( Math.PI/4.0f );
+ boxt3d.mul( tempt3d );
+ tempt3d.rotY( Math.PI/4.0f );
+ boxt3d.mul( tempt3d );
+ staticBoxRotTG.setTransform( boxt3d );
+ }
+
+ // adding static flat cube
+ {
+ Box staticBox = new Box( );
+ staticBox.setBounds( bounds );
+ Appearance boxApp = new Appearance();
+ Material boxMat = new Material();
+ boxMat.setDiffuseColor( .7f, .7f, .7f );
+ boxApp.setMaterial( boxMat );
+ staticBoxRA = new RenderingAttributes();
+ staticBoxRA.setCapability( staticBoxRA.ALLOW_DEPTH_TEST_FUNCTION_WRITE );
+ staticBoxRA.setCapability( staticBoxRA.ALLOW_DEPTH_ENABLE_WRITE );
+ staticBoxRA.setDepthTestFunction( staticBoxRA.LESS );
+ staticBoxRA.setDepthBufferWriteEnable( false );
+ boxApp.setRenderingAttributes( staticBoxRA );
+ staticBox.setAppearance( boxApp );
+ staticObjectOG.addChild( staticBox );
+ }
+ oGroup.addChild( rotObjectBG );
+ oGroup.addChild( staticBoxRotTG );
+
+ //adding the mouse rotate behavior to the group of cubes.
+ MouseRotate behavior = new MouseRotate();
+ behavior.setTransformGroup( objectsTGRot );
+ objectsTGRot.addChild( behavior );
+ objectsTGRot.setCapability( objectsTGRot.ALLOW_TRANSFORM_READ );
+ objectsTGRot.setCapability( objectsTGRot.ALLOW_TRANSFORM_WRITE );
+ behavior.setSchedulingBounds(bounds);
+ return globalBG;
+ }
+
+ public void setStaticWFObjectTestFunc( int func )
+ {
+ staticWFBoxRA.setDepthTestFunction( func );
+ }
+
+ public void setStaticObjectTestFunc( int func )
+ {
+ staticBoxRA.setDepthTestFunction( func );
+ }
+
+ public void setStaticWFObjectDBWriteStatus( boolean status )
+ {
+ staticWFBoxRA.setDepthBufferWriteEnable( status );
+ }
+
+ public void setStaticObjectDBWriteStatus( boolean status )
+ {
+ staticBoxRA.setDepthBufferWriteEnable( status );
+ }
+
+ public void setRotatingObjectROPMode( int mode )
+ {
+ rotatingBoxRA.setRasterOp( mode );
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java b/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java
new file mode 100644
index 0000000..134a128
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java
@@ -0,0 +1,194 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.distort_glyph;
+
+import java.util.Enumeration;
+
+import javax.media.j3d.Appearance;
+import javax.media.j3d.Behavior;
+import javax.media.j3d.GeometryArray;
+import javax.media.j3d.Shape3D;
+import javax.media.j3d.Transform3D;
+import javax.media.j3d.WakeupCondition;
+import javax.media.j3d.WakeupCriterion;
+import javax.media.j3d.WakeupOnElapsedFrames;
+import javax.media.j3d.WakeupOnElapsedTime;
+
+import javax.vecmath.Vector3f;
+
+public class DistortBehavior extends Behavior {
+ // the wake up condition for the behavior
+ protected WakeupCondition m_InitialWakeupCondition = null;
+ protected WakeupCondition m_FrameWakeupCondition = null;
+
+ // the GeometryArray for the Shape3D that we are modifying
+ protected Shape3D m_Shape3D = null;
+ protected GeometryArray m_GeometryArray = null;
+
+ protected float[] m_CoordinateArray = null;
+ protected float[] m_OriginalCoordinateArray = null;
+ protected Appearance m_Appearance = null;
+
+ protected int m_nElapsedTime = 0;
+ protected int m_nNumFrames = 0;
+ protected int m_nFrameNumber = 0;
+
+ private int frame = 0;
+ protected Vector3f m_Vector = null;
+
+ public DistortBehavior(Shape3D shape3D, int nElapsedTime, int nNumFrames) {
+ // allocate a temporary vector
+ m_Vector = new Vector3f();
+
+ m_FrameWakeupCondition = new WakeupOnElapsedFrames(0);
+
+ restart(shape3D, nElapsedTime, nNumFrames);
+ }
+
+ public WakeupCondition restart(Shape3D shape3D, int nElapsedTime, int nNumFrames) {
+ m_Shape3D = shape3D;
+ m_nElapsedTime = nElapsedTime;
+ m_nNumFrames = nNumFrames;
+ m_nFrameNumber = 0;
+
+ // create the WakeupCriterion for the behavior
+ m_InitialWakeupCondition = new WakeupOnElapsedTime(m_nElapsedTime);
+
+ // save the GeometryArray that we are modifying
+ m_GeometryArray = (GeometryArray) m_Shape3D.getGeometry();
+
+ if (m_Shape3D.isLive() == false && m_Shape3D.isCompiled() == false) {
+ // set the capability bits that the behavior requires
+ m_Shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ m_Shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+
+ m_Shape3D.getAppearance().setCapability(Appearance.ALLOW_POINT_ATTRIBUTES_WRITE);
+ m_Shape3D.getAppearance().setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_WRITE);
+ m_Shape3D.getAppearance().setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE);
+ m_Shape3D.getAppearance().setCapability(Appearance.ALLOW_TEXTURE_WRITE);
+
+ m_GeometryArray.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
+ m_GeometryArray.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE);
+ m_GeometryArray.setCapability(GeometryArray.ALLOW_COUNT_READ);
+ }
+
+ // make a copy of the object's original appearance
+ m_Appearance = new Appearance();
+ m_Appearance = (Appearance) m_Shape3D.getAppearance().cloneNodeComponent(true);
+
+ // allocate an array for the model coordinates
+ m_CoordinateArray = new float[3 * m_GeometryArray.getVertexCount()];
+
+ // make a copy of the models original coordinates
+ m_OriginalCoordinateArray = new float[3 * m_GeometryArray.getVertexCount()];
+ m_GeometryArray.getCoordinates(0, m_OriginalCoordinateArray);
+
+ // start (or restart) the behavior
+ setEnable(true);
+
+ return m_InitialWakeupCondition;
+ }
+
+ public void initialize() {
+ // apply the initial WakeupCriterion
+ wakeupOn(m_InitialWakeupCondition);
+ }
+
+ public void processStimulus(Enumeration criteria) {
+ while (criteria.hasMoreElements()) {
+ WakeupCriterion wakeUp = (WakeupCriterion) criteria.nextElement();
+
+ if (wakeUp instanceof WakeupOnElapsedTime) {
+ } else {
+ // we are mid explosion, modify the GeometryArray
+ m_nFrameNumber++;
+ frame++;
+ m_GeometryArray.getCoordinates(0, m_CoordinateArray);
+
+ Transform3D t3 = new Transform3D();
+ for (int n = 0; n < m_CoordinateArray.length; n += 3) {
+ m_Vector.x = m_OriginalCoordinateArray[n];
+ m_Vector.y = m_OriginalCoordinateArray[n + 1];
+ m_Vector.z = m_OriginalCoordinateArray[n + 2];
+
+ float spx = (float) (Math.sin(frame *3f / 500));
+ float spy = (float) (Math.cos(frame *5f / 500));
+ Vector3f v = new Vector3f(spx, spy, 0);
+
+ float px = (m_Vector.x - v.x);
+ float py = (m_Vector.y - v.y);
+ float pz = (m_Vector.z - v.z);
+ float d = (float) Math.sqrt(px * px + py * py + pz * pz);
+
+
+ m_Vector.add(new Vector3f(-.25f, -.25f, -.25f));
+ //m_Vector.scale(d);
+
+ t3.rotZ(d);
+ t3.rotX(d*2);
+ t3.rotY(d);
+ t3.transform(m_Vector);
+
+ m_CoordinateArray[n] = m_Vector.x;
+ m_CoordinateArray[n + 1] = m_Vector.y;
+ m_CoordinateArray[n + 2] = m_Vector.z;
+
+ }
+
+ // assign the new coordinates
+ m_GeometryArray.setCoordinates(0, m_CoordinateArray);
+ }
+ }
+
+ if (m_nFrameNumber < m_nNumFrames) {
+ // assign the next WakeUpCondition, so we are notified again
+ wakeupOn(m_FrameWakeupCondition);
+ } else {
+ // restart
+ m_nFrameNumber = 0;
+ wakeupOn(m_FrameWakeupCondition);
+ }
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java b/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java
new file mode 100644
index 0000000..afada2e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java
@@ -0,0 +1,210 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.distort_glyph;
+
+import java.applet.Applet;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+
+import javax.media.j3d.AmbientLight;
+import javax.media.j3d.Appearance;
+import javax.media.j3d.BoundingSphere;
+import javax.media.j3d.BranchGroup;
+import javax.media.j3d.Canvas3D;
+import javax.media.j3d.DirectionalLight;
+import javax.media.j3d.Font3D;
+import javax.media.j3d.FontExtrusion;
+import javax.media.j3d.GeometryArray;
+import javax.media.j3d.GraphicsConfigTemplate3D;
+import javax.media.j3d.Light;
+import javax.media.j3d.Material;
+import javax.media.j3d.PointLight;
+import javax.media.j3d.Shape3D;
+import javax.media.j3d.TexCoordGeneration;
+import javax.media.j3d.Texture;
+import javax.media.j3d.TransformGroup;
+
+import javax.vecmath.Color3f;
+import javax.vecmath.Point3d;
+import javax.vecmath.Point3f;
+import javax.vecmath.Vector3f;
+
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
+import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
+import com.sun.j3d.utils.behaviors.mouse.MouseZoom;
+import com.sun.j3d.utils.image.TextureLoader;
+import com.sun.j3d.utils.universe.SimpleUniverse;
+
+public class DistortGlyphTest extends Applet {
+ // get a nice graphics config
+ private static GraphicsConfiguration getGraphicsConfig() {
+ GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
+ template.setSceneAntialiasing(GraphicsConfigTemplate3D.PREFERRED);
+ GraphicsConfiguration gcfg = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(template);
+ return gcfg;
+ }
+
+ private void setupLights(BranchGroup root) {
+ // set up the BoundingSphere for all the lights
+ BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);
+
+ // Set up the ambient light
+ AmbientLight lightAmbient = new AmbientLight(new Color3f(0.37f, 0.37f, 0.37f));
+ lightAmbient.setInfluencingBounds(bounds);
+ root.addChild(lightAmbient);
+
+ // Set up the directional light
+ Vector3f lightDirection1 = new Vector3f(0.0f, 0.0f, -1.0f);
+ DirectionalLight lightDirectional1 = new DirectionalLight(new Color3f(1.00f, 0.10f, 0.00f), lightDirection1);
+ lightDirectional1.setInfluencingBounds(bounds);
+ lightDirectional1.setCapability(Light.ALLOW_STATE_WRITE);
+ root.addChild(lightDirectional1);
+
+ Point3f lightPos1 = new Point3f(-4.0f, 8.0f, 16.0f);
+ Point3f lightAttenuation1 = new Point3f(1.0f, 0.0f, 0.0f);
+ PointLight pointLight1 = new PointLight(new Color3f(0.37f, 1.00f, 0.37f), lightPos1, lightAttenuation1);
+ pointLight1.setInfluencingBounds(bounds);
+ root.addChild(pointLight1);
+
+ Point3f lightPos2 = new Point3f(-16.0f, 8.0f, 4.0f);
+ Point3f lightAttenuation2 = new Point3f(1.0f, 0.0f, 0.0f);
+ PointLight pointLight2 = new PointLight(new Color3f(0.37f, 0.37f, 1.00f), lightPos2, lightAttenuation2);
+ pointLight2.setInfluencingBounds(bounds);
+ root.addChild(pointLight2);
+ }
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ setupLights(objRoot);
+
+ TransformGroup objTransform = new TransformGroup();
+ objTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+
+ objRoot.addChild(objTransform);
+
+ // setup a nice textured appearance
+ Appearance app = new Appearance();
+ Color3f objColor = new Color3f(1.0f, 0.7f, 0.8f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor, black, 80.0f));
+ Texture txtr = new TextureLoader("gold.jpg",this).getTexture();
+ app.setTexture(txtr);
+ TexCoordGeneration tcg = new TexCoordGeneration(TexCoordGeneration.SPHERE_MAP,TexCoordGeneration.TEXTURE_COORDINATE_2);
+ app.setTexCoordGeneration(tcg);
+
+ // use a customized FontExtrusion object to control the depth of the text
+ java.awt.geom.GeneralPath gp = new java.awt.geom.GeneralPath();
+ gp.moveTo(0, 0);
+ gp.lineTo(.01f, .01f);
+ gp.lineTo(.2f, .01f);
+ gp.lineTo(.21f, 0f);
+ FontExtrusion fontEx = new FontExtrusion(gp);
+
+ // our glyph
+ Font fnt = new Font("dialog", Font.BOLD, 1);
+ Font3D f3d = new Font3D(fnt, .001, fontEx);
+ GeometryArray geom = f3d.getGlyphGeometry('A');
+ Shape3D shape = new Shape3D(geom, app);
+ objTransform.addChild(shape);
+
+ // the DistortBehavior
+ DistortBehavior eb = new DistortBehavior(shape, 1000, 1000);
+ eb.setSchedulingBounds(new BoundingSphere());
+ objTransform.addChild(eb);
+
+ MouseRotate myMouseRotate = new MouseRotate();
+ myMouseRotate.setTransformGroup(objTransform);
+ myMouseRotate.setSchedulingBounds(new BoundingSphere());
+ objRoot.addChild(myMouseRotate);
+
+ MouseTranslate myMouseTranslate = new MouseTranslate();
+ myMouseTranslate.setTransformGroup(objTransform);
+ myMouseTranslate.setSchedulingBounds(new BoundingSphere());
+ objRoot.addChild(myMouseTranslate);
+
+ MouseZoom myMouseZoom = new MouseZoom();
+ myMouseZoom.setTransformGroup(objTransform);
+ myMouseZoom.setSchedulingBounds(new BoundingSphere());
+ objRoot.addChild(myMouseZoom);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ // Create a simple scene and attach it to the virtual universe
+ public DistortGlyphTest() {
+ //setLayout(new BorderLayout());
+ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D canvas3D = new Canvas3D(getGraphicsConfig());
+ canvas3D.setBounds(0, 0, 800, 600);
+ add("Center", canvas3D);
+
+ BranchGroup scene = createSceneGraph();
+
+ // SimpleUniverse is a Convenience Utility class
+ SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ simpleU.getViewingPlatform().setNominalViewingTransform();
+
+ simpleU.addBranchGraph(scene);
+ }
+
+ // The following allows this to be run as an application
+ // as well as an applet
+ public static void main(String[] args) {
+ Frame frame = new MainFrame(new DistortGlyphTest(), 800, 600);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/BigCube.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/BigCube.java
new file mode 100644
index 0000000..9937c62
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/BigCube.java
@@ -0,0 +1,140 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import java.applet.Applet;
+import java.awt.event.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+/**
+ * Class BigCube
+ *
+ * Description: Creates the "big" cube used to mark the computer's
+ * position.
+ *
+ * Version: 1.0
+ */
+public class BigCube extends Object {
+
+ private Shape3D shape3D;
+
+ private static final float[] verts = {
+ // Front Face
+ 5.0f, -5.0f, 5.0f, 5.0f, 5.0f, 5.0f,
+ -5.0f, 5.0f, 5.0f, -5.0f, -5.0f, 5.0f,
+ // Back Face
+ -5.0f, -5.0f, -5.0f, -5.0f, 5.0f, -5.0f,
+ 5.0f, 5.0f, -5.0f, 5.0f, -5.0f, -5.0f,
+ // Right Face
+ 5.0f, -5.0f, -5.0f, 5.0f, 5.0f, -5.0f,
+ 5.0f, 5.0f, 5.0f, 5.0f, -5.0f, 5.0f,
+ // Left Face
+ -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, 5.0f,
+ -5.0f, 5.0f, -5.0f, -5.0f, -5.0f, -5.0f,
+ // Top Face
+ 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, -5.0f,
+ -5.0f, 5.0f, -5.0f, -5.0f, 5.0f, 5.0f,
+ // Bottom Face
+ -5.0f, -5.0f, 5.0f, -5.0f, -5.0f, -5.0f,
+ 5.0f, -5.0f, -5.0f, 5.0f, -5.0f, 5.0f,
+ };
+
+ private static final float[] normals = {
+ // Front Face
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ // Back Face
+ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ // Right Face
+ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+ // Left Face
+ -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
+ // Top Face
+ 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+ // Bottom Face
+ 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
+ };
+
+ public BigCube(Appearance appearance) {
+
+ QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES |
+ QuadArray.NORMALS );
+ quadArray.setCoordinates(0, verts);
+ quadArray.setNormals(0, normals);
+
+ shape3D = new Shape3D(quadArray, appearance);
+ shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
+ shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ }
+
+ public BigCube(Appearance appearance, float size) {
+
+ QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES |
+ QuadArray.NORMALS );
+
+ for (int i=0; i<72; i++) verts[i] *= size;
+
+ quadArray.setCoordinates(0, verts);
+ quadArray.setNormals(0, normals);
+
+ shape3D = new Shape3D(quadArray, appearance);
+ shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
+ shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ }
+
+ public Shape3D getChild() {
+ return shape3D;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/Board.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/Board.java
new file mode 100644
index 0000000..53aa71e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/Board.java
@@ -0,0 +1,2312 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import java.awt.*;
+
+/**
+ * Class: Board
+ *
+ * Description: Handles all logic with respect to play. Also renders
+ * the 2D window.
+ *
+ * Version: 1.1
+ *
+ */
+class Board {
+
+ final static int UNOCCUPIED = 0;
+ final static int HUMAN = 1;
+ final static int MACHINE = 2;
+ final static int END = 3;
+
+ private int[] moves;
+ private int[] occupied;
+ private int[][] combinations;
+ private int[][] outside_four;
+ private int[][] inside_four;
+ private int[][] faces;
+ private int[][] pos_to_comb;
+ private int[][] best_picks;
+ private int num_points;
+ private int num_balls;
+ private int num_polygons;
+ private int num_pt_indexes;
+ private int num_normal_indexes;
+ private int pt_start;
+ private int color_index;
+ private int width;
+ private int height;
+ private int center_x;
+ private int center_y;
+ private int player;
+ private int skill_level;
+ private int outside_four_index;
+ private int inside_four_index;
+ private int face_index;
+ private int nmoves;
+ private int current_face;
+ private int min = 1000;
+ private int max = 0;
+ private long[] sort_array;
+ private long time;
+ private long beg_time;
+ private long end_time;
+ private Color[] color_ramp;
+ private Color background;
+ private Color label_color;
+ private Color red;
+ private Color blue;
+ private Color white;
+ private Color gray;
+ private Color yellow;
+ private double max_dist;
+ private FourByFour panel;
+ private boolean debug;
+ private boolean outside_four_flag;
+ private boolean inside_four_flag;
+ private boolean face_flag;
+ private boolean label_flag;
+ private boolean block_chair_flag;
+ private boolean undoFlag;
+ private boolean[] highlight;
+ private int block_chair_next_move;
+ private int block_chair_face;
+ private Positions positions;
+ private Canvas2D canvas;
+
+ Board (FourByFour panel, Positions positions, int width, int height) {
+
+ // Set the debug state.
+ debug = false;
+
+ // Store arguments
+ this.width = width;
+ this.height = height;
+ this.panel = panel;
+ this.positions = positions;
+
+ // Initialize flags
+ label_flag = false;
+ outside_four_flag = false;
+ inside_four_flag = false;
+ block_chair_flag = false;
+ undoFlag = false;
+
+ // Total number of board positions.
+ num_points = 64;
+
+ // Allocate the logic arrays.
+ moves = new int[64];
+ occupied = new int[64];
+ combinations = new int[76][7];
+ outside_four = new int[18][6];
+ inside_four = new int[18][6];
+ faces = new int[18][18];
+ pos_to_comb = new int[64][8];
+ best_picks = new int[64][8];
+ highlight = new boolean[18];
+
+ // Initialize the logic arrays.
+ init_combinations();
+ init_faces();
+ init_outside_four();
+ init_inside_four();
+
+ // Set the player with the first move.
+ player = HUMAN;
+
+ // Set the default skill level.
+ skill_level = 4;
+
+ // Initialize the number of moves.
+ nmoves = 0;
+
+ // Define colors
+ background = new Color(13, 13, 51);
+ red = new Color(230, 26, 51);
+ blue = new Color(51, 51, 230);
+ white = new Color(255, 255, 255);
+ gray = new Color(240, 240, 240);
+ yellow = new Color(240, 240, 0);
+
+ // Record the start time
+ beg_time = System.currentTimeMillis();
+ }
+
+ public void setCanvas(Canvas2D canvas) {
+ this.canvas = canvas;
+ }
+
+ public void init_combinations () {
+
+ // The combination array contains all possible winning combinations.
+ //
+ // Each combination has the following format:
+ //
+ // combinations[x][0] = status: 0 = no player has selected positons in this row
+ // -1 = both players have men in this row
+ // 1 to 4 = number of positions occupied by player
+ //
+ // combinations[x][1] = player who owns this row (valid only if status = 1-4)
+ // combinations[x][2] = postion that define the row
+ // combinations[x][3] = postion that define the row
+ // combinations[x][4] = postion that define the row
+ // combinations[x][5] = postion that define the row
+
+ // Horizontal, Z
+
+ combinations[ 0][0] = 0; combinations[ 1][0] = 0; combinations[ 2][0] = 0; combinations[ 3][0] = 0;
+ combinations[ 0][1] = 0; combinations[ 1][1] = 0; combinations[ 2][1] = 0; combinations[ 3][1] = 0;
+ combinations[ 0][2] = 0; combinations[ 1][2] = 4; combinations[ 2][2] = 8; combinations[ 3][2] = 12;
+ combinations[ 0][3] = 1; combinations[ 1][3] = 5; combinations[ 2][3] = 9; combinations[ 3][3] = 13;
+ combinations[ 0][4] = 2; combinations[ 1][4] = 6; combinations[ 2][4] = 10; combinations[ 3][4] = 14;
+ combinations[ 0][5] = 3; combinations[ 1][5] = 7; combinations[ 2][5] = 11; combinations[ 3][5] = 15;
+
+ combinations[ 4][0] = 0; combinations[ 5][0] = 0; combinations[ 6][0] = 0; combinations[ 7][0] = 0;
+ combinations[ 4][1] = 0; combinations[ 5][1] = 0; combinations[ 6][1] = 0; combinations[ 7][1] = 0;
+ combinations[ 4][2] = 16; combinations[ 5][2] = 20; combinations[ 6][2] = 24; combinations[ 7][2] = 28;
+ combinations[ 4][3] = 17; combinations[ 5][3] = 21; combinations[ 6][3] = 25; combinations[ 7][3] = 29;
+ combinations[ 4][4] = 18; combinations[ 5][4] = 22; combinations[ 6][4] = 26; combinations[ 7][4] = 30;
+ combinations[ 4][5] = 19; combinations[ 5][5] = 23; combinations[ 6][5] = 27; combinations[ 7][5] = 31;
+
+ combinations[ 8][0] = 0; combinations[ 9][0] = 0; combinations[10][0] = 0; combinations[11][0] = 0;
+ combinations[ 8][1] = 0; combinations[ 9][1] = 0; combinations[10][1] = 0; combinations[11][1] = 0;
+ combinations[ 8][2] = 32; combinations[ 9][2] = 36; combinations[10][2] = 40; combinations[11][2] = 44;
+ combinations[ 8][3] = 33; combinations[ 9][3] = 37; combinations[10][3] = 41; combinations[11][3] = 45;
+ combinations[ 8][4] = 34; combinations[ 9][4] = 38; combinations[10][4] = 42; combinations[11][4] = 46;
+ combinations[ 8][5] = 35; combinations[ 9][5] = 39; combinations[10][5] = 43; combinations[11][5] = 47;
+
+ combinations[12][0] = 0; combinations[13][0] = 0; combinations[14][0] = 0; combinations[15][0] = 0;
+ combinations[12][1] = 0; combinations[13][1] = 0; combinations[14][1] = 0; combinations[15][1] = 0;
+ combinations[12][2] = 48; combinations[13][2] = 52; combinations[14][2] = 56; combinations[15][2] = 60;
+ combinations[12][3] = 49; combinations[13][3] = 53; combinations[14][3] = 57; combinations[15][3] = 61;
+ combinations[12][4] = 50; combinations[13][4] = 54; combinations[14][4] = 58; combinations[15][4] = 62;
+ combinations[12][5] = 51; combinations[13][5] = 55; combinations[14][5] = 59; combinations[15][5] = 63;
+
+ // Vertical, Z
+
+ combinations[16][0] = 0; combinations[17][0] = 0; combinations[18][0] = 0; combinations[19][0] = 0;
+ combinations[16][1] = 0; combinations[17][1] = 0; combinations[18][1] = 0; combinations[19][1] = 0;
+ combinations[16][2] = 0; combinations[17][2] = 1; combinations[18][2] = 2; combinations[19][2] = 3;
+ combinations[16][3] = 4; combinations[17][3] = 5; combinations[18][3] = 6; combinations[19][3] = 7;
+ combinations[16][4] = 8; combinations[17][4] = 9; combinations[18][4] = 10; combinations[19][4] = 11;
+ combinations[16][5] = 12; combinations[17][5] = 13; combinations[18][5] = 14; combinations[19][5] = 15;
+
+ combinations[20][0] = 0; combinations[21][0] = 0; combinations[22][0] = 0; combinations[23][0] = 0;
+ combinations[20][1] = 0; combinations[21][1] = 0; combinations[22][1] = 0; combinations[23][1] = 0;
+ combinations[20][2] = 16; combinations[21][2] = 17; combinations[22][2] = 18; combinations[23][2] = 19;
+ combinations[20][3] = 20; combinations[21][3] = 21; combinations[22][3] = 22; combinations[23][3] = 23;
+ combinations[20][4] = 24; combinations[21][4] = 25; combinations[22][4] = 26; combinations[23][4] = 27;
+ combinations[20][5] = 28; combinations[21][5] = 29; combinations[22][5] = 30; combinations[23][5] = 31;
+
+ combinations[24][0] = 0; combinations[25][0] = 0; combinations[26][0] = 0; combinations[27][0] = 0;
+ combinations[24][1] = 0; combinations[25][1] = 0; combinations[26][1] = 0; combinations[27][1] = 0;
+ combinations[24][2] = 32; combinations[25][2] = 33; combinations[26][2] = 34; combinations[27][2] = 35;
+ combinations[24][3] = 36; combinations[25][3] = 37; combinations[26][3] = 38; combinations[27][3] = 39;
+ combinations[24][4] = 40; combinations[25][4] = 41; combinations[26][4] = 42; combinations[27][4] = 43;
+ combinations[24][5] = 44; combinations[25][5] = 45; combinations[26][5] = 46; combinations[27][5] = 47;
+
+ combinations[28][0] = 0; combinations[29][0] = 0; combinations[30][0] = 0; combinations[31][0] = 0;
+ combinations[28][1] = 0; combinations[29][1] = 0; combinations[30][1] = 0; combinations[31][1] = 0;
+ combinations[28][2] = 48; combinations[29][2] = 49; combinations[30][2] = 50; combinations[31][2] = 51;
+ combinations[28][3] = 52; combinations[29][3] = 53; combinations[30][3] = 54; combinations[31][3] = 55;
+ combinations[28][4] = 56; combinations[29][4] = 57; combinations[30][4] = 58; combinations[31][4] = 59;
+ combinations[28][5] = 60; combinations[29][5] = 61; combinations[30][5] = 62; combinations[31][5] = 63;
+
+ // Diagonal, Z
+
+ combinations[32][0] = 0; combinations[33][0] = 0; combinations[34][0] = 0; combinations[35][0] = 0;
+ combinations[32][1] = 0; combinations[33][1] = 0; combinations[34][1] = 0; combinations[35][1] = 0;
+ combinations[32][2] = 0; combinations[33][2] = 16; combinations[34][2] = 32; combinations[35][2] = 48;
+ combinations[32][3] = 5; combinations[33][3] = 21; combinations[34][3] = 37; combinations[35][3] = 53;
+ combinations[32][4] = 10; combinations[33][4] = 26; combinations[34][4] = 42; combinations[35][4] = 58;
+ combinations[32][5] = 15; combinations[33][5] = 31; combinations[34][5] = 47; combinations[35][5] = 63;
+
+ combinations[36][0] = 0; combinations[37][0] = 0; combinations[38][0] = 0; combinations[39][0] = 0;
+ combinations[36][1] = 0; combinations[37][1] = 0; combinations[38][1] = 0; combinations[39][1] = 0;
+ combinations[36][2] = 3; combinations[37][2] = 19; combinations[38][2] = 35; combinations[39][2] = 51;
+ combinations[36][3] = 6; combinations[37][3] = 22; combinations[38][3] = 38; combinations[39][3] = 54;
+ combinations[36][4] = 9; combinations[37][4] = 25; combinations[38][4] = 41; combinations[39][4] = 57;
+ combinations[36][5] = 12; combinations[37][5] = 28; combinations[38][5] = 44; combinations[39][5] = 60;
+
+ // Horizontal, X
+
+ combinations[40][0] = 0; combinations[41][0] = 0; combinations[42][0] = 0; combinations[43][0] = 0;
+ combinations[40][1] = 0; combinations[41][1] = 0; combinations[42][1] = 0; combinations[43][1] = 0;
+ combinations[40][2] = 51; combinations[41][2] = 55; combinations[42][2] = 59; combinations[43][2] = 63;
+ combinations[40][3] = 35; combinations[41][3] = 39; combinations[42][3] = 43; combinations[43][3] = 47;
+ combinations[40][4] = 19; combinations[41][4] = 23; combinations[42][4] = 27; combinations[43][4] = 31;
+ combinations[40][5] = 3; combinations[41][5] = 7; combinations[42][5] = 11; combinations[43][5] = 15;
+
+ combinations[44][0] = 0; combinations[45][0] = 0; combinations[46][0] = 0; combinations[47][0] = 0;
+ combinations[44][1] = 0; combinations[45][1] = 0; combinations[46][1] = 0; combinations[47][1] = 0;
+ combinations[44][2] = 50; combinations[45][2] = 54; combinations[46][2] = 58; combinations[47][2] = 62;
+ combinations[44][3] = 34; combinations[45][3] = 38; combinations[46][3] = 42; combinations[47][3] = 46;
+ combinations[44][4] = 18; combinations[45][4] = 22; combinations[46][4] = 26; combinations[47][4] = 30;
+ combinations[44][5] = 2; combinations[45][5] = 6; combinations[46][5] = 10; combinations[47][5] = 14;
+
+ combinations[48][0] = 0; combinations[49][0] = 0; combinations[50][0] = 0; combinations[51][0] = 0;
+ combinations[48][1] = 0; combinations[49][1] = 0; combinations[50][1] = 0; combinations[51][1] = 0;
+ combinations[48][2] = 49; combinations[49][2] = 53; combinations[50][2] = 57; combinations[51][2] = 61;
+ combinations[48][3] = 33; combinations[49][3] = 37; combinations[50][3] = 41; combinations[51][3] = 45;
+ combinations[48][4] = 17; combinations[49][4] = 21; combinations[50][4] = 25; combinations[51][4] = 29;
+ combinations[48][5] = 1; combinations[49][5] = 5; combinations[50][5] = 9; combinations[51][5] = 13;
+
+ combinations[52][0] = 0; combinations[53][0] = 0; combinations[54][0] = 0; combinations[55][0] = 0;
+ combinations[52][1] = 0; combinations[53][1] = 0; combinations[54][1] = 0; combinations[55][1] = 0;
+ combinations[52][2] = 48; combinations[53][2] = 52; combinations[54][2] = 56; combinations[55][2] = 60;
+ combinations[52][3] = 32; combinations[53][3] = 36; combinations[54][3] = 40; combinations[55][3] = 44;
+ combinations[52][4] = 16; combinations[53][4] = 20; combinations[54][4] = 24; combinations[55][4] = 28;
+ combinations[52][5] = 0; combinations[53][5] = 4; combinations[54][5] = 8; combinations[55][5] = 12;
+
+ // Diagonal, X
+
+ combinations[56][0] = 0; combinations[57][0] = 0; combinations[58][0] = 0; combinations[59][0] = 0;
+ combinations[56][1] = 0; combinations[57][1] = 0; combinations[58][1] = 0; combinations[59][1] = 0;
+ combinations[56][2] = 51; combinations[57][2] = 50; combinations[58][2] = 49; combinations[59][2] = 48;
+ combinations[56][3] = 39; combinations[57][3] = 38; combinations[58][3] = 37; combinations[59][3] = 36;
+ combinations[56][4] = 27; combinations[57][4] = 26; combinations[58][4] = 25; combinations[59][4] = 24;
+ combinations[56][5] = 15; combinations[57][5] = 14; combinations[58][5] = 13; combinations[59][5] = 12;
+
+ combinations[60][0] = 0; combinations[61][0] = 0; combinations[62][0] = 0; combinations[63][0] = 0;
+ combinations[60][1] = 0; combinations[61][1] = 0; combinations[62][1] = 0; combinations[63][1] = 0;
+ combinations[60][2] = 3; combinations[61][2] = 2; combinations[62][2] = 1; combinations[63][2] = 0;
+ combinations[60][3] = 23; combinations[61][3] = 22; combinations[62][3] = 21; combinations[63][3] = 20;
+ combinations[60][4] = 43; combinations[61][4] = 42; combinations[62][4] = 41; combinations[63][4] = 40;
+ combinations[60][5] = 63; combinations[61][5] = 62; combinations[62][5] = 61; combinations[63][5] = 60;
+
+ // Diagonal, Y
+
+ combinations[64][0] = 0; combinations[65][0] = 0; combinations[66][0] = 0; combinations[67][0] = 0;
+ combinations[64][1] = 0; combinations[65][1] = 0; combinations[66][1] = 0; combinations[67][1] = 0;
+ combinations[64][2] = 63; combinations[65][2] = 59; combinations[66][2] = 55; combinations[67][2] = 51;
+ combinations[64][3] = 46; combinations[65][3] = 42; combinations[66][3] = 38; combinations[67][3] = 34;
+ combinations[64][4] = 29; combinations[65][4] = 25; combinations[66][4] = 21; combinations[67][4] = 17;
+ combinations[64][5] = 12; combinations[65][5] = 8; combinations[66][5] = 4; combinations[67][5] = 0;
+
+ combinations[68][0] = 0; combinations[69][0] = 0; combinations[70][0] = 0; combinations[71][0] = 0;
+ combinations[68][1] = 0; combinations[69][1] = 0; combinations[70][1] = 0; combinations[71][1] = 0;
+ combinations[68][2] = 15; combinations[69][2] = 11; combinations[70][2] = 7; combinations[71][2] = 3;
+ combinations[68][3] = 30; combinations[69][3] = 26; combinations[70][3] = 22; combinations[71][3] = 18;
+ combinations[68][4] = 45; combinations[69][4] = 41; combinations[70][4] = 37; combinations[71][4] = 33;
+ combinations[68][5] = 60; combinations[69][5] = 56; combinations[70][5] = 52; combinations[71][5] = 48;
+
+ // Corner to Corner
+
+ combinations[72][0] = 0; combinations[73][0] = 0; combinations[74][0] = 0; combinations[75][0] = 0;
+ combinations[72][1] = 0; combinations[73][1] = 0; combinations[74][1] = 0; combinations[75][1] = 0;
+ combinations[72][2] = 0; combinations[73][2] = 3; combinations[74][2] = 12; combinations[75][2] = 15;
+ combinations[72][3] = 21; combinations[73][3] = 22; combinations[74][3] = 25; combinations[75][3] = 26;
+ combinations[72][4] = 42; combinations[73][4] = 41; combinations[74][4] = 38; combinations[75][4] = 37;
+ combinations[72][5] = 63; combinations[73][5] = 60; combinations[74][5] = 51; combinations[75][5] = 48;
+
+ // Initialize the combination flags to zero.
+ for (int i=0; i<76; i++)
+ combinations[i][6] = 0;
+
+ // Set up the pos_to_comb array to point to every winning combination that a given
+ // position may have.
+ setup_pos_to_comb();
+
+ // Set up the best_picks array.
+ update_best_picks();
+ }
+
+
+ /**
+ * Initialize the "outside four" array.
+ */
+ public void init_outside_four() {
+ for (int i=0; i<18; i++) {
+ outside_four[i][0] = 0;
+ outside_four[i][1] = 0;
+ outside_four[i][2] = faces[i][ 2];
+ outside_four[i][3] = faces[i][ 5];
+ outside_four[i][4] = faces[i][14];
+ outside_four[i][5] = faces[i][17];
+ }
+ }
+
+
+ /**
+ * Initialize the "inside four" array.
+ */
+ public void init_inside_four() {
+ for (int i=0; i<18; i++) {
+ inside_four[i][0] = 0;
+ inside_four[i][1] = 0;
+ inside_four[i][2] = faces[i][ 7];
+ inside_four[i][3] = faces[i][ 8];
+ inside_four[i][4] = faces[i][11];
+ inside_four[i][5] = faces[i][12];
+ }
+ }
+
+ /**
+ * Initialize the "faces" array.
+ */
+ public void init_faces () {
+
+ faces[ 0][ 0] = 0;
+ faces[ 0][ 1] = 0;
+ faces[ 0][ 2] = 12; faces[ 0][ 6] = 13; faces[ 0][10] = 14; faces[ 0][14] = 15;
+ faces[ 0][ 3] = 8; faces[ 0][ 7] = 9; faces[ 0][11] = 10; faces[ 0][15] = 11;
+ faces[ 0][ 4] = 4; faces[ 0][ 8] = 5; faces[ 0][12] = 6; faces[ 0][16] = 7;
+ faces[ 0][ 5] = 0; faces[ 0][ 9] = 1; faces[ 0][13] = 2; faces[ 0][17] = 3;
+
+ faces[ 1][ 0] = 0;
+ faces[ 1][ 1] = 0;
+ faces[ 1][ 2] = 28; faces[ 1][ 6] = 29; faces[ 1][10] = 30; faces[ 1][14] = 31;
+ faces[ 1][ 3] = 24; faces[ 1][ 7] = 25; faces[ 1][11] = 26; faces[ 1][15] = 27;
+ faces[ 1][ 4] = 20; faces[ 1][ 8] = 21; faces[ 1][12] = 22; faces[ 1][16] = 23;
+ faces[ 1][ 5] = 16; faces[ 1][ 9] = 17; faces[ 1][13] = 18; faces[ 1][17] = 19;
+
+ faces[ 2][ 0] = 0;
+ faces[ 2][ 1] = 0;
+ faces[ 2][ 2] = 44; faces[ 2][ 6] = 45; faces[ 2][10] = 46; faces[ 2][14] = 47;
+ faces[ 2][ 3] = 40; faces[ 2][ 7] = 41; faces[ 2][11] = 42; faces[ 2][15] = 43;
+ faces[ 2][ 4] = 36; faces[ 2][ 8] = 37; faces[ 2][12] = 38; faces[ 2][16] = 39;
+ faces[ 2][ 5] = 32; faces[ 2][ 9] = 33; faces[ 2][13] = 34; faces[ 2][17] = 35;
+
+ faces[ 3][ 0] = 0;
+ faces[ 3][ 1] = 0;
+ faces[ 3][ 2] = 60; faces[ 3][ 6] = 61; faces[ 3][10] = 62; faces[ 3][14] = 63;
+ faces[ 3][ 3] = 56; faces[ 3][ 7] = 57; faces[ 3][11] = 58; faces[ 3][15] = 59;
+ faces[ 3][ 4] = 52; faces[ 3][ 8] = 53; faces[ 3][12] = 54; faces[ 3][16] = 55;
+ faces[ 3][ 5] = 48; faces[ 3][ 9] = 49; faces[ 3][13] = 50; faces[ 3][17] = 51;
+
+ faces[ 4][ 0] = 0;
+ faces[ 4][ 1] = 0;
+ faces[ 4][ 2] = 12; faces[ 4][ 6] = 28; faces[ 4][10] = 44; faces[ 4][14] = 60;
+ faces[ 4][ 3] = 8; faces[ 4][ 7] = 24; faces[ 4][11] = 40; faces[ 4][15] = 56;
+ faces[ 4][ 4] = 4; faces[ 4][ 8] = 20; faces[ 4][12] = 36; faces[ 4][16] = 52;
+ faces[ 4][ 5] = 0; faces[ 4][ 9] = 16; faces[ 4][13] = 32; faces[ 4][17] = 48;
+
+ faces[ 5][ 0] = 0;
+ faces[ 5][ 1] = 0;
+ faces[ 5][ 2] = 13; faces[ 5][ 6] = 29; faces[ 5][10] = 45; faces[ 5][14] = 61;
+ faces[ 5][ 3] = 9; faces[ 5][ 7] = 25; faces[ 5][11] = 41; faces[ 5][15] = 57;
+ faces[ 5][ 4] = 5; faces[ 5][ 8] = 21; faces[ 5][12] = 37; faces[ 5][16] = 53;
+ faces[ 5][ 5] = 1; faces[ 5][ 9] = 17; faces[ 5][13] = 33; faces[ 5][17] = 49;
+
+ faces[ 6][ 0] = 0;
+ faces[ 6][ 1] = 0;
+ faces[ 6][ 2] = 14; faces[ 6][ 6] = 30; faces[ 6][10] = 46; faces[ 6][14] = 62;
+ faces[ 6][ 3] = 10; faces[ 6][ 7] = 26; faces[ 6][11] = 42; faces[ 6][15] = 58;
+ faces[ 6][ 4] = 6; faces[ 6][ 8] = 22; faces[ 6][12] = 38; faces[ 6][16] = 54;
+ faces[ 6][ 5] = 2; faces[ 6][ 9] = 18; faces[ 6][13] = 34; faces[ 6][17] = 50;
+
+ faces[ 7][ 0] = 0;
+ faces[ 7][ 1] = 0;
+ faces[ 7][ 2] = 15; faces[ 7][ 6] = 31; faces[ 7][10] = 47; faces[ 7][14] = 63;
+ faces[ 7][ 3] = 11; faces[ 7][ 7] = 27; faces[ 7][11] = 43; faces[ 7][15] = 59;
+ faces[ 7][ 4] = 7; faces[ 7][ 8] = 23; faces[ 7][12] = 39; faces[ 7][16] = 55;
+ faces[ 7][ 5] = 3; faces[ 7][ 9] = 19; faces[ 7][13] = 35; faces[ 7][17] = 51;
+
+ faces[ 8][ 0] = 0;
+ faces[ 8][ 1] = 0;
+ faces[ 8][ 2] = 12; faces[ 8][ 6] = 28; faces[ 8][10] = 44; faces[ 8][14] = 60;
+ faces[ 8][ 3] = 13; faces[ 8][ 7] = 29; faces[ 8][11] = 45; faces[ 8][15] = 61;
+ faces[ 8][ 4] = 14; faces[ 8][ 8] = 30; faces[ 8][12] = 46; faces[ 8][16] = 62;
+ faces[ 8][ 5] = 15; faces[ 8][ 9] = 31; faces[ 8][13] = 47; faces[ 8][17] = 63;
+
+ faces[ 9][ 0] = 0;
+ faces[ 9][ 1] = 0;
+ faces[ 9][ 2] = 8; faces[ 9][ 6] = 24; faces[ 9][10] = 40; faces[ 9][14] = 56;
+ faces[ 9][ 3] = 9; faces[ 9][ 7] = 25; faces[ 9][11] = 41; faces[ 9][15] = 57;
+ faces[ 9][ 4] = 10; faces[ 9][ 8] = 26; faces[ 9][12] = 42; faces[ 9][16] = 58;
+ faces[ 9][ 5] = 11; faces[ 9][ 9] = 27; faces[ 9][13] = 43; faces[ 9][17] = 59;
+
+ faces[10][ 0] = 0;
+ faces[10][ 1] = 0;
+ faces[10][ 2] = 4; faces[10][ 6] = 20; faces[10][10] = 36; faces[10][14] = 52;
+ faces[10][ 3] = 5; faces[10][ 7] = 21; faces[10][11] = 37; faces[10][15] = 53;
+ faces[10][ 4] = 6; faces[10][ 8] = 22; faces[10][12] = 38; faces[10][16] = 54;
+ faces[10][ 5] = 7; faces[10][ 9] = 23; faces[10][13] = 39; faces[10][17] = 55;
+
+ faces[11][ 0] = 0;
+ faces[11][ 1] = 0;
+ faces[11][ 2] = 0; faces[11][ 6] = 16; faces[11][10] = 32; faces[11][14] = 48;
+ faces[11][ 3] = 1; faces[11][ 7] = 17; faces[11][11] = 33; faces[11][15] = 49;
+ faces[11][ 4] = 2; faces[11][ 8] = 18; faces[11][12] = 34; faces[11][16] = 50;
+ faces[11][ 5] = 3; faces[11][ 9] = 19; faces[11][13] = 35; faces[11][17] = 51;
+
+ faces[12][ 0] = 0;
+ faces[12][ 1] = 0;
+ faces[12][ 2] = 12; faces[12][ 6] = 13; faces[12][10] = 14; faces[12][14] = 15;
+ faces[12][ 3] = 24; faces[12][ 7] = 25; faces[12][11] = 26; faces[12][15] = 27;
+ faces[12][ 4] = 36; faces[12][ 8] = 37; faces[12][12] = 38; faces[12][16] = 39;
+ faces[12][ 5] = 48; faces[12][ 9] = 49; faces[12][13] = 50; faces[12][17] = 51;
+
+ faces[13][ 0] = 0;
+ faces[13][ 1] = 0;
+ faces[13][ 2] = 0; faces[13][ 6] = 1; faces[13][10] = 2; faces[13][14] = 3;
+ faces[13][ 3] = 20; faces[13][ 7] = 21; faces[13][11] = 22; faces[13][15] = 23;
+ faces[13][ 4] = 40; faces[13][ 8] = 41; faces[13][12] = 42; faces[13][16] = 43;
+ faces[13][ 5] = 60; faces[13][ 9] = 61; faces[13][13] = 62; faces[13][17] = 63;
+
+ faces[14][ 0] = 0;
+ faces[14][ 1] = 0;
+ faces[14][ 2] = 12; faces[14][ 6] = 28; faces[14][10] = 44; faces[14][14] = 60;
+ faces[14][ 3] = 9; faces[14][ 7] = 25; faces[14][11] = 41; faces[14][15] = 57;
+ faces[14][ 4] = 6; faces[14][ 8] = 22; faces[14][12] = 38; faces[14][16] = 54;
+ faces[14][ 5] = 3; faces[14][ 9] = 19; faces[14][13] = 35; faces[14][17] = 51;
+
+ faces[15][ 0] = 0;
+ faces[15][ 1] = 0;
+ faces[15][ 2] = 15; faces[15][ 6] = 31; faces[15][10] = 47; faces[15][14] = 63;
+ faces[15][ 3] = 10; faces[15][ 7] = 26; faces[15][11] = 42; faces[15][15] = 58;
+ faces[15][ 4] = 5; faces[15][ 8] = 21; faces[15][12] = 37; faces[15][16] = 53;
+ faces[15][ 5] = 0; faces[15][ 9] = 16; faces[15][13] = 32; faces[15][17] = 48;
+
+ faces[16][ 0] = 0;
+ faces[16][ 1] = 0;
+ faces[16][ 2] = 12; faces[16][ 6] = 29; faces[16][10] = 46; faces[16][14] = 63;
+ faces[16][ 3] = 8; faces[16][ 7] = 25; faces[16][11] = 42; faces[16][15] = 59;
+ faces[16][ 4] = 4; faces[16][ 8] = 21; faces[16][12] = 38; faces[16][16] = 55;
+ faces[16][ 5] = 0; faces[16][ 9] = 17; faces[16][13] = 34; faces[16][17] = 51;
+
+ faces[17][ 0] = 0;
+ faces[17][ 1] = 0;
+ faces[17][ 2] = 15; faces[17][ 6] = 30; faces[17][10] = 45; faces[17][14] = 60;
+ faces[17][ 3] = 11; faces[17][ 7] = 26; faces[17][11] = 41; faces[17][15] = 56;
+ faces[17][ 4] = 7; faces[17][ 8] = 22; faces[17][12] = 37; faces[17][16] = 52;
+ faces[17][ 5] = 3; faces[17][ 9] = 18; faces[17][13] = 33; faces[17][17] = 48;
+ }
+
+ /**
+ * Render the current face set in the 2D window.
+ */
+ public void render2D(Graphics gc) {
+
+ gc.setColor(background);
+ gc.fillRect(0, 0, width, height);
+
+ int id;
+ int x, y;
+
+ float begX;
+ float begY;
+
+ for (int l=0; l<3; l++) {
+ begY = 28.0f + l*(5.f*23.3f);
+ for (int k=0; k<6; k++) {
+ begX = 11.65f + k*(5.f*11.65f);
+ int count = 0;
+ int face = l*6+k;
+ for (int i=0; i<4; i++) {
+ for (int j=0; j<4; j++) {
+ x = (int)begX + i*12;
+ y = (int)begY + j*12;
+ id = faces[face][count+2];
+ if (occupied[id] == HUMAN) {
+ x -= 2;
+ y -= 2;
+ gc.setColor(red);
+ gc.fillRect(x, y, 5, 5);
+ }
+ else if (occupied[id] == MACHINE) {
+ x -= 2;
+ y -= 2;
+ gc.setColor(blue);
+ gc.fillRect(x, y, 5, 5);
+ }
+ else {
+ x -= 1;
+ y -= 1;
+ gc.setColor(gray);
+ gc.fillRect(x, y, 2, 2);
+ }
+ if (highlight[face]) {
+ gc.setColor(yellow);
+ positions.setHighlight(faces[face][count+2]);
+ }
+ count++;
+ }
+ }
+ if (highlight[face])
+ gc.setColor(yellow);
+ else
+ gc.setColor(white);
+ if ((face+1)<10)
+ gc.drawString("Face "+(face+1), (int)begX-2, (int)begY+60);
+ else
+ gc.drawString("Face "+(face+1), (int)begX-4, (int)begY+60);
+ }
+ }
+ }
+
+ /**
+ * Determine what position has been selected in the 2D window.
+ */
+ public void checkSelection2D(int x, int y, int player) {
+
+ int id;
+ int posX, posY;
+
+ float begX;
+ float begY;
+
+ for (int l=0; l<3; l++) {
+ begY = 28.0f + l*(5.f*23.3f);
+ for (int k=0; k<6; k++) {
+ begX = 11.65f + k*(5.f*11.65f);
+ int count = 0;
+ int face = l*6+k;
+ for (int i=0; i<4; i++) {
+ for (int j=0; j<4; j++) {
+ posX = (int)begX + i*12;
+ posY = (int)begY + j*12;
+ if (x > posX-4 && x < posX+4 &&
+ y > posY-4 && y < posY+4) {
+
+ id = faces[face][count+2];
+
+ if (occupied[id] == UNOCCUPIED) {
+ positions.set(id, player);
+ selection(id, player);
+ canvas.repaint();
+ }
+ return;
+ }
+ count++;
+ }
+ }
+ if ((x > begX-4 && x < begX+40) &&
+ (y > begY+45 && y < begY+60) ) {
+
+ count = 0;
+ for (int i=0; i<4; i++) {
+ for (int j=0; j<4; j++) {
+ if (highlight[face])
+ positions.clearHighlight(faces[face][count+2]);
+ count++;
+ }
+ }
+ if (highlight[face])
+ highlight[face] = false;
+ else
+ highlight[face] = true;
+ canvas.repaint();
+ }
+ }
+ }
+
+ }
+
+
+ /**
+ * Record the player's move.
+ */
+ public void selection(int pos, int player) {
+
+ int num_combinations;
+ int comb;
+
+ this.player = player;
+
+ if (player == HUMAN) {
+
+ // If position is already occupied, return.
+ if (occupied[pos] != 0) return;
+
+ // Mark the position as HUMAN.
+ occupied[pos] = HUMAN;
+
+ // Update the logic arrays.
+ this.player = update_logic_arrays(pos);
+
+ // Have the computer determine its move.
+ choose_move();
+ }
+ }
+
+
+ /**
+ * Determine the computer's move.
+ */
+ public void choose_move () {
+
+ if (player == MACHINE) {
+
+ // Babe in the woods.
+ if (skill_level == 0) {
+ if (!block_winning_move()) {
+ if (!pick_7()) {
+ if (!check_outside_four()) {
+ pick_best_position();
+ }
+ }
+ }
+ }
+
+ // Walk and chew gum.
+ else if (skill_level == 1) {
+ if (!block_winning_move()) {
+ if (!block_intersecting_rows()) {
+ if (!block_inside_four()) {
+ if (!block_outside_four()) {
+ pick_best_position();
+ }
+ }
+ }
+ }
+ }
+
+ // Jeopordy contestant.
+ else if (skill_level == 2) {
+ if (!block_winning_move()) {
+ if (!block_intersecting_rows()) {
+ if (!block_inside_four()) {
+ if (!block_outside_four()) {
+ if (!pick_7()) {
+ pick_best_position();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Rocket scientist.
+ else if (skill_level == 3) {
+ if (!block_winning_move()) {
+ if (!block_intersecting_rows()) {
+ if (!block_chair_move()) {
+ if (!check_face_three()) {
+ if (!block_central_four()) {
+ if (!block_inside_four()) {
+ if (!block_outside_four()) {
+ if (!take_inside_four()) {
+ if (!take_outside_four()) {
+ if (!pick_7()) {
+ if (!check_outside_four()) {
+ pick_best_position();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Be afraid, be very afraid.
+ else if (skill_level == 4) {
+ if (!block_winning_move()) {
+ if (!block_intersecting_rows()) {
+ if (!block_chair_move()) {
+ if (!block_walk_move()) {
+ if (!block_central_four()) {
+ if (!block_inside_four()) {
+ if (!block_outside_four()) {
+ if (!check_face_three()) {
+ if (!check_intersecting_rows2()) {
+ if (!take_inside_four()) {
+ if (!take_outside_four()) {
+ if (!pick_7()) {
+ if (!check_outside_four()) {
+ pick_best_position();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Check for a winning move.
+ */
+ public boolean block_winning_move() {
+
+ // Loop through each combination and see if any player occupies
+ // three positions. If so, take the last remaining position.
+ int pos;
+ for (int i=0; i<76; i++) {
+ if (combinations[i][0] == 3) {
+ for (int j=2; j<6; j++) {
+ pos = combinations[i][j];
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_winning_move: true");
+ return true;
+ }
+ }
+ }
+ }
+ if (debug) System.out.println("check_winning_move: false");
+ return false;
+ }
+
+
+ /**
+ * Block outside four
+ */
+ public boolean block_outside_four() {
+
+ int pos;
+ int index = 0;
+ int max = 0;
+
+ // Block the opponent, if necessary.
+ for (int i=0; i<18; i++) {
+ if (outside_four[i][0] > 0 &&
+ outside_four[i][1] == HUMAN) {
+ if(outside_four[i][0] > max) {
+ index = i;
+ max = outside_four[i][0];
+ }
+ }
+ }
+
+ if (max > 0) {
+ for (int j=2; j<6; j++) {
+ pos = outside_four[index][j];
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_outside_four: true");
+ return true;
+ }
+ }
+ }
+
+ if (debug) System.out.println("block_outside_four: false");
+ return false;
+ }
+
+
+ /**
+ * Block central four
+ */
+ public boolean block_central_four() {
+
+ int pos;
+ int index = 0;
+ int max = 0;
+
+ // Block the opponent, if necessary.
+ for (int i=1; i<3; i++) {
+ if (inside_four[i][0] > 0 &&
+ inside_four[i][1] == HUMAN) {
+ if(inside_four[i][0] > max) {
+ index = i;
+ max = inside_four[i][0];
+ }
+ }
+ }
+
+ if (max > 0) {
+ for (int j=2; j<6; j++) {
+ pos = inside_four[index][j];
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_central_four: true");
+ return true;
+ }
+ }
+ }
+
+ if (debug) System.out.println("block_central_four: false");
+ return false;
+ }
+
+ /**
+ * Check each face for a forced win.
+ */
+ public boolean check_face_three() {
+
+ int pos;
+ int index = 0;
+ int human = 0;
+ int machine = 0;
+
+ // Block the opponent from a forced win.
+ for (int i=0; i<18; i++) {
+ if (outside_four[i][0] == -1) {
+ human = 0;
+ machine = 0;
+ for (int j=2; j<6; j++) {
+ if (occupied[outside_four[i][j]] == MACHINE)
+ machine++;
+ else if (occupied[outside_four[i][j]] == HUMAN)
+ human++;
+ }
+ if (debug) System.out.println("machine = " + machine);
+ if (debug) System.out.println("human = " + human);
+ if (human == 3 && machine == 1) {
+ if (debug) System.out.println("human == 3 && machine == 1");
+ for (int j=2; j<18; j++) {
+ pos = faces[i][j];
+ if (occupied[pos] == 0) {
+ for (int k=0; k<76; k++) {
+ if (combinations[i][0] == 2 &
+ combinations[i][1] == HUMAN) {
+ for (int l=0; l<4; l++) {
+ if (combinations[i][l] == pos) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_face_three: true");
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (debug) System.out.println("check_face_three: false");
+ return false;
+ }
+
+
+
+ /**
+ * Block inside four
+ */
+ public boolean block_inside_four() {
+
+ int pos;
+ int index = 0;
+ int max = 0;
+
+ // Block the opponent, if necessary.
+ for (int i=0; i<18; i++) {
+ if (inside_four[i][0] > 0 &&
+ inside_four[i][1] == HUMAN) {
+ if(inside_four[i][0] > max) {
+ index = i;
+ max = inside_four[i][0];
+ }
+ }
+ }
+
+ if (max > 0) {
+ for (int j=2; j<6; j++) {
+ pos = inside_four[index][j];
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_inside_four: true");
+ return true;
+ }
+ }
+ }
+
+ if (debug) System.out.println("block_inside_four: false");
+ return false;
+ }
+
+
+ public boolean block_chair_move() {
+
+ int pos;
+
+ int ncorners = 0; // Number of corners owned by human
+ int corner = 0; // Corner owned by machine
+
+ if (debug) System.out.println("inside block_chair_move");
+
+ // Loop through all of the faces.
+ for(int i=0; i<18; i++) {
+
+ // Determine which corners the human owns.
+ if (occupied[faces[i][2]] == HUMAN)
+ ncorners++;
+ else if (occupied[faces[i][2]] == MACHINE)
+ corner = 2;
+ if (occupied[faces[i][5]] == HUMAN)
+ ncorners++;
+ else if (occupied[faces[i][5]] == MACHINE)
+ corner = 5;
+ if (occupied[faces[i][14]] == HUMAN)
+ ncorners++;
+ else if (occupied[faces[i][14]] == MACHINE)
+ corner = 14;
+ if (occupied[faces[i][17]] == HUMAN)
+ ncorners++;
+ else if (occupied[faces[i][17]] == MACHINE)
+ corner = 17;
+
+ // If the human owns three corners, continue with the search.
+ if (ncorners == 3) {
+ if (corner == 2) {
+ if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][11];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][12];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][ 9]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][13]] == 0) {
+ pos = faces[i][8];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][ 9]] == 0 && occupied[faces[i][11]] == 0 &&
+ occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) {
+ pos = faces[i][11];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][11];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 4]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][16];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ }
+ else if (corner == 5) {
+ if (occupied[faces[i][ 9]] == HUMAN && occupied[faces[i][ 6]] == 0 &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][10]] == 0 && occupied[faces[i][12]] == 0) {
+ pos = faces[i][7];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][13]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][10]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) {
+ pos = faces[i][12];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][12];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][7];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 4]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][12];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][12]] == 0 &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][ 7];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ }
+ else if (corner == 14) {
+ if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][ 9]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][13]] == 0) {
+ pos = faces[i][7];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][ 9]] == 0 && occupied[faces[i][11]] == 0 &&
+ occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) {
+ pos = faces[i][12];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) {
+ pos = faces[i][3];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0) {
+ pos = faces[i][12];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][12]] == 0 && occupied[faces[i][15]] == 0) {
+ pos = faces[i][7];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 6]] == 0 &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 9]] == 0 &&
+ occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) {
+ pos = faces[i][7];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ }
+ else if (corner == 17) {
+ if (occupied[faces[i][ 9]] == HUMAN && occupied[faces[i][ 6]] == 0 &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][10]] == 0 && occupied[faces[i][11]] == 0) {
+ pos = faces[i][8];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][13]] == HUMAN && occupied[faces[i][ 6]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][10]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) {
+ pos = faces[i][11];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0) {
+ pos = faces[i][11];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) {
+ pos = faces[i][8];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][16]] == 0) {
+ pos = faces[i][8];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][ 3]] == 0 &&
+ occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][15]] == 0) {
+ pos = faces[i][11];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ }
+ }
+ ncorners = 0;
+ corner = -1;
+ }
+ if (debug) System.out.println("block_chair_move: false");
+ return false;
+ }
+
+ public boolean block_walk_move() {
+
+ int pos;
+
+ if (debug) System.out.println("inside block_walk_move");
+
+ // Loop through all of the faces.
+ for(int i=0; i<18; i++) {
+
+ // Look for a matching pattern.
+ if (occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][14]] == HUMAN &&
+ occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][15]] == HUMAN &&
+ occupied[faces[i][ 6]] == 0 && occupied[faces[i][10]] == 0 &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][11]] == 0) {
+
+ if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 9]] == 0) {
+ pos = faces[i][6];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ else if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][13]] == 0) {
+ pos = faces[i][10];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ // Look for a matching pattern.
+ if (occupied[faces[i][14]] == HUMAN && occupied[faces[i][17]] == HUMAN &&
+ occupied[faces[i][10]] == HUMAN && occupied[faces[i][13]] == HUMAN &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0 &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) {
+
+ if (occupied[faces[i][7]] == HUMAN && occupied[faces[i][3]] == 0) {
+ pos = faces[i][15];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ else if (occupied[faces[i][8]] == HUMAN && occupied[faces[i][4]] == 0) {
+ pos = faces[i][16];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ // Look for a matching pattern.
+ if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][16]] == HUMAN &&
+ occupied[faces[i][ 5]] == HUMAN && occupied[faces[i][17]] == HUMAN &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0 &&
+ occupied[faces[i][ 9]] == 0 && occupied[faces[i][13]] == 0) {
+
+ if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][10]] == 0) {
+ pos = faces[i][18];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ else if (occupied[faces[i][7]] == HUMAN && occupied[faces[i][6]] == 0) {
+ pos = faces[i][9];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ // Look for a matching pattern.
+ if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 9]] == HUMAN &&
+ occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][ 5]] == HUMAN &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 &&
+ occupied[faces[i][ 3]] == 0 && occupied[faces[i][ 4]] == 0) {
+
+ if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][15]] == 0) {
+ pos = faces[i][3];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ else if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][16]] == 0) {
+ pos = faces[i][4];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ // Look for a matching pattern.
+ if (occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][14]] == HUMAN &&
+ occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][16]] == HUMAN &&
+ occupied[faces[i][ 6]] == 0 && occupied[faces[i][10]] == 0 &&
+ occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0) {
+
+ if ((occupied[faces[i][7]] == HUMAN && occupied[faces[i][9]] == 0) ||
+ (occupied[faces[i][9]] == HUMAN && occupied[faces[i][7]] == 0) ) {
+ pos = faces[i][6];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ else if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][13]] == 0) ||
+ (occupied[faces[i][13]] == HUMAN && occupied[faces[i][11]] == 0) ) {
+ pos = faces[i][10];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ // Look for a matching pattern.
+ if (occupied[faces[i][14]] == HUMAN && occupied[faces[i][17]] == HUMAN &&
+ occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 9]] == HUMAN &&
+ occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0 &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0) {
+
+ if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0) ||
+ (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][11]] == 0) ) {
+ pos = faces[i][15];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ else if ((occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 4]] == 0) ||
+ (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][12]] == 0) ) {
+ pos = faces[i][16];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ // Look for a matching pattern.
+ if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][15]] == HUMAN &&
+ occupied[faces[i][ 5]] == HUMAN && occupied[faces[i][17]] == HUMAN &&
+ occupied[faces[i][ 7]] == 0 && occupied[faces[i][11]] == 0 &&
+ occupied[faces[i][ 9]] == 0 && occupied[faces[i][13]] == 0) {
+
+ if ((occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 8]] == 0) ||
+ (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 6]] == 0) ) {
+ pos = faces[i][9];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ else if ((occupied[faces[i][10]] == HUMAN && occupied[faces[i][12]] == 0) ||
+ (occupied[faces[i][12]] == HUMAN && occupied[faces[i][10]] == 0) ) {
+ pos = faces[i][13];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ // Look for a matching pattern.
+ if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][13]] == HUMAN &&
+ occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][ 5]] == HUMAN &&
+ occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 &&
+ occupied[faces[i][ 3]] == 0 && occupied[faces[i][ 4]] == 0) {
+
+ if ((occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][15]] == 0) ||
+ (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 7]] == 0) ) {
+ pos = faces[i][3];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ else if ((occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][16]] == 0) ||
+ (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 8]] == 0) ) {
+ pos = faces[i][4];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ }
+
+ if (debug) System.out.println("block_walk_move: false");
+ return false;
+ }
+
+ public boolean check_chair_move() {
+
+ int pos;
+
+ // If the "block chair flag" is set, all we need to do is
+ // block the winning path...
+ if (block_chair_flag) {
+ pos = faces[block_chair_face][block_chair_next_move];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: march");
+ return true;
+ }
+
+ int ncorners = 0; // Number of corners owned by human
+ int corner = 0; // Corner owned by machine
+
+ // Loop through all of the faces.
+ for(int i=0; i<18; i++) {
+
+ // Determine which corners the human owns.
+ if (faces[i][ 2] == HUMAN)
+ ncorners++;
+ else
+ corner = 2;
+ if (faces[i][ 5] == HUMAN)
+ ncorners++;
+ else
+ corner = 5;
+ if (faces[i][14] == HUMAN)
+ ncorners++;
+ else
+ corner = 14;
+ if (faces[i][17] == HUMAN)
+ ncorners++;
+ else
+ corner = 17;
+
+ // If the human owns three corners, continue with the search.
+ if (ncorners == 3) {
+ if (corner == 2) {
+ if (faces[i][ 3] == HUMAN && faces[i][ 7] == 0 &&
+ faces[i][ 8] == 0 && faces[i][11] == 0 &&
+ faces[i][15] == 0 && faces[i][16] == 0) {
+ block_chair_flag = true;
+ block_chair_next_move = 11;
+ block_chair_face = i;
+ pos = faces[i][15];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ if (faces[i][ 4] == HUMAN && faces[i][ 8] == 0 &&
+ faces[i][11] == 0 && faces[i][12] == 0 &&
+ faces[i][15] == 0 && faces[i][16] == 0) {
+ block_chair_flag = true;
+ block_chair_next_move = 16;
+ block_chair_face = i;
+ pos = faces[i][8];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_chair_move: found");
+ return true;
+ }
+ }
+ else if (corner == 5) {
+ block_chair_flag = true;
+ block_chair_next_move = 11;
+ block_chair_face = i;
+ pos = faces[i][15];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_face_three: true");
+ return true;
+ }
+ else if (corner == 14) {
+ block_chair_flag = true;
+ block_chair_next_move = 11;
+ block_chair_face = i;
+ pos = faces[i][15];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_face_three: true");
+ return true;
+ }
+ else if (corner == 17) {
+ block_chair_flag = true;
+ block_chair_next_move = 11;
+ block_chair_face = i;
+ pos = faces[i][15];
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_face_three: true");
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Take inside four
+ */
+ public boolean take_inside_four() {
+
+ int pos = 0;
+ boolean found = false;
+
+ if (occupied[21] == 0) {
+ found = true;
+ pos = 21;
+ }
+ else if (occupied[22] == 0) {
+ found = true;
+ pos = 22;
+ }
+ else if (occupied[25] == 0) {
+ found = true;
+ pos = 25;
+ }
+ else if (occupied[26] == 0) {
+ found = true;
+ pos = 26;
+ }
+ else if (occupied[37] == 0) {
+ found = true;
+ pos = 37;
+ }
+ else if (occupied[38] == 0) {
+ found = true;
+ pos = 38;
+ }
+ else if (occupied[41] == 0) {
+ found = true;
+ pos = 41;
+ }
+ else if (occupied[42] == 0) {
+ found = true;
+ pos = 42;
+ }
+
+ if (found) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("take_inside_four: true");
+ return true;
+ }
+
+ if (debug) System.out.println("take_inside_four: false");
+ return false;
+ }
+
+
+ /**
+ * Check occupancy of outside four.
+ */
+ public boolean check_outside_four() {
+
+ int pos = 0;
+
+ // Finish off the four corner combination.
+ if (outside_four_flag) {
+ if (occupied[faces[face_index][7]] == 0) {
+ pos = faces[face_index][7];
+ }
+ else if (occupied[faces[face_index][6]] == 0) {
+ pos = faces[face_index][6];
+ }
+
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ return true;
+ }
+ }
+
+ // Look for a four corner combination.
+ for (int i=0; i<18; i++) {
+ if (outside_four[i][0] == 4 &&
+ outside_four[i][1] == MACHINE) {
+ if (faces[i][0] > 0 &&
+ faces[i][1] == MACHINE) {
+ if (occupied[faces[i][8]] == 0) {
+ pos = faces[i][8];
+ outside_four_flag = true;
+ face_index = i;
+ }
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_outside_four: true");
+ return true;
+ }
+ }
+ }
+ }
+
+ // Take the corners, if available.
+ for (int i=0; i<18; i++) {
+ if (outside_four[i][0] > 0 &&
+ outside_four[i][1] == MACHINE) {
+ if (faces[i][0] > 0 &&
+ faces[i][1] == MACHINE) {
+ for (int j=2; j<6; j++) {
+ pos = outside_four[i][j];
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_outside_four: true");
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ // Look for an "outside four" combination in a face in which the
+ // opponent holds no positions.
+ for (int i=0; i<18; i++) {
+ if (outside_four[i][0] == 0 || (outside_four[i][0] > 0 &&
+ outside_four[i][1] == MACHINE)) {
+
+ if (outside_four[i][1] == MACHINE)
+ outside_four_flag = true;
+ for (int j=2; j<6; j++) {
+ pos = outside_four[i][j];
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_outside_four: true");
+ return true;
+ }
+ }
+ }
+ }
+
+ if (debug) System.out.println("check_outside_four: false");
+ return false;
+ }
+
+
+ /**
+ * Take outside four
+ */
+ public boolean take_outside_four() {
+
+ int pos = 0;
+ boolean found = false;
+
+ if (occupied[0] == 0) {
+ found = true;
+ pos = 0;
+ }
+ else if (occupied[3] == 0) {
+ found = true;
+ pos = 3;
+ }
+ else if (occupied[12] == 0) {
+ found = true;
+ pos = 12;
+ }
+ else if (occupied[15] == 0) {
+ found = true;
+ pos = 15;
+ }
+ else if (occupied[48] == 0) {
+ found = true;
+ pos = 48;
+ }
+ else if (occupied[51] == 0) {
+ found = true;
+ pos = 51;
+ }
+ else if (occupied[60] == 0) {
+ found = true;
+ pos = 60;
+ }
+ else if (occupied[63] == 0) {
+ found = true;
+ pos = 63;
+ }
+
+ if (found) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("take_outside_four: true");
+ return true;
+ }
+
+ if (debug) System.out.println("take_outside_four: false");
+ return false;
+ }
+
+
+ /**
+ * Check for a forced win by intersecting rows. Block
+ * if necessary.
+ */
+ public boolean block_intersecting_rows() {
+
+ int pos;
+
+ // Loop through each row and check for rows that have two
+ // positions occupied by the human and two positions which are empty.
+ // Make sure that none of the empty positions in this row intersect
+ // with another row that also contains two positions held by the human.
+ // If so, block the row by taking the position at the intersection
+ // of these two row.
+
+ // Loop through each row.
+ for (int i=0; i<76; i++) {
+
+ // Look for a row that has two positions held by the human.
+ if (combinations[i][0] == 2 && combinations[i][1] == HUMAN) {
+
+ if (debug)
+ System.out.println(" row " + i + "has 2 positions occupied by the human");
+
+ // Mark this row with a flag.
+ combinations[i][6] = 1;
+
+ // Check each position in the row.
+ for (int j=2; j<6; j++) {
+
+ // Look for the empty positions in the row.
+ pos = combinations[i][j];
+ if (occupied[pos] == 0) {
+
+ // Loop through the rows again.
+ for (int k=0; k<76; k++) {
+
+ if (debug) System.out.println(" row " + k);
+
+ // Look for another row that has two positions held
+ // by the human (and which is unmarked.) modified
+ if (combinations[k][0] == 2 &&
+ combinations[k][1] == HUMAN &&
+ combinations[k][6] == 0) {
+
+ if (debug)
+ System.out.println("found an intersecting row: row " + k);
+
+ // Check the positions in this row and see if
+ // any match the position we're looking for. If
+ // we find a match, grab the position and return.
+ for (int l=2; l<6; l++) {
+ if (pos == combinations[k][l]) {
+ combinations[i][6] = 0;
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("block_intersecting_rows: true");
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Unmark the combination before moving on.
+ combinations[i][6] = 0;
+ }
+
+ }
+ if (debug) System.out.println("block_intersecting_rows: false");
+ return false;
+ }
+
+ /**
+ * Check for a forced win by intersecting rows. Block
+ * if necessary.
+ */
+ public boolean check_intersecting_rows2() {
+
+ int pos;
+
+ // Loop through each row and check for rows that have two
+ // positions occupied by the human and two positions which are empty.
+ // Make sure that none of the empty positions in this row intersect
+ // with another row that also contains two positions held by the human.
+ // If so, block the row by taking the position at the intersection
+ // of these two row.
+
+ // Loop through each row.
+ for (int i=0; i<76; i++) {
+
+ // Look for a row that has two positions held by the human.
+ if (combinations[i][0] == 2 && combinations[i][1] == HUMAN) {
+
+ if (debug) {
+ System.out.println(" row " + i + "has 2 positions occupied by the human");
+ }
+
+ // Mark this row with a flag.
+ combinations[i][6] = 1;
+
+ // Check each position in the row.
+ for (int j=2; j<6; j++) {
+
+ // Look for the empty positions in the row.
+ pos = combinations[i][j];
+ if (occupied[pos] == 0) {
+
+ // Loop through the rows again.
+ for (int k=0; k<76; k++) {
+
+ if (debug) System.out.println(" row " + k);
+
+ // Look for another row that has two positions held
+ // by the human (and which is unmarked.) modified
+ if (combinations[k][0] == 1 &&
+ combinations[k][1] == HUMAN &&
+ combinations[k][6] == 0) {
+
+ if (debug)
+ System.out.println("found an intersecting row: row " + k);
+
+ // Check the positions in this row and see if
+ // any match the position we're looking for. If
+ // we find a match, grab the position and return.
+ for (int l=2; l<6; l++) {
+ if (pos == combinations[k][l]) {
+ combinations[i][6] = 0;
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_intersecting_rows: true");
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Unmark the combination before moving on.
+ combinations[i][6] = 0;
+ }
+
+ }
+ if (debug) System.out.println("check_intersecting_rows: false");
+ return false;
+ }
+
+
+ /**
+ * Check for a forced win by intersecting rows. Block
+ * if necessary.
+ */
+ public boolean check_for_two() {
+
+ int pos;
+
+ // Loop through the rows.
+ for (int i=0; i<76; i++) {
+
+ // Look for a row that has two positions held
+ // by the human (and which is unmarked.)
+ if (combinations[i][0] == 2 &&
+ combinations[i][1] == HUMAN &&
+ combinations[i][6] == 0) {
+
+ // Take the first available spot.
+ for (int j=2; j<6; j++) {
+ pos = combinations[i][j];
+ if (occupied[pos] == 0) {
+ occupied[pos] = MACHINE;
+ positions.set(pos, MACHINE);
+ player = update_logic_arrays(pos);
+ if (debug) System.out.println("check_for_two: true");
+ return true;
+ }
+ }
+
+ }
+ }
+ if (debug) System.out.println("check_for_two: false");
+ return false;
+ }
+
+ public void undo_move() {
+
+ // Return if no moves are recorded
+ if (nmoves == 0) return;
+
+ // Set the undo flag
+ undoFlag = true;
+
+ // Undo the last two moves
+ positions.clear(moves[--nmoves]);
+ positions.clear(moves[--nmoves]);
+
+ // Undo the winner flag in the positions object
+ positions.noWinner();
+
+ // Repaint the 2D canvas.
+ canvas.repaint();
+
+ // Reset the inside/outside flags
+ inside_four_flag = false;
+ outside_four_flag = false;
+ block_chair_flag = false;
+
+ // Reset the board
+ for (int i=0; i<64; i++) {
+ occupied[i] = 0;
+ }
+
+ // Reset the inside/outside arrays
+ for (int i=0; i<18; i++) {
+ inside_four[i][0] = 0;
+ inside_four[i][1] = 0;
+ outside_four[i][0] = 0;
+ outside_four[i][1] = 0;
+ }
+
+ // Reset the faces array
+ for (int i=0; i<18; i++) {
+ faces[i][0] = 0;
+ faces[i][1] = 0;
+ }
+
+ // Reset the combinations array
+ for (int i=0; i<76; i++) {
+ combinations[i][0] = 0;
+ combinations[i][1] = 0;
+ }
+
+ if (nmoves == 0) {
+ undoFlag = false;
+ player = HUMAN;
+ return;
+ }
+
+ // Update the logic arrays
+ int pos;
+ player = HUMAN;
+ for (int i=0; i<nmoves; i++) {
+ pos = moves[i];
+ occupied[pos] = player;
+ player = update_logic_arrays(pos);
+ }
+
+ // Reset the "best picks" array
+ update_best_picks();
+
+ // Reset the player and undo flag
+ player = HUMAN;
+ undoFlag = false;
+ }
+
+ /**
+ * Update the logic arrays that keep track of positions and status.
+ * If we have a winner, stop the game.
+ */
+ public int update_logic_arrays(int pos) {
+
+ // Record the move.
+ if (!undoFlag) {
+ moves[nmoves++] = pos;
+ }
+
+ // Get the number of combinations that this position has.
+ int num_combinations = pos_to_comb[pos][0];
+
+ // Go through each combination associated with this position
+ // and update the status. If we have a winner, stop the game.
+ int comb;
+ for (int j=0; j<num_combinations; j++) {
+ comb = pos_to_comb[pos][j+1];
+ if (combinations[comb][1] != player &&
+ combinations[comb][1] != 0) {
+ combinations[comb][0] = -1;
+ }
+ else {
+ combinations[comb][0]++;
+ if (combinations[comb][0] == 4) {
+ end_time = System.currentTimeMillis();
+ time = (end_time - beg_time)/1000;
+ panel.winner(player, skill_level, nmoves, time);
+ panel.repaint();
+ canvas.repaint();
+ positions.winner();
+ return END;
+ }
+ else {
+ combinations[comb][1] = player;
+ }
+ }
+ }
+
+ // Update the best_picks array.
+ update_best_picks();
+
+ // Update the inside_four array.
+ for (int i=0; i<18; i++) {
+ for (int j=2; j<6; j++) {
+ if (pos == inside_four[i][j]) {
+ if (inside_four[i][0] == 0) {
+ inside_four[i][0] = 1;
+ inside_four[i][1] = player;
+ }
+ else if (inside_four[i][1] == player) {
+ inside_four[i][0]++;
+ inside_four[i][1] = player;
+ }
+ else {
+ inside_four[i][0] = -1;
+ }
+ }
+ }
+ }
+
+ // Update the outside_four array.
+ for (int i=0; i<18; i++) {
+ for (int j=2; j<6; j++) {
+ if (pos == outside_four[i][j]) {
+ if (outside_four[i][0] == 0) {
+ outside_four[i][0] = 1;
+ outside_four[i][1] = player;
+ }
+ else if (outside_four[i][1] == player) {
+ outside_four[i][0]++;
+ outside_four[i][1] = player;
+ }
+ else {
+ outside_four[i][0] = -1;
+ }
+ }
+ }
+ }
+
+ // Update the faces array.
+ for (int i=0; i<18; i++) {
+ for (int j=2; j<18; j++) {
+ if (pos == faces[i][j]) {
+ if (faces[i][0] == 0) {
+ faces[i][0] = 1;
+ faces[i][1] = player;
+ }
+ else if (faces[i][1] == player) {
+ faces[i][0]++;
+ }
+ else {
+ faces[i][0] = -1;
+ }
+ }
+ }
+
+ }
+
+ // Switch players.
+ if (player == HUMAN)
+ return MACHINE;
+ else
+ return HUMAN;
+ }
+
+
+ /**
+ * Start a new game.
+ */
+ public void newGame() {
+
+ // Initialize the inside/outside flags.
+ inside_four_flag = false;
+ outside_four_flag = false;
+ block_chair_flag = false;
+
+ // Initialize the inside/outside arrays.
+ for (int i=0; i<18; i++) {
+ inside_four[i][0] = 0;
+ inside_four[i][1] = 0;
+ outside_four[i][0] = 0;
+ outside_four[i][1] = 0;
+ }
+
+ // Initialize the faces array.
+ for (int i=0; i<18; i++) {
+ faces[i][0] = 0;
+ faces[i][1] = 0;
+ }
+
+ // Initialize the board.
+ for (int i=0; i<64; i++) {
+ occupied[i] = 0;
+ }
+ for (int i=0; i<76; i++) {
+ combinations[i][0] = 0;
+ combinations[i][1] = 0;
+ }
+
+ // Reset the best_picks array.
+ update_best_picks();
+
+ // Set the player with the first move.
+ player = HUMAN;
+
+ // Initialize the number of moves.
+ nmoves = 0;
+
+ // Reset the playing positions.
+ positions.newGame();
+ }
+
+
+ /**
+ * Set the skill level.
+ */
+ public void set_skill_level(int level) {
+ skill_level = level;
+ }
+
+
+ /**
+ * Set up the pos_to_comb array.
+ */
+ public void setup_pos_to_comb() {
+
+ // Set up the pos_to_comb array to point to every winning
+ // combination a given position may have.
+ int count;
+ for (int i=0; i<64; i++) {
+ count = 1;
+ pos_to_comb[i][0] = 0;
+ for (int j=0; j<76; j++) {
+ for (int k=2; k<6; k++) {
+ if (combinations[j][k] == i) {
+ pos_to_comb[i][0]++;
+ pos_to_comb[i][count++] = j;
+ }
+ }
+ }
+ }
+
+ if (debug) {
+ for (int i=0; i<64; i++) {
+ System.out.println("");
+ for (int j=0; j<8; j++) {
+ System.out.println("pos_to_comb[" + i + "][" + j + "] = " + pos_to_comb[i][j]);
+ }
+ }
+ }
+
+ }
+
+
+ /**
+ * Update the best_picks array.
+ */
+ public void update_best_picks() {
+
+ // Re-calculate the best_picks array to point to every (current) winning
+ // combination a given position may have.
+ int count;
+ for (int i=0; i<64; i++) {
+
+ count = 1;
+ best_picks[i][0] = 0;
+ if (occupied[i] == 0) {
+ for (int j=0; j<76; j++) {
+
+ if (combinations[j][0] == 0 ||
+ combinations[j][1] == MACHINE) {
+
+ for (int k=2; k<6; k++) {
+ if (combinations[j][k] == i) {
+ best_picks[i][0]++;
+ best_picks[i][count++] = j;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (debug) {
+ for (int i=0; i<64; i++) {
+ System.out.println("");
+ for (int j=0; j<8; j++) {
+ System.out.println("best_picks[" + i + "][" + j + "] = " + best_picks[i][j]);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Pick the computer's best possible move based on the number
+ * of combinations per position. Choose the position with the
+ * most combinations.
+ */
+ public void pick_best_position() {
+
+ int pos = 0;
+ int max_num = 0;
+ for (int i=0; i<64; i++) {
+ if (best_picks[i][0] > max_num &&
+ occupied[i] == 0) {
+ pos = i;
+ max_num = best_picks[i][0];
+ }
+ }
+
+ // Mark the position as MACHINE.
+ occupied[pos] = MACHINE;
+
+ positions.set(pos, MACHINE);
+
+ // Udate the logic arrays and reset the player.
+ player = update_logic_arrays(pos);
+ }
+
+
+ public boolean pick_7() {
+
+ for (int i=0; i<64; i++) {
+ if (best_picks[i][0] == 7) {
+ occupied[i] = MACHINE;
+ positions.set(i, MACHINE);
+ player = update_logic_arrays(i);
+ return true;
+ }
+ }
+ return false;
+
+ }
+
+ public void change_face() {
+ current_face = ++current_face%18;
+ }
+
+ public void label() {
+ label_flag ^= true;
+ }
+
+ public boolean unoccupied(int pos) {
+ if (occupied[pos] == UNOCCUPIED)
+ return true;
+ else
+ return false;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java
new file mode 100644
index 0000000..bc0e9b7
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java
@@ -0,0 +1,94 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+
+/**
+ * Class: Canvas2D
+ *
+ * Description: Used to respond to mouse events in the 2D window.
+ *
+ * Version: 1.0
+ *
+ */
+class Canvas2D extends Canvas implements MouseListener {
+
+ Image backbuffer; // Backbuffer image
+ Graphics gc; // Graphics context of backbuffer
+ Board board; // Game board
+
+ Canvas2D(Board board) {
+ this.board = board;
+ }
+
+ public void setBuffer(Image backbuffer) {
+ this.backbuffer = backbuffer;
+ gc = backbuffer.getGraphics();
+ }
+
+ public void update(Graphics g) {
+ paint(g);
+ }
+
+ public void paint(Graphics g) {
+ if (board != null) {
+ board.render2D(gc);
+ g.drawImage(backbuffer, 0, 0, this);
+ }
+ }
+
+ public void mousePressed(MouseEvent e) {
+ board.checkSelection2D(e.getX(), e.getY(), 1);
+ repaint();
+ }
+
+ public void mouseClicked(MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseExited(MouseEvent e) {}
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/Cube.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/Cube.java
new file mode 100644
index 0000000..d69df45
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/Cube.java
@@ -0,0 +1,133 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import java.applet.Applet;
+import java.awt.event.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Cube extends Object {
+
+ private Shape3D shape3D;
+
+ private static final float[] verts = {
+ // Front Face
+ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
+ // Back Face
+ -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
+ // Right Face
+ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
+ // Left Face
+ -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
+ // Top Face
+ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
+ // Bottom Face
+ -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f,
+ };
+
+ private static final float[] normals = {
+ // Front Face
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ // Back Face
+ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
+ // Right Face
+ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+ // Left Face
+ -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
+ // Top Face
+ 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+ // Bottom Face
+ 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
+ };
+
+ public Cube(Appearance appearance) {
+
+ QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES |
+ QuadArray.NORMALS |
+ QuadArray.TEXTURE_COORDINATE_2);
+ quadArray.setCoordinates(0, verts);
+ quadArray.setNormals(0, normals);
+
+ shape3D = new Shape3D(quadArray, appearance);
+ shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
+ shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ }
+
+ public Cube(Appearance appearance, float size) {
+
+ QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES |
+ QuadArray.NORMALS);
+ for (int i=0; i<72; i++)
+ verts[i] *= size;
+
+ quadArray.setCoordinates(0, verts);
+ quadArray.setNormals(0, normals);
+
+ shape3D = new Shape3D(quadArray, appearance);
+ shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
+ shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ }
+
+ public Shape3D getChild() {
+ return shape3D;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/Cylinder.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/Cylinder.java
new file mode 100644
index 0000000..670c31c
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/Cylinder.java
@@ -0,0 +1,116 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Cylinder {
+
+ float verts[];
+ float normals[];
+ QuadArray quad = null;
+ float div = 3.0f;
+ Shape3D shape;
+
+ public Cylinder(float x, float z, float radius, float length, int quality, Appearance a) {
+
+ if (quality < 3) quality = 3;
+
+ div = (float) quality;
+
+ verts = new float[quality*12];
+ normals = new float[quality*12];
+
+ double inc = 2.0*Math.PI/(double)div;
+ for (int i=0; i< quality; i++){
+ float z1 = radius * (float)Math.sin((double)i*inc) + z;
+ float x1 = radius * (float)Math.cos((double)i*inc) + x;
+ float z2 = radius * (float)Math.sin((double)(i+1)*inc) + z;
+ float x2 = radius * (float)Math.cos((double)(i+1)*inc) + x;
+
+ verts[12*i] = x1;
+ verts[12*i+1] = -length/2.f;
+ verts[12*i+2] = z1;
+ verts[12*i+3] = x1;
+ verts[12*i+4] = length/2.f;
+ verts[12*i+5] = z1;
+ verts[12*i+6] = x2;
+ verts[12*i+7] = length/2.f;
+ verts[12*i+8] = z2;
+ verts[12*i+9] = x2;
+ verts[12*i+10] = -length/2.f;
+ verts[12*i+11] = z2;
+
+ float nz1 = (float)Math.sin((double)i*inc);
+ float nx1 = (float)Math.cos((double)i*inc);
+ float nz2 = (float)Math.sin((double)(i+1)*inc);
+ float nx2 = (float)Math.cos((double)(i+1)*inc);
+
+ normals[12*i] = nx1;
+ normals[12*i+1] = 0.0f;
+ normals[12*i+2] = nz1;
+ normals[12*i+3] = nx1;
+ normals[12*i+4] = 0.0f;
+ normals[12*i+5] = nz1;
+ normals[12*i+6] = nx2;
+ normals[12*i+7] = 0.0f;
+ normals[12*i+8] = nz2;
+ normals[12*i+9] = nx2;
+ normals[12*i+10] = 0.0f;
+ normals[12*i+11] = nz2;
+ }
+
+ quad = new QuadArray(quality*4, QuadArray.COORDINATES |
+ QuadArray.NORMALS );
+ quad.setCoordinates(0, verts);
+ quad.setNormals(0, normals);
+ shape = new Shape3D(quad, a);
+ }
+
+ Shape3D getShape(){
+ return shape;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.html b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.html
new file mode 100644
index 0000000..8adb168
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.html
@@ -0,0 +1,15 @@
+<HTML>
+<HEAD>
+<TITLE>Drag the mouse in the window</TITLE>
+</HEAD>
+<BODY BGCOLOR="#0C0C33">
+<applet align=middle code="FourByFour.class" width=716 height=410>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see "FourByFour" instead of this paragraph.
+<hr>
+</blockquote>
+</applet>
+</BODY>
+</HTML>
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.java
new file mode 100644
index 0000000..744086c
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.java
@@ -0,0 +1,886 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.net.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import com.sun.j3d.utils.universe.SimpleUniverse;
+import com.sun.j3d.utils.applet.MainFrame;
+
+/**
+ * Class FourByFour
+ *
+ * Description: High level class for the game FourByFour
+ *
+ * Version: 1.2
+ *
+ */
+public class FourByFour extends Applet implements ActionListener {
+
+ String host; // Host from which this applet came from
+ int port; // Port number for writing high scores
+ Image backbuffer2D; // Backbuffer image used for 2D double buffering
+ int width, height; // Size of the graphics window in pixels
+ int score; // Final game score
+ int level_weight; // Weighting factor for skill level
+ int move_weight; // Weighting factor for number of moves to win
+ int time_weight; // Weighting factor for amount of time it took to win
+ int skill_level; // Skill level, 0 - 4
+ Canvas2D canvas2D; // 2D rendering canvas
+ Canvas3D canvas3D; // 3D rendering canvas
+ Board board; // Game board object
+ Panel b_container; // Container to hold the buttons
+ Panel c_container; // Container to hold the canvas
+ Panel l_container; // Container to hold the labels
+ Panel skill_panel; // Panel to hold skill levels
+ Panel instruct_panel; // Panel to hold instructions
+ Panel winner_panel; // Panel to hold winner announcement
+ Panel high_panel; // Panel to hold high scores
+ Button instruct_button; // Instructions button
+ Button new_button; // New Game button
+ Button skill_button; // Skill Level button
+ Button high_button; // High Scores button
+ Button undo_button; // Undo Move button
+ Label skill_label; // Label on skill panel
+ Label winner_label; // Label on winner panel
+ Label winner_score_label; // Score label on winner panel
+ Label winner_name_label; // Name label on winner panel
+ Label winner_top_label; // Top 20 label on winner panel
+ Label high_label; // High score label
+ Label high_places[]; // Labels to hold places
+ Label high_names[]; // Labels to hold names
+ Label high_scores[]; // Labels to hold scores
+ TextArea instruct_text; // TextArea object that holds instructions
+ TextArea high_text; // TextArea object that holds top 20 scores
+ TextField winner_name; // TextField object that holds winner's name
+ Button instruct_return_button; // Return button for instruction panel
+ Button skill_return_button; // Return button for skill level panel
+ Button winner_return_button; // Return button for winner panel
+ Button high_return_button; // Return button for high scores panel
+ CheckboxGroup group; // CheckboxGroup object for skill level panel
+ InputStream inStream; // Input stream for reading instructions and high scores
+ OutputStream outStream; // Output stream for writing high scores
+ static boolean appletFlag = true; // Applet flag
+ boolean winner_flag = false; // Winner flag
+ byte text[]; // Temporary storage area for reading instructions file
+ byte outText[]; // Temporary storage area for writing high scores file
+ String textString; // Storage area for instructions
+ String scoresString; // String used for writing high scores file
+ int places[]; // Storage area for high score places
+ int scores[]; // Storage area for high score scores
+ String names[]; // Storage area for high score names
+ Positions positions; // Positions object, used to render player positions
+
+ private SimpleUniverse universe = null;
+
+ /**
+ * Initialization
+ */
+ public void init() {
+
+ // Set the port number.
+ port = 4111;
+
+ // Set the graphics window size.
+ width = 350;
+ height = 350;
+
+ // Set the weighting factors used for scoring.
+ level_weight = 1311;
+ move_weight = 111;
+ time_weight = 1000;
+
+ // Create the "base" color for the AWT components.
+ setBackground(new Color(200, 200, 200));
+
+ // Read the instructions file.
+ if (appletFlag) {
+
+ // Get the host from which this applet came.
+ host = getCodeBase().getHost();
+
+ try {
+ inStream = new BufferedInputStream
+ (new URL(getCodeBase(), "instructions.txt").openStream(), 8192);
+ text = new byte[5000];
+ int character = inStream.read();
+ int count = 0;
+ while (character != -1) {
+ text[count++] = (byte) character;
+ character = inStream.read();
+ }
+ textString = new String(text);
+ inStream.close();
+ }
+ catch(Exception e) {
+ System.out.println("Error: " + e.toString());
+ }
+ }
+ else {
+
+ try {
+ inStream = new BufferedInputStream
+ (new FileInputStream("instructions.txt"));
+ text = new byte[5000];
+ int character = inStream.read();
+ int count = 0;
+ while (character != -1) {
+ text[count++] = (byte) character;
+ character = inStream.read();
+ }
+ textString = new String(text);
+ inStream.close();
+ }
+ catch(Exception e) {
+ System.out.println("Error: " + e.toString());
+ }
+ }
+
+ // Read the high-scores file.
+ places = new int[20];
+ scores = new int[20];
+ names = new String[20];
+ if (appletFlag) {
+ try {
+ inStream = new BufferedInputStream
+ (new URL(getCodeBase(), "scores.txt").openStream(), 8192);
+ Reader read = new BufferedReader(new InputStreamReader(inStream));
+ StreamTokenizer st = new StreamTokenizer(read);
+ st.whitespaceChars(32,44);
+ st.eolIsSignificant(false);
+
+ int count = 0;
+ int token = st.nextToken();
+ boolean scoreFlag = true;
+ String string;
+ while (count<20) {
+ places[count] = (int) st.nval;
+ string = new String("");
+ token = st.nextToken();
+ while (token == StreamTokenizer.TT_WORD) {
+ string += st.sval;
+ string += " ";
+ token = st.nextToken();
+ }
+ names[count] = string;
+ scores[count] = (int) st.nval;
+ token = st.nextToken();
+ count++;
+ }
+ inStream.close();
+ }
+ catch(Exception e) {
+ System.out.println("Error: " + e.toString());
+ }
+ }
+ else {
+ try {
+ inStream = new BufferedInputStream
+ (new FileInputStream("scores.txt"));
+ Reader read = new BufferedReader(new InputStreamReader(inStream));
+ StreamTokenizer st = new StreamTokenizer(read);
+ st.whitespaceChars(32,44);
+ st.eolIsSignificant(false);
+
+ int count = 0;
+ int token = st.nextToken();
+ boolean scoreFlag = true;
+ String string;
+ while (count<20) {
+ places[count] = (int) st.nval;
+ string = new String("");
+ token = st.nextToken();
+ while (token == StreamTokenizer.TT_WORD) {
+ string += st.sval;
+ string += " ";
+ token = st.nextToken();
+ }
+ names[count] = string;
+ scores[count] = (int) st.nval;
+ token = st.nextToken();
+ count++;
+ }
+ inStream.close();
+ }
+ catch(Exception e) {
+ System.out.println("Error: " + e.toString());
+ }
+ }
+
+ // The positions object sets up the switch nodes which
+ // control the rendering of the player's positions.
+ positions = new Positions();
+
+ // Create the game board object which is responsible
+ // for keeping track of the moves on the game board
+ // and determining what move the computer should make.
+ board = new Board(this, positions, width, height);
+ positions.setBoard(board);
+
+ // Create a 2D graphics canvas.
+ canvas2D = new Canvas2D(board);
+ canvas2D.setSize(width, height);
+ canvas2D.setLocation(width+10, 5);
+ canvas2D.addMouseListener(canvas2D);
+ board.setCanvas(canvas2D);
+
+ // Create the 2D backbuffer
+ backbuffer2D = createImage(width, height);
+ canvas2D.setBuffer(backbuffer2D);
+
+ // Create a 3D graphics canvas.
+ canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ canvas3D.setSize(width, height);
+ canvas3D.setLocation(5, 5);
+
+ // Create the scene branchgroup.
+ BranchGroup scene3D = createScene3D();
+
+ // Create a universe with the Java3D universe utility.
+ universe = new SimpleUniverse(canvas3D);
+ universe.addBranchGraph(scene3D);
+
+ // Use parallel projection.
+ View view = universe.getViewer().getView();
+ view.setProjectionPolicy(View.PARALLEL_PROJECTION);
+
+ // Set the universe Transform3D object.
+ TransformGroup tg =
+ universe.getViewingPlatform().getViewPlatformTransform();
+ Transform3D transform = new Transform3D();
+ transform.set(65.f, new Vector3f(0.0f, 0.0f, 400.0f));
+ tg.setTransform(transform);
+
+ // Create the canvas container.
+ c_container = new Panel();
+ c_container.setSize(720, 360);
+ c_container.setLocation(0, 0);
+ c_container.setVisible(true);
+ c_container.setLayout(null);
+ add(c_container);
+
+ // Add the 2D and 3D canvases to the container.
+ c_container.add(canvas2D);
+ c_container.add(canvas3D);
+
+ // Turn off the layout manager, widgets will be sized
+ // and positioned explicitly.
+ setLayout(null);
+
+ // Create the button container.
+ b_container = new Panel();
+ b_container.setSize(720, 70);
+ b_container.setLocation(0, 360);
+ b_container.setVisible(true);
+ b_container.setLayout(null);
+
+ // Create the buttons.
+ instruct_button = new Button("Instructions");
+ instruct_button.setSize(135, 25);
+ instruct_button.setLocation(10, 10);
+ instruct_button.setVisible(true);
+ instruct_button.addActionListener(this);
+
+ new_button = new Button("New Game");
+ new_button.setSize(135, 25);
+ new_button.setLocation(150, 10);
+ new_button.setVisible(true);
+ new_button.addActionListener(this);
+
+ undo_button = new Button("Undo Move");
+ undo_button.setSize(135, 25);
+ undo_button.setLocation(290, 10);
+ undo_button.setVisible(true);
+ undo_button.addActionListener(this);
+
+ skill_button = new Button("Skill Level");
+ skill_button.setSize(135, 25);
+ skill_button.setLocation(430, 10);
+ skill_button.setVisible(true);
+ skill_button.addActionListener(this);
+
+ high_button = new Button("High Scores");
+ high_button.setSize(135, 25);
+ high_button.setLocation(570, 10);
+ high_button.setVisible(true);
+ high_button.addActionListener(this);
+
+ b_container.add(new_button);
+ b_container.add(undo_button);
+ b_container.add(skill_button);
+ b_container.add(high_button);
+ b_container.add(instruct_button);
+
+ // Add the button container to the applet.
+ add(b_container);
+
+ // Create the "Skill Level" dialog box.
+ skill_panel = new Panel();
+ skill_panel.setSize(400, 300);
+ skill_panel.setLocation(200, 20);
+ skill_panel.setLayout(null);
+
+ skill_label = new Label("Pick your skill level:");
+ skill_label.setSize(200, 25);
+ skill_label.setLocation(25, 20);
+ skill_label.setVisible(true);
+ skill_panel.add(skill_label);
+
+ group = new CheckboxGroup();
+ Checkbox skill_1 = new Checkbox("Babe in the Woods ", group, false);
+ Checkbox skill_2 = new Checkbox("Walk and Chew Gum ", group, false);
+ Checkbox skill_3 = new Checkbox("Jeopardy Contestant ", group, false);
+ Checkbox skill_4 = new Checkbox("Rocket Scientist ", group, false);
+ Checkbox skill_5 = new Checkbox("Be afraid, be very afraid", group, true);
+ skill_1.setSize(170, 25);
+ skill_1.setLocation(80, 60);
+ skill_1.setVisible(true);
+ skill_2.setSize(170, 25);
+ skill_2.setLocation(80, 100);
+ skill_2.setVisible(true);
+ skill_3.setSize(170, 25);
+ skill_3.setLocation(80, 140);
+ skill_3.setVisible(true);
+ skill_4.setSize(170, 25);
+ skill_4.setLocation(80, 180);
+ skill_4.setVisible(true);
+ skill_5.setSize(170, 25);
+ skill_5.setLocation(80, 220);
+ skill_5.setVisible(true);
+ skill_return_button = new Button("Return");
+ skill_return_button.setSize(120, 25);
+ skill_return_button.setLocation(300, 370);
+ skill_return_button.setVisible(false);
+ skill_return_button.addActionListener(this);
+ skill_panel.add(skill_1);
+ skill_panel.add(skill_2);
+ skill_panel.add(skill_3);
+ skill_panel.add(skill_4);
+ skill_panel.add(skill_5);
+ skill_panel.setVisible(false);
+ add(skill_return_button);
+ add(skill_panel);
+
+ // Create the "Instructions" panel.
+ instruct_return_button = new Button("Return");
+ instruct_return_button.setLocation(300, 370);
+ instruct_return_button.setSize(120, 25);
+ instruct_return_button.setVisible(false);
+ instruct_return_button.addActionListener(this);
+ instruct_text =
+ new TextArea(textString, 100, 200, TextArea.SCROLLBARS_VERTICAL_ONLY);
+ instruct_text.setSize(715, 350);
+ instruct_text.setLocation(0, 0);
+ instruct_text.setVisible(false);
+ add(instruct_text);
+
+ add(instruct_return_button);
+
+ high_panel = new Panel();
+ high_panel.setSize(715, 350);
+ high_panel.setLocation(0, 0);
+ high_panel.setVisible(false);
+ high_panel.setLayout(null);
+
+ high_label = new Label("High Scores");
+ high_label.setLocation(330, 5);
+ high_label.setSize(200, 30);
+ high_label.setVisible(true);
+ high_panel.add(high_label);
+
+ high_places = new Label[20];
+ high_names = new Label[20];
+ high_scores = new Label[20];
+ for (int i=0; i<20; i++) {
+ high_places[i] = new Label(Integer.toString(i+1));
+ high_places[i].setSize(20, 30);
+ high_places[i].setVisible(true);
+ high_names[i] = new Label(names[i]);
+ high_names[i].setSize(150, 30);
+ high_names[i].setVisible(true);
+ high_scores[i] = new Label(Integer.toString(scores[i]));
+ high_scores[i].setSize(150, 30);
+ high_scores[i].setVisible(true);
+ if (i<10) {
+ high_places[i].setLocation(70, i*30+40);
+ high_names[i].setLocation(100, i*30+40);
+ high_scores[i].setLocation(260, i*30+40);
+ }
+ else {
+ high_places[i].setLocation(425, (i-10)*30+40);
+ high_names[i].setLocation(455, (i-10)*30+40);
+ high_scores[i].setLocation(615, (i-10)*30+40);
+ }
+ high_panel.add(high_places[i]);
+ high_panel.add(high_names[i]);
+ high_panel.add(high_scores[i]);
+ }
+ high_return_button = new Button("Return");
+ high_return_button.setSize(120, 25);
+ high_return_button.setLocation(300, 370);
+ high_return_button.setVisible(false);
+ high_return_button.addActionListener(this);
+ add(high_return_button);
+ add(high_panel);
+
+ // Create the "Winner" dialog box
+ winner_panel = new Panel();
+ winner_panel.setLayout(null);
+ winner_panel.setSize(600, 500);
+ winner_panel.setLocation(0, 0);
+ winner_return_button = new Button("Return");
+ winner_return_button.setSize(120, 25);
+ winner_return_button.setLocation(300, 360);
+ winner_return_button.addActionListener(this);
+ winner_panel.add(winner_return_button);
+ winner_label = new Label("");
+ winner_label.setSize(200, 30);
+ winner_label.setLocation(270, 110);
+ winner_score_label = new Label("");
+ winner_score_label.setSize(200, 30);
+ winner_top_label = new Label("You have a score in the top 20.");
+ winner_top_label.setSize(200, 25);
+ winner_top_label.setLocation(260, 185);
+ winner_top_label.setVisible(false); winner_name_label = new Label("Enter your name here:");
+ winner_name_label.setSize(150, 25);
+ winner_name_label.setLocation(260, 210);
+ winner_name_label.setVisible(false);
+ winner_name = new TextField("");
+ winner_name.setSize(200, 30);
+ winner_name.setLocation(260, 240);
+ winner_name.setVisible(false);
+ winner_panel.add(winner_label);
+ winner_panel.add(winner_score_label);
+ winner_panel.add(winner_top_label);
+ winner_panel.add(winner_name_label);
+ winner_panel.add(winner_name);
+ winner_panel.setVisible(false);
+ add(winner_panel);
+ }
+
+ public void destroy() {
+ universe.cleanup();
+ }
+
+ /**
+ * Create the scenegraph for the 3D view.
+ */
+ public BranchGroup createScene3D() {
+
+ // Define colors
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f red = new Color3f(0.80f, 0.20f, 0.2f);
+ Color3f ambient = new Color3f(0.25f, 0.25f, 0.25f);
+ Color3f diffuse = new Color3f(0.7f, 0.7f, 0.7f);
+ Color3f specular = new Color3f(0.9f, 0.9f, 0.9f);
+ Color3f ambientRed = new Color3f(0.2f, 0.05f, 0.0f);
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+
+ // Create the branch group
+ BranchGroup branchGroup = new BranchGroup();
+
+ // Create the bounding leaf node
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 1000.0);
+ BoundingLeaf boundingLeaf = new BoundingLeaf(bounds);
+ branchGroup.addChild(boundingLeaf);
+
+ // Create the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ branchGroup.addChild(bg);
+
+ // Create the ambient light
+ AmbientLight ambLight = new AmbientLight(white);
+ ambLight.setInfluencingBounds(bounds);
+ branchGroup.addChild(ambLight);
+
+ // Create the directional light
+ Vector3f dir = new Vector3f(-1.0f, -1.0f, -1.0f);
+ DirectionalLight dirLight = new DirectionalLight(white, dir);
+ dirLight.setInfluencingBounds(bounds);
+ branchGroup.addChild(dirLight);
+
+ // Create the pole appearance
+ Material poleMaterial =
+ new Material(ambient, black, diffuse, specular, 110.f);
+ poleMaterial.setLightingEnable(true);
+ Appearance poleAppearance = new Appearance();
+ poleAppearance.setMaterial(poleMaterial);
+
+ // Create the transform group node
+ TransformGroup transformGroup = new TransformGroup();
+ transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ branchGroup.addChild(transformGroup);
+
+ // Create the poles
+ Poles poles = new Poles(poleAppearance);
+ transformGroup.addChild(poles.getChild());
+
+ // Add the position markers to the transform group
+ transformGroup.addChild(positions.getChild());
+
+ // Let the positions object know about the transform group
+ positions.setTransformGroup(transformGroup);
+
+ // Create the mouse pick and drag behavior node
+ PickDragBehavior behavior = new PickDragBehavior(canvas2D, canvas3D, positions,
+ branchGroup, transformGroup);
+ behavior.setSchedulingBounds(bounds);
+ transformGroup.addChild(behavior);
+
+ return branchGroup;
+ }
+
+ public void actionPerformed (ActionEvent event) {
+
+ Object target = event.getSource();
+
+ // Process the button events.
+ if (target == skill_return_button) {
+ skill_panel.setVisible(false);
+ skill_return_button.setVisible(false);
+ c_container.setVisible(true);
+ b_container.setVisible(true);
+ newGame();
+ }
+ else if (target == winner_return_button) {
+ if (winner_flag) {
+ String name = winner_name.getText();
+ String tmp_name = new String("");
+ int tmp_score = 0;
+ boolean insert_flag = false;
+ winner_flag = false;
+ for (int i=0; i<20; i++) {
+ if (insert_flag) {
+ name = names[i];
+ score = scores[i];
+ names[i] = tmp_name;
+ scores[i] = tmp_score;
+ tmp_name = name;
+ tmp_score = score;
+ }
+ if (!insert_flag && score > scores[i]) {
+ tmp_name = names[i];
+ tmp_score = scores[i];
+ scores[i] = score;
+ names[i] = name;
+ insert_flag = true;
+ }
+ high_names[i].setText(names[i]);
+ high_scores[i].setText(Integer.toString(scores[i]));
+ }
+ scoresString = new String("");
+ int place;
+ for (int i=0; i<20; i++) {
+ place = (int) places[i];
+ scoresString += Integer.toString(place);
+ scoresString += "\t";
+ scoresString += names[i];
+ scoresString += " ";
+ scoresString += Integer.toString(scores[i]);
+ scoresString += "\n";
+ }
+
+ if (appletFlag) {
+ // Use this section of code when writing the high
+ // scores file back to a server. Requires the use
+ // of a deamon on the server to receive the socket
+ // connection.
+ //
+ // Create the output stream.
+ // try {
+ // Socket socket = new Socket(host, port);
+ // outStream = new BufferedOutputStream
+ // (socket.getOutputStream(), 8192);
+ // }
+ // catch(IOException ioe) {
+ // System.out.println("Error: " + ioe.toString());
+ // }
+ // System.out.println("Output stream opened");
+ //
+ // Write the scores to the file back on the server.
+ // outText = scoresString.getBytes();
+ // try {
+ // outStream.write(outText);
+ // outStream.flush();
+ // outStream.close();
+ // outStream = null;
+ // }
+ // catch (IOException ioe) {
+ // System.out.println("Error: " + ioe.toString());
+ // }
+ // System.out.println("Output stream written");
+
+ try {
+ OutputStreamWriter outFile =
+ new OutputStreamWriter(new FileOutputStream("scores.txt"));
+ outFile.write(scoresString);
+ outFile.flush();
+ outFile.close();
+ outFile = null;
+ }
+ catch (IOException ioe) {
+ System.out.println("Error: " + ioe.toString());
+ }
+ catch (Exception e) {
+ System.out.println("Error: " + e.toString());
+ }
+ }
+ else {
+
+ try {
+ OutputStreamWriter outFile =
+ new OutputStreamWriter(new FileOutputStream("scores.txt"));
+ outFile.write(scoresString);
+ outFile.flush();
+ outFile.close();
+ outFile = null;
+ }
+ catch (IOException ioe) {
+ System.out.println("Error: " + ioe.toString());
+ }
+ }
+ }
+ winner_panel.setVisible(false);
+ winner_return_button.setVisible(false);
+ winner_label.setVisible(false);
+ winner_score_label.setVisible(false);
+ winner_name_label.setVisible(false);
+ winner_top_label.setVisible(false);
+ winner_name.setVisible(false);
+ c_container.setVisible(true);
+ b_container.setVisible(true);
+ }
+ else if (target == high_return_button) {
+ high_return_button.setVisible(false);
+ high_panel.setVisible(false);
+ c_container.setVisible(true);
+ b_container.setVisible(true);
+ }
+ else if (target == instruct_return_button) {
+ instruct_text.setVisible(false);
+ instruct_return_button.setVisible(false);
+ instruct_text.repaint();
+ c_container.setVisible(true);
+ b_container.setVisible(true);
+ }
+ else if (target == undo_button) {
+ board.undo_move();
+ canvas2D.repaint();
+ }
+ else if (target == instruct_button) {
+ c_container.setVisible(false);
+ b_container.setVisible(false);
+ instruct_text.setVisible(true);
+ instruct_return_button.setVisible(true);
+ }
+ else if (target == new_button) {
+ newGame();
+ }
+ else if (target == skill_button) {
+ c_container.setVisible(false);
+ b_container.setVisible(false);
+ skill_panel.setVisible(true);
+ skill_return_button.setVisible(true);
+ }
+ else if (target == high_button) {
+ // Read the high scores file.
+ if (appletFlag) {
+ try {
+ inStream = new BufferedInputStream
+ (new URL(getCodeBase(), "scores.txt").openStream(), 8192);
+ Reader read = new BufferedReader(new InputStreamReader(inStream));
+ StreamTokenizer st = new StreamTokenizer(read);
+ st.whitespaceChars(32,44);
+ st.eolIsSignificant(false);
+
+ int count = 0;
+ int token = st.nextToken();
+ boolean scoreFlag = true;
+ String string;
+ while (count<20) {
+ places[count] = (int) st.nval;
+ string = new String("");
+ token = st.nextToken();
+ while (token == StreamTokenizer.TT_WORD) {
+ string += st.sval;
+ string += " ";
+ token = st.nextToken();
+ }
+ names[count] = string;
+ scores[count] = (int) st.nval;
+ token = st.nextToken();
+ count++;
+ }
+ inStream.close();
+ }
+ catch(Exception ioe) {
+ System.out.println("Error: " + ioe.toString());
+ }
+ }
+ else {
+ try {
+ inStream = new BufferedInputStream
+ (new FileInputStream("scores.txt"));
+ Reader read = new BufferedReader(new InputStreamReader(inStream));
+ StreamTokenizer st = new StreamTokenizer(read);
+ st.whitespaceChars(32,44);
+ st.eolIsSignificant(false);
+
+ int count = 0;
+ int token = st.nextToken();
+ boolean scoreFlag = true;
+ String string;
+ while (count<20) {
+ places[count] = (int) st.nval;
+ string = new String("");
+ token = st.nextToken();
+ while (token == StreamTokenizer.TT_WORD) {
+ string += st.sval;
+ string += " ";
+ token = st.nextToken();
+ }
+ names[count] = string;
+ scores[count] = (int) st.nval;
+ token = st.nextToken();
+ count++;
+ }
+ inStream.close();
+ }
+ catch(Exception ioe) {
+ System.out.println("Error: " + ioe.toString());
+ }
+ }
+ c_container.setVisible(false);
+ b_container.setVisible(false);
+ high_panel.setVisible(true);
+ high_return_button.setVisible(true);
+ }
+
+ Checkbox box = group.getSelectedCheckbox();
+ String label = box.getLabel();
+ if (label.equals("Babe in the Woods ")) {
+ board.set_skill_level(0);
+ }
+ else if (label.equals("Walk and Chew Gum ")) {
+ board.set_skill_level(1);
+ }
+ else if (label.equals("Jeopardy Contestant ")) {
+ board.set_skill_level(2);
+ }
+ else if (label.equals("Rocket Scientist ")) {
+ board.set_skill_level(3);
+ }
+ else if (label.equals("Be afraid, be very afraid")) {
+ board.set_skill_level(4);
+ }
+ }
+
+ public void newGame() {
+ board.newGame();
+ canvas2D.repaint();
+ }
+
+ public void start() {
+ if (appletFlag) showStatus("FourByFour");
+ }
+
+ public void winner(int player, int level, int nmoves, long time) {
+
+ if (player == 1) {
+ score = level * level_weight +
+ (66 - nmoves) * move_weight -
+ (int) Math.min(time * time_weight, 5000);
+ winner_label.setText("Game over, you win!");
+ winner_label.setLocation(290, 90);
+ winner_score_label.setText("Score = " + score);
+ winner_score_label.setVisible(true);
+ winner_score_label.setLocation(315, 120);
+ if (score > scores[19]) {
+ winner_name_label.setVisible(true);
+ winner_top_label.setVisible(true);
+ winner_name.setVisible(true);
+ winner_flag = true;
+ }
+ }
+ else {
+ winner_label.setText("Game over, the computer wins!");
+ winner_label.setLocation(250, 150);
+ }
+ c_container.setVisible(false);
+ b_container.setVisible(false);
+ winner_panel.setVisible(true);
+ winner_label.setVisible(true);
+ winner_return_button.setVisible(true);
+ repaint();
+ }
+
+ /**
+ * Inner class used to "kill" the window when running as
+ * an application.
+ */
+ static class killAdapter extends WindowAdapter {
+ public void windowClosing(WindowEvent event) {
+ System.exit(0);
+ }
+ }
+
+ /**
+ * Main method, only used when running as an application.
+ */
+ public static void main(String[] args) {
+ FourByFour.appletFlag = false;
+ new MainFrame(new FourByFour(), 730, 450);
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour_plugin.html b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour_plugin.html
new file mode 100644
index 0000000..55e1cf4
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour_plugin.html
@@ -0,0 +1,39 @@
+<HTML>
+<HEAD>
+<TITLE>Drag the mouse in the window</TITLE>
+</HEAD>
+<BODY BGCOLOR="#0C0C33">
+<!--"CONVERTED_APPLET"-->
+<!-- CONVERTER VERSION 1.3 -->
+<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+WIDTH = 716 HEIGHT = 410 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
+<PARAM NAME = CODE VALUE = "FourByFour.class" >
+
+<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2">
+<PARAM NAME="scriptable" VALUE="false">
+<COMMENT>
+<EMBED type="application/x-java-applet;version=1.2.2" CODE = "FourByFour.class" WIDTH = 716 HEIGHT = 410 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see "FourByFour" instead of this paragraph.
+<hr>
+</blockquote>
+</NOEMBED></EMBED>
+</OBJECT>
+
+<!--
+<APPLET CODE = "FourByFour.class" WIDTH = 716 HEIGHT = 410 ALIGN = middle>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see "FourByFour" instead of this paragraph.
+<hr>
+</blockquote>
+
+</APPLET>
+-->
+<!--"END_CONVERTED_APPLET"-->
+
+</BODY>
+</HTML>
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/ID.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/ID.java
new file mode 100644
index 0000000..a9c43df
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/ID.java
@@ -0,0 +1,61 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+class ID {
+ int id;
+
+ public ID(int id) {
+ this.id = id;
+ }
+
+ public int get() {
+ return id;
+ }
+
+ public void set(int id) {
+ this.id = id;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java
new file mode 100644
index 0000000..e6348a2
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java
@@ -0,0 +1,218 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import com.sun.j3d.utils.geometry.Sphere;
+
+/**
+ * Class: PickDragBehavior
+ *
+ * Description: Used to respond to mouse pick and drag events
+ * in the 3D window.
+ *
+ * Version: 1.0
+ *
+ */
+public class PickDragBehavior extends Behavior {
+
+ WakeupCriterion[] mouseEvents;
+ WakeupOr mouseCriterion;
+ int x, y;
+ int x_last, y_last;
+ double x_angle, y_angle;
+ double x_factor, y_factor;
+ Transform3D modelTrans;
+ Transform3D transformX;
+ Transform3D transformY;
+ TransformGroup transformGroup;
+ BranchGroup branchGroup;
+ Canvas2D canvas2D;
+ Canvas3D canvas3D;
+ Positions positions;
+ PickRay pickRay = new PickRay();
+ SceneGraphPath sceneGraphPath[];
+ Appearance highlight;
+ boolean parallel;
+
+ PickDragBehavior(Canvas2D canvas2D, Canvas3D canvas3D, Positions positions,
+ BranchGroup branchGroup, TransformGroup transformGroup) {
+
+ this.canvas2D = canvas2D;
+ this.canvas3D = canvas3D;
+ this.positions = positions;
+ this.branchGroup = branchGroup;
+ this.transformGroup = transformGroup;
+
+ modelTrans = new Transform3D();
+ transformX = new Transform3D();
+ transformY = new Transform3D();
+
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
+
+ highlight = new Appearance();
+ highlight.setMaterial(new Material(green, black, green, white, 80.f));
+
+ parallel = true;
+ }
+
+ public void initialize() {
+ x = 0;
+ y = 0;
+ x_last = 0;
+ y_last = 0;
+ x_angle = 0;
+ y_angle = 0;
+ x_factor = .02;
+ y_factor = .02;
+
+ mouseEvents = new WakeupCriterion[2];
+ mouseEvents[0] = new WakeupOnAWTEvent(MouseEvent.MOUSE_DRAGGED);
+ mouseEvents[1] = new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED);
+ mouseCriterion = new WakeupOr(mouseEvents);
+ wakeupOn (mouseCriterion);
+ }
+
+ public void processStimulus (Enumeration criteria) {
+ WakeupCriterion wakeup;
+ AWTEvent[] event;
+ int id;
+ int dx, dy;
+
+ while (criteria.hasMoreElements()) {
+ wakeup = (WakeupCriterion) criteria.nextElement();
+ if (wakeup instanceof WakeupOnAWTEvent) {
+ event = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
+ for (int i=0; i<event.length; i++) {
+ id = event[i].getID();
+ if (id == MouseEvent.MOUSE_DRAGGED) {
+
+ x = ((MouseEvent)event[i]).getX();
+ y = ((MouseEvent)event[i]).getY();
+
+ dx = x - x_last;
+ dy = y - y_last;
+
+ x_angle = dy * y_factor;
+ y_angle = dx * x_factor;
+
+ transformX.rotX(x_angle);
+ transformY.rotY(y_angle);
+
+ modelTrans.mul(transformX, modelTrans);
+ modelTrans.mul(transformY, modelTrans);
+
+ transformGroup.setTransform(modelTrans);
+
+ x_last = x;
+ y_last = y;
+ }
+ else if (id == MouseEvent.MOUSE_PRESSED) {
+
+ x = x_last = ((MouseEvent)event[i]).getX();
+ y = y_last = ((MouseEvent)event[i]).getY();
+
+ Point3d eyePos = new Point3d();
+ canvas3D.getCenterEyeInImagePlate(eyePos);
+
+ Point3d mousePos = new Point3d();
+ canvas3D.getPixelLocationInImagePlate(x, y, mousePos);
+
+ Transform3D transform3D = new Transform3D();
+ canvas3D.getImagePlateToVworld(transform3D);
+
+ transform3D.transform(eyePos);
+ transform3D.transform(mousePos);
+
+ Vector3d mouseVec;
+ if (parallel) {
+ mouseVec = new Vector3d(0.f, 0.f, -1.f);
+ }
+ else {
+ mouseVec = new Vector3d();
+ mouseVec.sub(mousePos, eyePos);
+ mouseVec.normalize();
+ }
+
+ pickRay.set(mousePos, mouseVec);
+ sceneGraphPath = branchGroup.pickAllSorted(pickRay);
+
+ if (sceneGraphPath != null) {
+ for (int j=0; j<sceneGraphPath.length; j++) {
+ if (sceneGraphPath[j] != null) {
+ Node node = sceneGraphPath[j].getObject();
+ if (node instanceof Shape3D) {
+ try {
+ ID posID = (ID) node.getUserData();
+ if (posID != null) {
+ int pos = posID.get();
+ positions.set(pos, Positions.HUMAN);
+ canvas2D.repaint();
+ break;
+ }
+ }
+ catch (CapabilityNotSetException e) {
+ // Catch all CapabilityNotSet exceptions and
+ // throw them away, prevents renderer from
+ // locking up when encountering "non-selectable"
+ // objects.
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ wakeupOn (mouseCriterion);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/Poles.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/Poles.java
new file mode 100644
index 0000000..0cf606c
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/Poles.java
@@ -0,0 +1,82 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import java.applet.Applet;
+import java.awt.event.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+/**
+ * Class: Poles
+ *
+ * Description: Creates the "poles" in the 3D window.
+ *
+ * Version: 1.0
+ *
+ */
+public class Poles extends Object {
+
+ private Group group;
+
+ public Poles(Appearance appearance) {
+ float x = -30.0f;
+ float z = -30.0f;
+ group = new Group();
+ for(int i=0; i<4; i++) {
+ for(int j=0; j<4; j++) {
+ Cylinder c = new Cylinder(x, z, 1.0f, 60.0f, 10, appearance);
+ group.addChild(c.getShape());
+ x += 20.0f;
+ }
+ x = -30.0f;
+ z += 20.0f;
+ }
+ }
+
+ public Group getChild() {
+ return group;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/Positions.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/Positions.java
new file mode 100644
index 0000000..6303c90
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/Positions.java
@@ -0,0 +1,313 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.four_by_four;
+
+import java.applet.Applet;
+import java.awt.event.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.BitSet;
+import com.sun.j3d.utils.geometry.Sphere;
+
+/**
+ * Class: Positions
+ *
+ * Description: Creates the position markers.
+ *
+ * Version: 1.0
+ *
+ */
+public class Positions extends Object {
+
+ final static int UNOCCUPIED = 0;
+ final static int HUMAN = 1;
+ final static int MACHINE = 2;
+ final static int END = 3;
+
+ private Vector3f point[];
+ private Switch posSwitch;
+ private Switch humanSwitch;
+ private Switch machineSwitch;
+ private BitSet posMask;
+ private BitSet humanMask;
+ private BitSet machineMask;
+ private Group group;
+ private Material redMat;
+ private Material blueMat;
+ private Material yellowMat;
+ private Material whiteMat;
+ private Appearance redApp;
+ private Appearance blueApp;
+ private Appearance yellowApp;
+ private Appearance whiteApp;
+ private Board board;
+ private Sphere posSphere[];
+ private BigCube cube[];
+ private TransformGroup tgroup;
+ private boolean winnerFlag = false;
+
+ public Positions() {
+
+ // Define colors for lighting
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f red = new Color3f(0.9f, 0.1f, 0.2f);
+ Color3f blue = new Color3f(0.3f, 0.3f, 0.8f);
+ Color3f yellow = new Color3f(1.0f, 1.0f, 0.0f);
+ Color3f ambRed = new Color3f(0.3f, 0.03f, 0.03f);
+ Color3f ambBlue = new Color3f(0.03f, 0.03f, 0.3f);
+ Color3f ambYellow = new Color3f(0.3f, 0.3f, 0.03f);
+ Color3f ambWhite = new Color3f(0.3f, 0.3f, 0.3f);
+ Color3f specular = new Color3f(1.0f, 1.0f, 1.0f);
+
+ // Create the red appearance node
+ redMat= new Material(ambRed, black, red, specular, 100.f);
+ redMat.setLightingEnable(true);
+ redApp = new Appearance();
+ redApp.setMaterial(redMat);
+
+ // Create the blue appearance node
+ blueMat= new Material(ambBlue, black, blue, specular, 100.f);
+ blueMat.setLightingEnable(true);
+ blueApp = new Appearance();
+ blueApp.setMaterial(blueMat);
+
+ // Create the yellow appearance node
+ yellowMat= new Material(ambYellow, black, yellow, specular, 100.f);
+ yellowMat.setLightingEnable(true);
+ yellowApp = new Appearance();
+ yellowApp.setMaterial(yellowMat);
+
+ // Create the white appearance node
+ whiteMat= new Material(ambWhite, black, white, specular, 100.f);
+ whiteMat.setLightingEnable(true);
+ whiteApp = new Appearance();
+ whiteApp.setMaterial(whiteMat);
+
+ // Load the point array with the offset (coordinates) for each of
+ // the 64 positions.
+ point = new Vector3f[64];
+ int count = 0;
+ for (int i=-30; i<40; i+=20) {
+ for (int j=-30; j<40; j+=20) {
+ for (int k=-30; k<40; k+=20) {
+ point[count] = new Vector3f((float) k, (float) j, (float) i);
+ count++;
+ }
+ }
+ }
+
+ // Create the switch nodes
+ posSwitch = new Switch(Switch.CHILD_MASK);
+ humanSwitch = new Switch(Switch.CHILD_MASK);
+ machineSwitch = new Switch(Switch.CHILD_MASK);
+
+ // Set the capability bits
+ posSwitch.setCapability(Switch.ALLOW_SWITCH_READ);
+ posSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
+
+ humanSwitch.setCapability(Switch.ALLOW_SWITCH_READ);
+ humanSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
+
+ machineSwitch.setCapability(Switch.ALLOW_SWITCH_READ);
+ machineSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
+
+ // Create the bit masks
+ posMask = new BitSet();
+ humanMask = new BitSet();
+ machineMask = new BitSet();
+
+ // Create the small white spheres that mark unoccupied
+ // positions.
+ posSphere = new Sphere[64];
+ for (int i=0; i<64; i++) {
+ Transform3D transform3D = new Transform3D();
+ transform3D.set(point[i]);
+ TransformGroup transformGroup = new TransformGroup(transform3D);
+ posSphere[i] = new Sphere(2.0f, Sphere.GENERATE_NORMALS |
+ Sphere.ENABLE_APPEARANCE_MODIFY,
+ 12, whiteApp);
+ Shape3D shape = posSphere[i].getShape();
+ ID id = new ID(i);
+ shape.setUserData(id);
+ transformGroup.addChild(posSphere[i]);
+ posSwitch.addChild(transformGroup);
+ posMask.set(i);
+ }
+
+ // Create the red spheres that mark the user's positions.
+ for (int i=0; i<64; i++) {
+ Transform3D transform3D = new Transform3D();
+ transform3D.set(point[i]);
+ TransformGroup transformGroup = new TransformGroup(transform3D);
+ transformGroup.addChild(new Sphere(7.0f, redApp));
+ humanSwitch.addChild(transformGroup);
+ humanMask.clear(i);
+ }
+
+ // Create the blue cubes that mark the computer's positions.
+ for (int i=0; i<64; i++) {
+ Transform3D transform3D = new Transform3D();
+ transform3D.set(point[i]);
+ TransformGroup transformGroup = new TransformGroup(transform3D);
+ BigCube cube = new BigCube(blueApp);
+ transformGroup.addChild(cube.getChild());
+ machineSwitch.addChild(transformGroup);
+ machineMask.clear(i);
+ }
+
+ // Set the positions mask
+ posSwitch.setChildMask(posMask);
+ humanSwitch.setChildMask(humanMask);
+ machineSwitch.setChildMask(machineMask);
+
+ // Throw everything into a single group
+ group = new Group();
+ group.addChild(posSwitch);
+ group.addChild(humanSwitch);
+ group.addChild(machineSwitch);
+ }
+
+ public void setTransformGroup(TransformGroup transformGroup) {
+ tgroup = transformGroup;
+ }
+
+ public Group getChild() {
+ return group;
+ }
+
+ public void setBoard(Board board) {
+ this.board = board;
+ }
+
+ public void winner() {
+ winnerFlag = true;
+ }
+
+ public void noWinner() {
+ winnerFlag = false;
+ }
+
+ public void setHighlight(int pos) {
+ posSphere[pos].setAppearance(yellowApp);
+ }
+
+ public void clearHighlight(int pos) {
+ posSphere[pos].setAppearance(whiteApp);
+ }
+
+ public void newGame() {
+
+ // Clear the board
+ for (int i=0; i<64; i++) {
+ posMask.set(i);
+ humanMask.clear(i);
+ machineMask.clear(i);
+ }
+ posSwitch.setChildMask(posMask);
+ humanSwitch.setChildMask(humanMask);
+ machineSwitch.setChildMask(machineMask);
+
+ // The following three lines fix a bug in J3D
+ Transform3D t = new Transform3D();
+ tgroup.getTransform(t);
+ tgroup.setTransform(t);
+
+ // Reset the winner flag
+ winnerFlag = false;
+ }
+
+ public void set(int pos, int player) {
+
+ // Stop accepting selections when the game
+ // is over.
+ if (winnerFlag) return;
+
+ // Make sure the position is not occupied.
+ if (player == HUMAN)
+ if (!board.unoccupied(pos)) return;
+
+ // Turn off the position marker for the given position
+ posMask.clear(pos);
+ posSwitch.setChildMask(posMask);
+
+ // Turn on the player marker
+ if (player == Positions.HUMAN) {
+ humanMask.set(pos);
+ humanSwitch.setChildMask(humanMask);
+ board.selection(pos, Positions.HUMAN);
+ }
+ else {
+ machineMask.set(pos);
+ machineSwitch.setChildMask(machineMask);
+ }
+
+ // The following three lines fix a bug in J3D
+ Transform3D t = new Transform3D();
+ tgroup.getTransform(t);
+ tgroup.setTransform(t);
+ }
+
+ public void clear(int pos) {
+
+ // Turn on the position marker
+ posMask.set(pos);
+ posSwitch.setChildMask(posMask);
+
+ // Turn off the player marker
+ humanMask.clear(pos);
+ humanSwitch.setChildMask(humanMask);
+ machineMask.clear(pos);
+ machineSwitch.setChildMask(machineMask);
+
+ // The following three lines are a workaround for a bug
+ // in dev09 in which the transform3D of certain items are
+ // not updated properly. Scheduled to be fixed in dev10
+ Transform3D t = new Transform3D();
+ tgroup.getTransform(t);
+ tgroup.setTransform(t);
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/README.txt b/src/classes/org/jdesktop/j3d/examples/four_by_four/README.txt
new file mode 100644
index 0000000..40798d0
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/README.txt
@@ -0,0 +1,8 @@
+FourByFour
+
+To run:
+
+ appletviewer FourByFour.html
+
+Press the "Instructions" button to get instructions on
+how to play FourByFour.
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/instructions.txt b/src/classes/org/jdesktop/j3d/examples/four_by_four/instructions.txt
new file mode 100644
index 0000000..36ded73
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/instructions.txt
@@ -0,0 +1,98 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+ Four By Four
+
+Description:
+
+ A three dimensional game of tic-tac-toe on a 4x4x4 cube.
+
+Object:
+
+ Be the first to score four in a row.
+
+Instructions:
+
+ 1. It's you versus the computer.
+
+ 2. There are five skill levels. Press the "Skill Level" button to select your level
+ of play. The program defaults to the hardest level. Changing the skill level in
+ the middle of a game will force the start of a new game.
+
+ 3. The screen on the left is a 3D window. A mouse drag in this window will rotate the
+ view to any desired position.
+
+ 4. The screen on the right is a 2D window which displays all 18 faces that exist in the
+ 4x4x4 array.
+
+ 5. Click on any of the small gray spheres (in either the 2D or 3D window) to select a position.
+
+ 6. Positions owned by you will be marked in red. Positions owned by the computer will be
+ marked in blue.
+
+ 7. Click the "Undo Move" button to take back a move.
+
+ 8. Clicking on any of words "Face X" in the 2D window will cause that particular face to highlight
+ in the 3D window. Clicking the word again will un-highlight the face.
+
+ 9. The final score is based on skill level, number of moves, and time. Select the button
+ "High Scores" to see a list of the top 20 scores. There is no penalty for using the
+ undo button.
+
+ 10. Good luck.
+
+General Strategy:
+
+ 1. There are a 64 positions from which to choose. In total, there are 72 possible winning
+ combinations.
+
+ 2. The outer four corners and the inner "core" of eight have the most winning combinations,
+ 7 each, and should perhaps be chosen first.
+
+ 3. Use the 2D window to keep an eye on all the faces.
+
+ 4. The computer plays well at the highest skill level (the default). There are, however,
+ faults in it's logic that can be exploited. Thus the human player can win even at the
+ highest skill level. In the beginning, however, you may want to start at the lower skill
+ levels and work your way up.
diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/scores.txt b/src/classes/org/jdesktop/j3d/examples/four_by_four/scores.txt
new file mode 100644
index 0000000..0ebc31a
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/scores.txt
@@ -0,0 +1,20 @@
+1 Bart Simpson 5283
+2 Dwight Eisenhower 5105
+3 Ken 5061
+4 Barbie 2883
+5 DoubleMint Twins 2195
+6 Robin Hood 1772
+7 Jack Benny 1604
+8 Anonymous 1550
+9 Duke 1501
+10 Jack Paar 1499
+11 Barney 1488
+12 Mick Jagger 1472
+13 Howard Hughes 1329
+14 Bugs Bunny 1328
+15 Suzi Chapstick 1302
+16 Forest Gump 1244
+17 Alfred Hitchcock 1231
+18 Roman Polaski 1168
+19 Missy Giovi 1106
+20 Bill Joy 1002
diff --git a/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java b/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java
new file mode 100644
index 0000000..e15a23c
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java
@@ -0,0 +1,281 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.fps_counter;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.text.*;
+
+/** This behavior calculates the frame rate and average frame rate of a
+ * Java3D application.
+ * The behavior sets itself up to wakeup every time a new frame is rendered.
+ *
+ * <p> The HotSpot(tm) compiler performs some initial optimizations before
+ * running at optimal speed. Frame rates measured during this warmup period
+ * will be inaccurate and not indicative of the true performance of the the
+ * application. Therefore, before beginning the frame rate computation,
+ * the frame counter waits for a fixed time period to allow the HotSpot(tm)
+ * compiler to stablilize.
+ *
+ * <p> To avoid computing the frame rate too frequently (which would also
+ * hamper rendering performance), the frame counter only computes the frame
+ * rate at fixed time intervals. The default sampling duration is 10 seconds.
+ * After waiting for the warmup period, the frame counter needs to calibrate
+ * itself. It computes the number of frames rendered during the sampling
+ * period. After doing this calibration, the frame counter reports the frame
+ * rate after these many frames are rendered. It also reports the average
+ * frame rate after a fixed number of sampling intervals (the default is 5).
+ *
+ * <p>The frame counter can be set up to run for a fixed number of sampling
+ * intervals or to run indefinitely. The defaultis to run indefinitely.
+ */
+
+public class FPSCounter extends Behavior {
+ // Wakeup condition - framecount = 0 -> wakeup on every frame
+ WakeupOnElapsedFrames FPSwakeup = new WakeupOnElapsedFrames(0);
+
+ // Do calibration for these many millisec
+ private static final long testduration = 1000;
+
+ // Report frame rate after every sampleduration milliseconds
+ private static final long sampleduration = 10000;
+
+ // Flag to indicate that it is time to (re)calibrate
+ private boolean doCalibration = true;
+
+ // Flag to indicate the counter has started
+ private boolean startup = true;
+
+ // Wait for HotSpot compiler to perform optimizations
+ private boolean warmup = true;
+
+ // Time to wait for HotSpot compiler to stabilize (in milliseconds)
+ private long warmupTime = 20000;
+
+ // Counter for number of frames rendered
+ private int numframes = 0;
+
+ // Report frame rate after maxframe number of frames have been rendered
+ private int maxframes = 1;
+
+ // Variables to keep track of elapsed time
+ private long startuptime = 0;
+ private long currtime = 0;
+ private long lasttime = 0;
+ private long deltatime;
+
+ // Run indefinitely or for a fixed duration
+ private boolean finiteLoop = false;
+
+ // No. of sampling intervals to run for if not running indefinitely
+ private long maxLoops;
+
+ // No. of sampling intervals run for so far
+ private long numLoops = 0;
+
+ // Total number of frames rendered so far
+ private int sumFrames = 0;
+
+ // Total time since last reporting of average frame rate
+ private long sumTimes = 0;
+
+ // Counts no. of sampling intervals
+ private int loop = 0;
+
+ // Average frame rate is reported after loopCount number of
+ // sampling intervals
+ private int loopCount = 5;
+ private double sumFps = 0.0;
+
+ private String symbol[] = {"\\", "|", "|", "/", "-", "|", "-"};
+ int index = 0;
+ private NumberFormat nf = null;
+
+ public FPSCounter() {
+ setEnable(true);
+ nf = NumberFormat.getNumberInstance();
+ }
+
+ /**
+ * Called to init the behavior
+ */
+ public void initialize() {
+ // Set the trigger for the behavior to wakeup on every frame rendered
+ wakeupOn(FPSwakeup);
+ }
+
+ /**
+ * Called every time the behavior is activated
+ */
+ public void processStimulus(java.util.Enumeration critera) {
+ // Apply calibration algorithm to determine number of frames to
+ // wait before computing frames per second.
+ // sampleduration = 10000 -> to run test, pass for 10 seconds.
+
+ if (doCalibration) { // start calibration
+ if (startup) {
+ // Record time at which the behavior was first invoked
+ startuptime = System.currentTimeMillis();
+ startup = false;
+ }
+ else if(warmup) { // Wait for the system to stabilize.
+ System.out.print("\rFPSCounter warming up..." +
+ symbol[(index++)%symbol.length]);
+ currtime = System.currentTimeMillis();
+ deltatime = currtime - startuptime;
+ if(deltatime > warmupTime) {
+ // Done waiting for warmup
+ warmup = false;
+ lasttime = System.currentTimeMillis();
+ System.out.println("\rFPSCounter warming up...Done");
+ }
+ }
+ else {
+ numframes += 1;
+ // Wait till at least maxframe no. of frames have been rendered
+ if (numframes >= maxframes) {
+ currtime = System.currentTimeMillis();
+ deltatime = currtime - lasttime;
+ // Do the calibration for testduration no. of millisecs
+ if (deltatime > testduration) {
+ // Compute total no. of frames rendered so far in the
+ // current sampling duration
+ maxframes = (int)Math.ceil((double)numframes *
+ ((double)sampleduration /
+ (double)deltatime));
+
+ // Done with calibration
+ doCalibration = false;
+ // reset the value for the measurement
+ numframes = 0;
+ lasttime = System.currentTimeMillis();
+ }
+ else {
+ // Need to run the calibration routine for some more
+ // time. Increase the no. of frames to be rendered
+ maxframes *= 2;
+ }
+ }
+ }
+ }
+ else { // do the measurement
+ numframes += 1;
+ if (numframes >= maxframes) {
+ currtime = System.currentTimeMillis();
+ deltatime = currtime - lasttime;
+ // time is in millisec, so multiply by 1000 to get frames/sec
+ double fps = (double)numframes / ((double)deltatime / 1000.0);
+
+ System.out.println("Frame Rate : \n\tNo. of frames : " +
+ numframes + "\n\tTime : " +
+ ((double)deltatime / 1000.0) +
+ " sec." + "\n\tFrames/sec : " + nf.format(fps));
+
+ // Calculate average frame rate
+ sumFrames += numframes;
+ sumTimes += deltatime;
+ sumFps += fps;
+ loop++;
+ if (loop >= loopCount) {
+ double avgFps = (double)sumFrames*1000.0/(double)sumTimes;
+ double ravgFps = sumFps/(double)loopCount;
+ System.out.println("Aggregate frame rate " +
+ nf.format(avgFps) + " frames/sec");
+ System.out.println("Average frame rate " +
+ nf.format(ravgFps) + " frames/sec");
+ numLoops++;
+ if (finiteLoop && numLoops >= maxLoops) {
+ System.out.println("************** The End **************\n");
+ setEnable(false);
+ }
+ loop = 0;
+ sumFps = 0;
+ }
+ numframes = 0;
+ lasttime = System.currentTimeMillis();;
+ }
+ }
+ // Set the trigger for the behavior
+ wakeupOn(FPSwakeup);
+ }
+
+ /**
+ * The frame counter waits for some time before computing the
+ * frame rate. This allows the HotSpot compiler to perform
+ * initial optimizations. The amount of time to wait for is set
+ * by this method. The default is 20000 (20 sec)
+ *
+ * @param amount of time to wait for before computing frame rate
+ * (specified in milliseconds)
+ */
+ public void setWarmupTime(long wt) {
+ warmupTime = wt;
+ }
+
+ /**
+ * Sets the number of sampling intervals to wait for before computing
+ * the average frame rate.
+ * The default is 5.
+ *
+ * @param number of sampling intervals over which to compute frame rate.
+ * A value of 0 implies the average frame rate is computed over one
+ * sampling interval
+ */
+ public void setLoopCount(int lc) {
+ loopCount = lc;
+ }
+
+ /**
+ * This method sets the number of sampling intervals for which
+ * the frame counter should run.
+ *
+ * @param number of sampling intervals to run for
+ */
+ public void setMaxLoops(int ml) {
+ maxLoops = ml;
+ finiteLoop = true;
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java b/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java
new file mode 100644
index 0000000..f73be9d
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java
@@ -0,0 +1,221 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.fps_counter;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.event.*;
+import java.awt.GraphicsConfiguration;
+import com.sun.j3d.utils.applet.JMainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import javax.swing.JOptionPane;
+
+/** This program demonstrates the use of the frames per second counter.
+ * The program displays a rotating cube and sets up the FPSCounter to compute
+ * the frame rate. The FPSCounter is set up with default values:
+ * - run indefinitely
+ * - 2 sec. warmup time
+ * - display average frame rate every fifth sampling interval.
+ * The default values can be changed through the command line
+ * arguments. Use FPSCounterDemo -h for help on the various arguments.
+ */
+
+public class FPSCounterDemo extends Applet {
+ private SimpleUniverse u = null;
+ private FPSCounter fpsCounter = new FPSCounter();
+
+ BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create the TransformGroup node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at run time. Add it to
+ // the root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // Create a simple Shape3D node; add it to the scene graph.
+ objTrans.addChild(new ColorCube(0.4));
+
+ // Create a new Behavior object that will perform the
+ // desired operation on the specified transform and add
+ // it into the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, 4000);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0),
+ 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objRoot.addChild(rotator);
+
+ // Create the Framecounter behavior
+ fpsCounter.setSchedulingBounds(bounds);
+ objRoot.addChild(fpsCounter);
+
+ return objRoot;
+ }
+
+
+ public FPSCounterDemo(String args[]) {
+ }
+
+ public FPSCounterDemo() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+
+ // Parse the command line to set the various parameters
+
+ // Have Java 3D perform optimizations on this scene graph.
+ scene.compile();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+
+ JOptionPane.showMessageDialog(this,
+ ("This program measures the number of frames rendered per second.\n" +
+ "Note that the frame rate is limited by the refresh rate of the monitor.\n" +
+ "To get the true frame rate you need to disable vertical retrace.\n\n" +
+ "On Windows(tm) you do this through the Control Panel.\n\n" +
+ "On Solaris set the environment variable OGL_NO_VBLANK"),
+ "Frame Counter",
+ JOptionPane.INFORMATION_MESSAGE);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows FPSCounterDemo to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ FPSCounterDemo fp = new FPSCounterDemo();
+ fp.parseArgs(args);
+ JMainFrame frame = new JMainFrame(fp, 256, 256);
+ }
+
+ /** Parses the commandline for the various switches to set the FPSCounter
+ * variables.
+ * All arguments are of the form <i>-name value</i>.
+ * All -name arguments can be shortened to one character. All the value
+ * arguments take a number. The arguments accepted are :
+ * <ul>
+ * <li>warmupTime : Specifies amount of time the FPSCounter should wait
+ * for the HotSpot<sup><font size="-2">TM</font></sup> VM to perform
+ * initial optimizations. Specified in milliseconds<br>
+ * <li>loopCount : Specifies the number of sampling intervals over which
+ * the FPSCounter should calculate the aggregate and average frame rate.
+ * Specified as a count. <br>
+ * <li>maxLoops : Specifies that the FPSCounter should run for only
+ * these many sampling intervals. Specified as number. If this argument
+ * is not specified, the FPSCounter runs indefinitely. <br>
+ * <li>help : Prints the accepted arguments. <br>
+ * </ul>
+ */
+ private void parseArgs(String args[]) {
+ for(int i = 0; i < args.length; i++) {
+ if(args[i].startsWith("-")) {
+ if(args[i].startsWith("w", 1)) {
+ i++;
+ System.out.println("Warmup time : " + args[i]);
+ int w = new Integer(args[i]).intValue();
+ fpsCounter.setWarmupTime(w);
+ }
+ else if(args[i].startsWith("l", 1)) {
+ i++;
+ System.out.println("Loop count : " + args[i]);
+ int l = new Integer(args[i]).intValue();
+ fpsCounter.setLoopCount(l);
+ }
+ else if(args[i].startsWith("m", 1)) {
+ i++;
+ System.out.println("Max Loop Count : " + args[i]);
+ int m = new Integer(args[i]).intValue();
+ fpsCounter.setMaxLoops(m);
+ }
+ else if(args[i].startsWith("h", 1)) {
+ System.out.println("Usage : FPSCounterDemo [-name value]\n" +
+ "All arguments are of the form: -name value. All -name arguments can be\n" +
+ "shortened to one character. All the value arguments take a number. The\n" +
+ "arguments accepted are:\n\n" +
+ " -warmupTime : Specifies amount of time the FPSCounter should wait\n" +
+ " for the HotSpot(tm) VM to perform initial\n" +
+ " optimizations. Specified in milliseconds\n\n" +
+ " -loopCount : Specifies the number of sampling intervals over which\n" +
+ " the FPSCounter should calculate the aggregate and average\n" +
+ " frame rate. Specified as a count\n\n" +
+ " -maxLoops : Specifies that the FPSCounter should run for only these\n" +
+ " many sampling intervals. Specified as number. If this argument\n" +
+ " is not specified, the FPSCounter runs indefinitely.\n\n" +
+ " -help : Prints this message.");
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/gears/Gear.java b/src/classes/org/jdesktop/j3d/examples/gears/Gear.java
new file mode 100644
index 0000000..fb1be1d
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/gears/Gear.java
@@ -0,0 +1,399 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.gears;
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Gear extends javax.media.j3d.TransformGroup {
+
+ // Specifiers determining whether to generate outward facing normals or
+ // inward facing normals.
+ static final int OutwardNormals = 1;
+ static final int InwardNormals = -1;
+
+ // The number of teeth in the gear
+ int toothCount;
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ double gearStartAngle;
+ // The Z-rotation angle to place the tooth center at theta = 0
+ float toothTopCenterAngle;
+ // The Z-rotation angle to place the valley center at theta = 0
+ float valleyCenterAngle;
+ // The angle about Z subtended by one tooth and its associated valley
+ float circularPitchAngle;
+
+ // Increment angles
+ float toothValleyAngleIncrement;
+
+ // Front and rear facing normals for the gear's body
+ final Vector3f frontNormal = new Vector3f(0.0f, 0.0f, -1.0f);
+ final Vector3f rearNormal = new Vector3f(0.0f, 0.0f, 1.0f);
+
+
+ Gear(int toothCount) {
+ this.toothCount = toothCount;
+ }
+
+ void addBodyDisks(float shaftRadius, float bodyOuterRadius,
+ float thickness, Appearance look) {
+ int gearBodySegmentVertexCount; // #(segments) per tooth-unit
+ int gearBodyTotalVertexCount; // #(vertices) in a gear face
+ int gearBodyStripCount[] = new int[1]; // per strip (1) vertex count
+
+ // A ray from the gear center, used in normal calculations
+ float xDirection, yDirection;
+
+ // The x and y coordinates at each point of a facet and at each
+ // point on the gear: at the shaft, the root of the teeth, and
+ // the outer point of the teeth
+ float xRoot0, yRoot0, xShaft0, yShaft0;
+ float xRoot3, yRoot3, xShaft3, yShaft3;
+ float xRoot4, yRoot4, xShaft4, yShaft4;
+
+ // Temporary variables for storing coordinates and vectors
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ double gearStartAngle = -1.0 * toothTopCenterAngle;
+
+ // Temporaries that store start angle for each portion of tooth facet
+ double toothStartAngle, toothTopStartAngle,
+ toothDeclineStartAngle, toothValleyStartAngle,
+ nextToothStartAngle;
+
+ Shape3D newShape;
+ int index;
+
+ // The z coordinates for the body disks
+ final float frontZ = -0.5f * thickness;
+ final float rearZ = 0.5f * thickness;
+
+ /* Construct the gear's front body (front facing torus disk)
+ * __2__
+ * - | - 4
+ * - /| /-
+ * / / | /| \
+ * 0\ / | / / >
+ * \ / | / | >
+ * \ / | / / |
+ * \ / ____|/ | >
+ * \-- --__/ |
+ * 1 3 5
+ *
+ */
+ gearBodySegmentVertexCount = 4;
+ gearBodyTotalVertexCount = 2 + gearBodySegmentVertexCount * toothCount;
+ gearBodyStripCount[0] = gearBodyTotalVertexCount;
+
+ TriangleStripArray frontGearBody
+ = new TriangleStripArray(gearBodyTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ gearBodyStripCount);
+
+ xDirection = (float)Math.cos(gearStartAngle);
+ yDirection = (float)Math.sin(gearStartAngle);
+ xShaft0 = shaftRadius * xDirection;
+ yShaft0 = shaftRadius * yDirection;
+ xRoot0 = bodyOuterRadius * xDirection;
+ yRoot0 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xRoot0, yRoot0, frontZ);
+ frontGearBody.setCoordinate(0, coordinate);
+ frontGearBody.setNormal(0, frontNormal);
+
+ coordinate.set(xShaft0, yShaft0, frontZ);
+ frontGearBody.setCoordinate(1, coordinate);
+ frontGearBody.setNormal(1, frontNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ xRoot3 = bodyOuterRadius * xDirection;
+ yRoot3 = bodyOuterRadius * yDirection;
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ xRoot4 = bodyOuterRadius * xDirection;
+ yRoot4 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xRoot3, yRoot3, frontZ);
+ frontGearBody.setCoordinate(index, coordinate);
+ frontGearBody.setNormal(index, frontNormal);
+
+ coordinate.set(xShaft3, yShaft3, frontZ);
+ frontGearBody.setCoordinate(index + 1, coordinate);
+ frontGearBody.setNormal(index + 1, frontNormal);
+
+ coordinate.set(xRoot4, yRoot4, frontZ);
+ frontGearBody.setCoordinate(index + 2, coordinate);
+ frontGearBody.setNormal(index + 2, frontNormal);
+
+ coordinate.set(xShaft4, yShaft4, frontZ);
+ frontGearBody.setCoordinate(index + 3, coordinate);
+ frontGearBody.setNormal(index + 3, frontNormal);
+ }
+ newShape = new Shape3D(frontGearBody, look);
+ this.addChild(newShape);
+
+ // Construct the gear's rear body (rear facing torus disc)
+ TriangleStripArray rearGearBody
+ = new TriangleStripArray(gearBodyTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ gearBodyStripCount);
+ xDirection = (float)Math.cos(gearStartAngle);
+ yDirection = (float)Math.sin(gearStartAngle);
+ xShaft0 = shaftRadius * xDirection;
+ yShaft0 = shaftRadius * yDirection;
+ xRoot0 = bodyOuterRadius * xDirection;
+ yRoot0 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xShaft0, yShaft0, rearZ);
+ rearGearBody.setCoordinate(0, coordinate);
+ rearGearBody.setNormal(0, rearNormal);
+
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ rearGearBody.setCoordinate(1, coordinate);
+ rearGearBody.setNormal(1, rearNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ xRoot3 = bodyOuterRadius * xDirection;
+ yRoot3 = bodyOuterRadius * yDirection;
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ xRoot4 = bodyOuterRadius * xDirection;
+ yRoot4 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xShaft3, yShaft3, rearZ);
+ rearGearBody.setCoordinate(index, coordinate);
+ rearGearBody.setNormal(index, rearNormal);
+
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ rearGearBody.setCoordinate(index + 1, coordinate);
+ rearGearBody.setNormal(index + 1, rearNormal);
+
+ coordinate.set(xShaft4, yShaft4, rearZ);
+ rearGearBody.setCoordinate(index + 2, coordinate);
+ rearGearBody.setNormal(index + 2, rearNormal);
+
+ coordinate.set(xRoot4, yRoot4, rearZ);
+ rearGearBody.setCoordinate(index + 3, coordinate);
+ rearGearBody.setNormal(index + 3, rearNormal);
+
+ }
+ newShape = new Shape3D(rearGearBody, look);
+ this.addChild(newShape);
+ }
+
+ void addCylinderSkins(float shaftRadius, float length,
+ int normalDirection, Appearance look) {
+ int insideShaftVertexCount; // #(vertices) for shaft
+ int insideShaftStripCount[] = new int[1]; // #(vertices) in strip/strip
+ double toothStartAngle, nextToothStartAngle, toothValleyStartAngle;
+
+ // A ray from the gear center, used in normal calculations
+ float xDirection, yDirection;
+
+ // The z coordinates for the body disks
+ final float frontZ = -0.5f * length;
+ final float rearZ = 0.5f * length;
+
+ // Temporary variables for storing coordinates, points, and vectors
+ float xShaft3, yShaft3, xShaft4, yShaft4;
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+ Vector3f surfaceNormal = new Vector3f();
+
+ Shape3D newShape;
+ int index;
+ int firstIndex;
+ int secondIndex;
+
+
+ /*
+ * Construct gear's inside shaft cylinder
+ * First the tooth's up, flat outer, and down distances
+ * Second the tooth's flat inner distance
+ *
+ * Outward facing vertex order:
+ * 0_______2____4
+ * | /| /|
+ * | / | / |
+ * | / | / |
+ * |/______|/___|
+ * 1 3 5
+ *
+ * Inward facing vertex order:
+ * 1_______3____5
+ * |\ |\ |
+ * | \ | \ |
+ * | \ | \ |
+ * |______\|___\|
+ * 0 2 4
+ */
+ insideShaftVertexCount = 4 * toothCount + 2;
+ insideShaftStripCount[0] = insideShaftVertexCount;
+
+ TriangleStripArray insideShaft
+ = new TriangleStripArray(insideShaftVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ insideShaftStripCount);
+ xShaft3 = shaftRadius * (float)Math.cos(gearStartAngle);
+ yShaft3 = shaftRadius * (float)Math.sin(gearStartAngle);
+
+ if (normalDirection == OutwardNormals) {
+ surfaceNormal.set(1.0f, 0.0f, 0.0f);
+ firstIndex = 1;
+ secondIndex = 0;
+ } else {
+ surfaceNormal.set(-1.0f, 0.0f, 0.0f);
+ firstIndex = 0;
+ secondIndex = 1;
+ }
+
+ // Coordinate labeled 0 in the strip
+ coordinate.set(shaftRadius, 0.0f, frontZ);
+ insideShaft.setCoordinate(firstIndex, coordinate);
+ insideShaft.setNormal(firstIndex, surfaceNormal);
+
+ // Coordinate labeled 1 in the strip
+ coordinate.set(shaftRadius, 0.0f, rearZ);
+ insideShaft.setCoordinate(secondIndex, coordinate);
+ insideShaft.setNormal(secondIndex, surfaceNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+
+ toothStartAngle = circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ if (normalDirection == OutwardNormals)
+ surfaceNormal.set(xDirection, yDirection, 0.0f);
+ else
+ surfaceNormal.set(-xDirection, -yDirection, 0.0f);
+
+ // Coordinate labeled 2 in the strip
+ coordinate.set(xShaft3, yShaft3, frontZ);
+ insideShaft.setCoordinate(index + firstIndex, coordinate);
+ insideShaft.setNormal(index + firstIndex, surfaceNormal);
+
+ // Coordinate labeled 3 in the strip
+ coordinate.set(xShaft3, yShaft3, rearZ);
+ insideShaft.setCoordinate(index + secondIndex, coordinate);
+ insideShaft.setNormal(index + secondIndex, surfaceNormal);
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ if (normalDirection == OutwardNormals)
+ surfaceNormal.set(xDirection, yDirection, 0.0f);
+ else
+ surfaceNormal.set(-xDirection, -yDirection, 0.0f);
+
+ // Coordinate labeled 4 in the strip
+ coordinate.set(xShaft4, yShaft4, frontZ);
+ insideShaft.setCoordinate(index + 2 + firstIndex, coordinate);
+ insideShaft.setNormal(index + 2 + firstIndex, surfaceNormal);
+
+ // Coordinate labeled 5 in the strip
+ coordinate.set(xShaft4, yShaft4, rearZ);
+ insideShaft.setCoordinate(index + 2 + secondIndex, coordinate);
+ insideShaft.setNormal(index + 2 + secondIndex, surfaceNormal);
+
+ }
+ newShape = new Shape3D(insideShaft, look);
+ this.addChild(newShape);
+ }
+
+ public float getToothTopCenterAngle() {
+ return toothTopCenterAngle;
+ }
+
+ public float getValleyCenterAngle() {
+ return valleyCenterAngle;
+ }
+
+ public float getCircularPitchAngle() {
+ return circularPitchAngle;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/gears/GearBox.java b/src/classes/org/jdesktop/j3d/examples/gears/GearBox.java
new file mode 100644
index 0000000..a3b0a84
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/gears/GearBox.java
@@ -0,0 +1,356 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.gears;
+
+import com.sun.j3d.utils.behaviors.mouse.*;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.lang.Integer;
+import com.sun.j3d.utils.behaviors.vp.*;
+
+public class GearBox extends Applet {
+
+ static final int defaultToothCount = 48;
+ private int toothCount;
+ private SimpleUniverse u = null;
+
+ public BranchGroup createGearBox(int toothCount) {
+ Transform3D tempTransform = new Transform3D();
+
+ // Create the root of the branch graph
+ BranchGroup branchRoot = createBranchEnvironment();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ branchRoot.addChild(objScale);
+
+ // Create an Appearance.
+ Appearance look = new Appearance();
+ Color3f objColor = new Color3f(0.5f, 0.5f, 0.6f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ look.setMaterial(new Material(objColor, black,
+ objColor, white, 100.0f));
+
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup gearboxTrans = new TransformGroup();
+ gearboxTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ gearboxTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(gearboxTrans);
+
+ // Create a bounds for the mouse behavior methods
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Define the shaft base information
+ int shaftCount = 4;
+ int secondsPerRevolution = 8000;
+
+ // Create the Shaft(s)
+ Shaft shafts[] = new Shaft[shaftCount];
+ TransformGroup shaftTGs[] = new TransformGroup[shaftCount];
+ Alpha shaftAlphas[] = new Alpha[shaftCount];
+ RotationInterpolator shaftRotors[]
+ = new RotationInterpolator[shaftCount];
+ Transform3D shaftAxis[] = new Transform3D[shaftCount];
+
+ // Note: the following arrays we're incorporated to make changing
+ // the gearbox easier.
+ float shaftRatios[] = new float[shaftCount];
+ shaftRatios[0] = 1.0f;
+ shaftRatios[1] = 0.5f;
+ shaftRatios[2] = 0.75f;
+ shaftRatios[3] = 5.0f;
+
+ float shaftRadius[] = new float[shaftCount];
+ shaftRadius[0] = 0.2f;
+ shaftRadius[1] = 0.2f;
+ shaftRadius[2] = 0.2f;
+ shaftRadius[3] = 0.2f;
+
+ float shaftLength[] = new float[shaftCount];
+ shaftLength[0] = 1.8f;
+ shaftLength[1] = 0.8f;
+ shaftLength[2] = 0.8f;
+ shaftLength[3] = 0.8f;
+
+ float shaftDirection[] = new float[shaftCount];
+ shaftDirection[0] = 1.0f;
+ shaftDirection[1] = -1.0f;
+ shaftDirection[2] = 1.0f;
+ shaftDirection[3] = -1.0f;
+
+ Vector3d shaftPlacement[] = new Vector3d[shaftCount];
+ shaftPlacement[0] = new Vector3d(-0.75, -0.9, 0.0);
+ shaftPlacement[1] = new Vector3d(0.75, -0.9, 0.0);
+ shaftPlacement[2] = new Vector3d(0.75, 0.35, 0.0);
+ shaftPlacement[3] = new Vector3d(-0.75, 0.60, -0.7);
+
+ // Create the shafts.
+ for(int i = 0; i < shaftCount; i++) {
+ shafts[i] = new Shaft(shaftRadius[i], shaftLength[i], 25, look);
+ }
+
+ // Create a transform group node for placing each shaft
+ for(int i = 0; i < shaftCount; i++) {
+ shaftTGs[i] = new TransformGroup();
+ gearboxTrans.addChild(shaftTGs[i]);
+ shaftTGs[i].getTransform(tempTransform);
+ tempTransform.setTranslation(shaftPlacement[i]);
+ shaftTGs[i].setTransform(tempTransform);
+ shaftTGs[i].addChild(shafts[i]);
+ }
+
+ // Add rotation interpolators to rotate the shaft in the appropriate
+ // direction and at the appropriate rate
+ for(int i = 0; i < shaftCount; i++) {
+ shaftAlphas[i] = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0,
+ (long)(secondsPerRevolution
+ * shaftRatios[i]),
+ 0, 0,
+ 0, 0, 0);
+ shaftAxis[i] = new Transform3D();
+ shaftAxis[i].rotX(Math.PI/2.0);
+ shaftRotors[i]
+ = new RotationInterpolator(shaftAlphas[i], shafts[i],
+ shaftAxis[i],
+ 0.0f,
+ shaftDirection[i] *
+ (float) Math.PI * 2.0f);
+ shaftRotors[i].setSchedulingBounds(bounds);
+ shaftTGs[i].addChild(shaftRotors[i]);
+ }
+
+ // Define the gear base information. Again, these arrays exist to
+ // make the process of changing the GearBox via an editor faster
+ int gearCount = 5;
+ float valleyToCircularPitchRatio = .15f;
+ float pitchCircleRadius = 1.0f;
+ float addendum = 0.05f;
+ float dedendum = 0.05f;
+ float gearThickness = 0.3f;
+ float toothTipThickness = 0.27f;
+
+ // Create an array of gears and their associated information
+ SpurGear gears[] = new SpurGear[gearCount];
+ TransformGroup gearTGs[] = new TransformGroup[gearCount];
+
+ int gearShaft[] = new int[gearCount];
+ gearShaft[0] = 0;
+ gearShaft[1] = 1;
+ gearShaft[2] = 2;
+ gearShaft[3] = 0;
+ gearShaft[4] = 3;
+
+ float ratio[] = new float[gearCount];
+ ratio[0] = 1.0f;
+ ratio[1] = 0.5f;
+ ratio[2] = 0.75f;
+ ratio[3] = 0.25f;
+ ratio[4] = 1.25f;
+
+ Vector3d placement[] = new Vector3d[gearCount];
+ placement[0] = new Vector3d(0.0, 0.0, 0.0);
+ placement[1] = new Vector3d(0.0, 0.0, 0.0);
+ placement[2] = new Vector3d(0.0, 0.0, 0.0);
+ placement[3] = new Vector3d(0.0, 0.0, -0.7);
+ placement[4] = new Vector3d(0.0, 0.0, 0.0);
+
+ // Create the gears.
+ for(int i = 0; i < gearCount; i++) {
+ gears[i]
+ = new SpurGearThinBody(((int)((float)toothCount * ratio[i])),
+ pitchCircleRadius * ratio[i],
+ shaftRadius[0],
+ addendum, dedendum,
+ gearThickness,
+ toothTipThickness,
+ valleyToCircularPitchRatio, look);
+ }
+
+ // Create a transform group node for arranging the gears on a shaft
+ // and attach the gear to its associated shaft
+ for(int i = 0; i < gearCount; i++) {
+ gearTGs[i] = new TransformGroup();
+ gearTGs[i].getTransform(tempTransform);
+ tempTransform.rotZ((shaftDirection[gearShaft[i]] == -1.0) ?
+ gears[i].getCircularPitchAngle()/-2.0f :
+ 0.0f);
+ tempTransform.setTranslation(placement[i]);
+ gearTGs[i].setTransform(tempTransform);
+ gearTGs[i].addChild(gears[i]);
+ shafts[gearShaft[i]].addChild(gearTGs[i]);
+ }
+
+ // Have Java 3D perform optimizations on this scene graph.
+ branchRoot.compile();
+
+ return branchRoot;
+ }
+
+ BranchGroup createBranchEnvironment(){
+ // Create the root of the branch graph
+ BranchGroup branchRoot = new BranchGroup();
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ branchRoot.addChild(bgNode);
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ branchRoot.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ branchRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ branchRoot.addChild(light2);
+
+ return branchRoot;
+ }
+
+ public GearBox() {
+ this(defaultToothCount);
+ }
+
+ public GearBox(int toothCount) {
+ this.toothCount = toothCount;
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create the gearbox and attach it to the virtual universe
+ BranchGroup scene = createGearBox(toothCount);
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ // add orbit behavior to the ViewingPlatform
+ OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows GearBox to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ int value;
+
+ if (args.length > 1) {
+ System.out.println("Usage: java GearBox #teeth (LCD 4)");
+ System.exit(0);
+ } else if (args.length == 0) {
+ new MainFrame(new GearBox(), 700, 700);
+ } else
+ {
+ try{
+ value = Integer.parseInt(args[0]);
+ } catch (NumberFormatException e) {
+ System.out.println("Illegal integer specified");
+ System.out.println("Usage: java GearBox #teeth (LCD 4)");
+ value = 0;
+ System.exit(0);
+ }
+ if (value <= 0 | (value % 4) != 0) {
+ System.out.println("Integer not a positive multiple of 4");
+ System.out.println("Usage: java GearBox #teeth (LCD 4)");
+ System.exit(0);
+ }
+ new MainFrame(new GearBox(value), 700, 700);
+ }
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/gears/GearTest.java b/src/classes/org/jdesktop/j3d/examples/gears/GearTest.java
new file mode 100644
index 0000000..29ecca9
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/gears/GearTest.java
@@ -0,0 +1,208 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.gears;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class GearTest extends Applet {
+
+ static final int defaultToothCount = 24;
+
+ private int toothCount;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(int toothCount) {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objScale.addChild(bgNode);
+
+ // Set up the global lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
+ Color3f light2Color = new Color3f(0.3f, 0.3f, 0.4f);
+ Vector3f light2Direction = new Vector3f(-6.0f, -2.0f, -1.0f);
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ objScale.addChild(ambientLightNode);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ objScale.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ objScale.addChild(light2);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(objTrans);
+
+ // Create an Appearance.
+ Appearance look = new Appearance();
+ Color3f objColor = new Color3f(0.5f, 0.5f, 0.6f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ look.setMaterial(new Material(objColor, black, objColor, white, 100.0f));
+
+ // Create a gear, add it to the scene graph.
+ // SpurGear gear = new SpurGear(toothCount, 1.0f, 0.2f,
+ SpurGear gear = new SpurGearThinBody(toothCount, 1.0f, 0.2f,
+ 0.05f, 0.05f, 0.3f, 0.28f, look);
+ objTrans.addChild(gear);
+
+ // Create a new Behavior object that will rotate the object and
+ // add it into the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 8000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public GearTest() {
+ this(defaultToothCount);
+ }
+
+ public GearTest(int toothCount) {
+ this.toothCount = toothCount;
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph(toothCount);
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows GearTest to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ int value;
+
+ if (args.length > 1) {
+ System.out.println("Usage: java GearTest [#teeth]");
+ System.exit(0);
+ } else if (args.length == 0) {
+ new MainFrame(new GearTest(), 700, 700);
+ } else
+ {
+ try {
+ value = Integer.parseInt(args[0]);
+ } catch (NumberFormatException e) {
+ System.out.println("Illegal integer specified");
+ System.out.println("Usage: java GearTest [#teeth]");
+ value = 0;
+ System.exit(0);
+ }
+ if (value <= 0) {
+ System.out.println("Integer must be positive (> 0)");
+ System.out.println("Usage: java GearBox [#teeth]");
+ System.exit(0);
+ }
+ new MainFrame(new GearTest(value), 700, 700);
+ }
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/gears/Shaft.java b/src/classes/org/jdesktop/j3d/examples/gears/Shaft.java
new file mode 100644
index 0000000..b02bf9e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/gears/Shaft.java
@@ -0,0 +1,198 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.gears;
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Shaft extends javax.media.j3d.TransformGroup {
+
+ /**
+ * Construct a Shaft;
+ * @return a new shaft that with the specified radius centered about
+ * the origin an laying in the XY plane and of a specified length
+ * extending in the Z dimension
+ * @param radius radius of shaft
+ * @param length shaft length shaft extends from -length/2 to length/2 in
+ * the Z dimension
+ * @param segmentCount number of segments for the shaft face
+ * @param look the Appearance to associate with this shaft
+ */
+ public Shaft(float radius, float length, int segmentCount,
+ Appearance look) {
+ // The direction of the ray from the shaft's center
+ float xDirection, yDirection;
+ float xShaft, yShaft;
+
+ // The z coordinates for the shaft's faces (never change)
+ float frontZ = -0.5f * length;
+ float rearZ = 0.5f * length;
+
+ int shaftFaceVertexCount; // #(vertices) per shaft face
+ int shaftFaceTotalVertexCount; // total #(vertices) in all teeth
+ int shaftFaceStripCount[] = new int[1]; // per shaft vertex count
+ int shaftVertexCount; // #(vertices) for shaft
+ int shaftStripCount[] = new int[1]; // #(vertices) in strip/strip
+
+ // Front and rear facing normals for the shaft's faces
+ Vector3f frontNormal = new Vector3f(0.0f, 0.0f, -1.0f);
+ Vector3f rearNormal = new Vector3f(0.0f, 0.0f, 1.0f);
+ // Outward facing normal
+ Vector3f outNormal = new Vector3f(1.0f, 0.0f, 0.0f);
+
+ // Temporary variables for storing coordinates and vectors
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+ Shape3D newShape;
+
+ // The angle subtended by a single segment
+ double segmentAngle = 2.0 * Math.PI/segmentCount;
+ double tempAngle;
+
+ // Allow this object to spin. etc.
+ this.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+
+ /* for the forward facing fan:
+ * ___3___
+ * - | -
+ * / | \
+ * 4/\ | /\2
+ * / \ | / \
+ * / \ | / \
+ * : \ | / :
+ * |--------------- *----------------|
+ * 5 0 1
+ *
+ * for backward facing fan exchange 1 with 5; 2 with 4, etc.
+ */
+
+ // Construct the shaft's front and rear face
+ shaftFaceVertexCount = segmentCount + 2;
+ shaftFaceStripCount[0] = shaftFaceVertexCount;
+
+ TriangleFanArray frontShaftFace
+ = new TriangleFanArray(shaftFaceVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ shaftFaceStripCount);
+
+ TriangleFanArray rearShaftFace
+ = new TriangleFanArray(shaftFaceVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ shaftFaceStripCount);
+
+ coordinate.set(0.0f, 0.0f, frontZ);
+ frontShaftFace.setCoordinate(0, coordinate);
+ frontShaftFace.setNormal(0, frontNormal);
+
+ coordinate.set(0.0f, 0.0f, rearZ);
+ rearShaftFace.setCoordinate(0, coordinate);
+ rearShaftFace.setNormal(0, rearNormal);
+
+ for(int index = 1; index < segmentCount+2; index++) {
+
+ tempAngle = segmentAngle * -(double)index;
+ coordinate.set(radius * (float)Math.cos(tempAngle),
+ radius * (float)Math.sin(tempAngle),
+ frontZ);
+ frontShaftFace.setCoordinate(index, coordinate);
+ frontShaftFace.setNormal(index, frontNormal);
+
+ tempAngle = -tempAngle;
+ coordinate.set(radius * (float)Math.cos(tempAngle),
+ radius * (float)Math.sin(tempAngle),
+ rearZ);
+ rearShaftFace.setCoordinate(index, coordinate);
+ rearShaftFace.setNormal(index, rearNormal);
+ }
+ newShape = new Shape3D(frontShaftFace, look);
+ this.addChild(newShape);
+ newShape = new Shape3D(rearShaftFace, look);
+ this.addChild(newShape);
+
+ // Construct shaft's outer skin (the cylinder body)
+ shaftVertexCount = 2 * segmentCount + 2;
+ shaftStripCount[0] = shaftVertexCount;
+
+ TriangleStripArray shaft
+ = new TriangleStripArray(shaftVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ shaftStripCount);
+
+ outNormal.set(1.0f, 0.0f, 0.0f);
+
+ coordinate.set(radius, 0.0f, rearZ);
+ shaft.setCoordinate(0, coordinate);
+ shaft.setNormal(0, outNormal);
+
+ coordinate.set(radius, 0.0f, frontZ);
+ shaft.setCoordinate(1, coordinate);
+ shaft.setNormal(1, outNormal);
+
+ for(int count = 0; count < segmentCount; count++) {
+ int index = 2 + count * 2;
+
+ tempAngle = segmentAngle * (double)(count + 1);
+ xDirection = (float)Math.cos(tempAngle);
+ yDirection = (float)Math.sin(tempAngle);
+ xShaft = radius * xDirection;
+ yShaft = radius * yDirection;
+ outNormal.set(xDirection, yDirection, 0.0f);
+
+ coordinate.set(xShaft, yShaft, rearZ);
+ shaft.setCoordinate(index, coordinate);
+ shaft.setNormal(index, outNormal);
+
+ coordinate.set(xShaft, yShaft, frontZ);
+ shaft.setCoordinate(index + 1, coordinate);
+ shaft.setNormal(index + 1, outNormal);
+ }
+ newShape = new Shape3D(shaft, look);
+ this.addChild(newShape);
+ }
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/gears/SpurGear.java b/src/classes/org/jdesktop/j3d/examples/gears/SpurGear.java
new file mode 100644
index 0000000..525a661
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/gears/SpurGear.java
@@ -0,0 +1,558 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.gears;
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class SpurGear extends Gear {
+
+ float toothTopAngleIncrement;
+ float toothDeclineAngleIncrement;
+
+ float rootRadius;
+ float outsideRadius;
+
+ //The angle subtended by the ascending or descending portion of a tooth
+ float circularToothEdgeAngle;
+ // The angle subtended by a flat (either a tooth top or a valley
+ // between teeth
+ float circularToothFlatAngle;
+
+ /**
+ * internal constructor for SpurGear, used by subclasses to establish
+ * SpurGear's required state
+ * @return a new spur gear that contains sufficient information to
+ * continue building
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ */
+ SpurGear(int toothCount, float pitchCircleRadius,
+ float addendum, float dedendum, float toothToValleyAngleRatio) {
+
+ super(toothCount);
+
+ // The angle about Z subtended by one tooth and its associated valley
+ circularPitchAngle = (float)(2.0 * Math.PI / (double)toothCount);
+
+ // The angle subtended by a flat (either a tooth top or a valley
+ // between teeth
+ circularToothFlatAngle = circularPitchAngle * toothToValleyAngleRatio;
+
+ //The angle subtended by the ascending or descending portion of a tooth
+ circularToothEdgeAngle = circularPitchAngle/2.0f -
+ circularToothFlatAngle;
+
+ // Increment angles
+ toothTopAngleIncrement = circularToothEdgeAngle;
+ toothDeclineAngleIncrement
+ = toothTopAngleIncrement + circularToothFlatAngle;
+ toothValleyAngleIncrement
+ = toothDeclineAngleIncrement + circularToothEdgeAngle;
+
+ // Differential angles for offsetting to the center of tooth's top
+ // and valley
+ toothTopCenterAngle
+ = toothTopAngleIncrement + circularToothFlatAngle/2.0f;
+ valleyCenterAngle
+ = toothValleyAngleIncrement + circularToothFlatAngle/2.0f;
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ gearStartAngle = -1.0 * toothTopCenterAngle;
+
+ // The radial distance to the root and top of the teeth, respectively
+ rootRadius = pitchCircleRadius - dedendum;
+ outsideRadius = pitchCircleRadius + addendum;
+
+ // Allow this object to spin. etc.
+ this.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, gearThickness, 0.25f, null);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param look the gear's appearance
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, gearThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param look the gear's appearance
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ float toothTipThickness, Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, toothTipThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ * @param look the gear's appearance object
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ float toothTipThickness, float toothToValleyAngleRatio,
+ Appearance look) {
+
+ this(toothCount, pitchCircleRadius, addendum, dedendum,
+ toothToValleyAngleRatio);
+
+ // Generate the gear's body disks
+ addBodyDisks(shaftRadius, rootRadius, gearThickness, look);
+
+ // Generate the gear's interior shaft
+ addCylinderSkins(shaftRadius, gearThickness, InwardNormals, look);
+
+ // Generate the gear's teeth
+ addTeeth(pitchCircleRadius, rootRadius,
+ outsideRadius, gearThickness, toothTipThickness,
+ toothToValleyAngleRatio, look);
+ }
+
+ /**
+ * Construct a SpurGear's teeth by adding the teeth shape nodes
+ * @param pitchCircleRadius radius at center of teeth
+ * @param rootRadius distance from pitch circle to top of teeth
+ * @param outsideRadius distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ * @param look the gear's appearance object
+ */
+ void addTeeth(float pitchCircleRadius, float rootRadius,
+ float outsideRadius, float gearThickness,
+ float toothTipThickness, float toothToValleyAngleRatio,
+ Appearance look) {
+ int index;
+ Shape3D newShape;
+
+ // Temporaries that store start angle for each portion of tooth facet
+ double toothStartAngle, toothTopStartAngle,
+ toothDeclineStartAngle, toothValleyStartAngle,
+ nextToothStartAngle;
+
+ // The x and y coordinates at each point of a facet and at each
+ // point on the gear: at the shaft, the root of the teeth, and
+ // the outer point of the teeth
+ float xRoot0, yRoot0;
+ float xOuter1, yOuter1;
+ float xOuter2, yOuter2;
+ float xRoot3, yRoot3;
+ float xRoot4, yRoot4;
+
+ // The z coordinates for the gear
+ final float frontZ = -0.5f * gearThickness;
+ final float rearZ = 0.5f * gearThickness;
+
+ // The z coordinates for the tooth tip of the gear
+ final float toothTipFrontZ = -0.5f * toothTipThickness;
+ final float toothTipRearZ = 0.5f * toothTipThickness;
+
+ int toothFacetVertexCount; // #(vertices) per tooth facet
+ int toothFacetCount; // #(facets) per tooth
+ int toothFaceTotalVertexCount; // #(vertices) in all teeth
+ int toothFaceStripCount[] = new int[toothCount];
+ // per tooth vertex count
+ int topVertexCount; // #(vertices) for teeth tops
+ int topStripCount[] = new int[1]; // #(vertices) in strip/strip
+
+ // Front and rear facing normals for the teeth faces
+ Vector3f frontToothNormal = new Vector3f(0.0f, 0.0f, -1.0f);
+ Vector3f rearToothNormal = new Vector3f(0.0f, 0.0f, 1.0f);
+
+ // Normals for teeth tops up incline, tooth top, and down incline
+ Vector3f leftNormal = new Vector3f(-1.0f, 0.0f, 0.0f);
+ Vector3f rightNormal = new Vector3f(1.0f, 0.0f, 0.0f);
+ Vector3f outNormal = new Vector3f(1.0f, 0.0f, 0.0f);
+ Vector3f inNormal = new Vector3f(-1.0f, 0.0f, 0.0f);
+
+ // Temporary variables for storing coordinates and vectors
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate1 = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate2 = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate3 = new Point3f(0.0f, 0.0f, 0.0f);
+ Vector3f tempVector1 = new Vector3f(0.0f, 0.0f, 0.0f);
+ Vector3f tempVector2 = new Vector3f(0.0f, 0.0f, 0.0f);
+
+ /* Construct the gear's front facing teeth facets
+ * 0______2
+ * / /\
+ * / / \
+ * / / \
+ * //___________\
+ * 1 3
+ */
+ toothFacetVertexCount = 4;
+ toothFaceTotalVertexCount = toothFacetVertexCount * toothCount;
+ for(int i = 0; i < toothCount; i++)
+ toothFaceStripCount[i] = toothFacetVertexCount;
+
+ TriangleStripArray frontGearTeeth
+ = new TriangleStripArray(toothFaceTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ toothFaceStripCount);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = count * toothFacetVertexCount;
+
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+
+ tempCoordinate1.set(xRoot0, yRoot0, frontZ);
+ tempCoordinate2.set(xRoot3, yRoot3, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector2.sub(tempCoordinate2, tempCoordinate1);
+
+ frontToothNormal.cross(tempVector1, tempVector2);
+ frontToothNormal.normalize();
+
+ coordinate.set(xOuter1, yOuter1, toothTipFrontZ);
+ frontGearTeeth.setCoordinate(index, coordinate);
+ frontGearTeeth.setNormal(index, frontToothNormal);
+
+ coordinate.set(xRoot0, yRoot0, frontZ);
+ frontGearTeeth.setCoordinate(index + 1, coordinate);
+ frontGearTeeth.setNormal(index + 1, frontToothNormal);
+
+ coordinate.set(xOuter2, yOuter2, toothTipFrontZ);
+ frontGearTeeth.setCoordinate(index + 2, coordinate);
+ frontGearTeeth.setNormal(index + 2, frontToothNormal);
+
+ coordinate.set(xRoot3, yRoot3, frontZ);
+ frontGearTeeth.setCoordinate(index + 3, coordinate);
+ frontGearTeeth.setNormal(index + 3, frontToothNormal);
+ }
+ newShape = new Shape3D(frontGearTeeth, look);
+ this.addChild(newShape);
+
+ /* Construct the gear's rear facing teeth facets (Using Quads)
+ * 1______2
+ * / \
+ * / \
+ * / \
+ * /____________\
+ * 0 3
+ */
+ toothFacetVertexCount = 4;
+ toothFaceTotalVertexCount = toothFacetVertexCount * toothCount;
+
+ QuadArray rearGearTeeth
+ = new QuadArray(toothCount * toothFacetVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS);
+
+ for(int count = 0; count < toothCount; count++) {
+
+ index = count * toothFacetVertexCount;
+ toothStartAngle =
+ gearStartAngle + circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle = toothStartAngle + toothValleyAngleIncrement;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+
+ tempCoordinate1.set(xRoot0, yRoot0, rearZ);
+ tempCoordinate2.set(xRoot3, yRoot3, rearZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipRearZ);
+ tempVector2.sub(tempCoordinate2, tempCoordinate1);
+ rearToothNormal.cross(tempVector2, tempVector1);
+ rearToothNormal.normalize();
+
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ rearGearTeeth.setCoordinate(index, coordinate);
+ rearGearTeeth.setNormal(index, rearToothNormal);
+
+ coordinate.set(xOuter1, yOuter1, toothTipRearZ);
+ rearGearTeeth.setCoordinate(index + 1, coordinate);
+ rearGearTeeth.setNormal(index + 1, rearToothNormal);
+
+ coordinate.set(xOuter2, yOuter2, toothTipRearZ);
+ rearGearTeeth.setCoordinate(index + 2, coordinate);
+ rearGearTeeth.setNormal(index + 2, rearToothNormal);
+
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ rearGearTeeth.setCoordinate(index + 3, coordinate);
+ rearGearTeeth.setNormal(index + 3, rearToothNormal);
+
+ }
+ newShape = new Shape3D(rearGearTeeth, look);
+ this.addChild(newShape);
+
+ /*
+ * Construct the gear's top teeth faces (As seen from above)
+ * Root0 Outer1 Outer2 Root3 Root4 (RearZ)
+ * 0_______3 2_______5 4_______7 6_______9
+ * |0 3| |4 7| |8 11| |12 15|
+ * | | | | | | | |
+ * | | | | | | | |
+ * |1_____2| |5_____6| |9____10| |13___14|
+ * 1 2 3 4 5 6 7 8
+ * Root0 Outer1 Outer2 Root3 Root4 (FrontZ)
+ *
+ * Quad 0123 uses a left normal
+ * Quad 2345 uses an out normal
+ * Quad 4567 uses a right normal
+ * Quad 6789 uses an out normal
+ */
+ topVertexCount = 8 * toothCount + 2;
+ topStripCount[0] = topVertexCount;
+
+ toothFacetVertexCount = 4;
+ toothFacetCount = 4;
+
+ QuadArray topGearTeeth
+ = new QuadArray(toothCount * toothFacetVertexCount
+ * toothFacetCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = count * toothFacetCount * toothFacetVertexCount;
+ toothStartAngle = gearStartAngle +
+ circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+ xRoot4 = rootRadius * (float)Math.cos(nextToothStartAngle);
+ yRoot4 = rootRadius * (float)Math.sin(nextToothStartAngle);
+
+ // Compute normal for quad 1
+ tempCoordinate1.set(xRoot0, yRoot0, frontZ);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ leftNormal.cross(frontNormal, tempVector1);
+ leftNormal.normalize();
+
+ // Coordinate labeled 0 in the quad
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ topGearTeeth.setCoordinate(index, coordinate);
+ topGearTeeth.setNormal(index, leftNormal);
+
+ // Coordinate labeled 1 in the quad
+ coordinate.set(tempCoordinate1);
+ topGearTeeth.setCoordinate(index + 1, coordinate);
+ topGearTeeth.setNormal(index + 1, leftNormal);
+
+ // Coordinate labeled 2 in the quad
+ topGearTeeth.setCoordinate(index + 2, tempCoordinate2);
+ topGearTeeth.setNormal(index + 2, leftNormal);
+ topGearTeeth.setCoordinate(index + 5, tempCoordinate2);
+
+ // Coordinate labeled 3 in the quad
+ coordinate.set(xOuter1, yOuter1, toothTipRearZ);
+ topGearTeeth.setCoordinate(index + 3, coordinate);
+ topGearTeeth.setNormal(index + 3, leftNormal);
+ topGearTeeth.setCoordinate(index + 4, coordinate);
+
+ // Compute normal for quad 2
+ tempCoordinate1.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempCoordinate2.set(xOuter2, yOuter2, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ outNormal.cross(frontNormal, tempVector1);
+ outNormal.normalize();
+
+ topGearTeeth.setNormal(index + 4, outNormal);
+ topGearTeeth.setNormal(index + 5, outNormal);
+
+ // Coordinate labeled 4 in the quad
+ topGearTeeth.setCoordinate(index + 6, tempCoordinate2);
+ topGearTeeth.setNormal(index + 6, outNormal);
+ topGearTeeth.setCoordinate(index + 9, tempCoordinate2);
+
+ // Coordinate labeled 5 in the quad
+ coordinate.set(xOuter2, yOuter2, toothTipRearZ);
+ topGearTeeth.setCoordinate(index + 7, coordinate);
+ topGearTeeth.setNormal(index + 7, outNormal);
+ topGearTeeth.setCoordinate(index + 8, coordinate);
+
+ // Compute normal for quad 3
+ tempCoordinate1.set(xOuter2, yOuter2, toothTipFrontZ);
+ tempCoordinate2.set(xRoot3, yRoot3, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ rightNormal.cross(frontNormal, tempVector1);
+ rightNormal.normalize();
+
+ topGearTeeth.setNormal(index + 8, rightNormal);
+ topGearTeeth.setNormal(index + 9, rightNormal);
+
+ // Coordinate labeled 7 in the quad
+ topGearTeeth.setCoordinate(index + 10, tempCoordinate2);
+ topGearTeeth.setNormal(index + 10, rightNormal);
+ topGearTeeth.setCoordinate(index + 13, tempCoordinate2);
+
+ // Coordinate labeled 6 in the quad
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ topGearTeeth.setCoordinate(index + 11, coordinate);
+ topGearTeeth.setNormal(index + 11, rightNormal);
+ topGearTeeth.setCoordinate(index + 12, coordinate);
+
+ // Compute normal for quad 4
+ tempCoordinate1.set(xRoot3, yRoot3, frontZ);
+ tempCoordinate2.set(xRoot4, yRoot4, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ outNormal.cross(frontNormal, tempVector1);
+ outNormal.normalize();
+
+ topGearTeeth.setNormal(index + 12, outNormal);
+ topGearTeeth.setNormal(index + 13, outNormal);
+
+ // Coordinate labeled 9 in the quad
+ topGearTeeth.setCoordinate(index + 14, tempCoordinate2);
+ topGearTeeth.setNormal(index + 14, outNormal);
+
+ // Coordinate labeled 8 in the quad
+ coordinate.set(xRoot4, yRoot4, rearZ);
+ topGearTeeth.setCoordinate(index + 15, coordinate);
+ topGearTeeth.setNormal(index + 15, outNormal);
+
+ // Prepare for the loop by computing the new normal
+ toothTopStartAngle
+ = nextToothStartAngle + toothTopAngleIncrement;
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+
+ tempCoordinate1.set(xRoot4, yRoot4, toothTipFrontZ);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ leftNormal.cross(frontNormal, tempVector1);
+ leftNormal.normalize();
+ }
+ newShape = new Shape3D(topGearTeeth, look);
+ this.addChild(newShape);
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java b/src/classes/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java
new file mode 100644
index 0000000..cd2f4ab
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java
@@ -0,0 +1,187 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.gears;
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class SpurGearThinBody extends SpurGear {
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness) {
+ this(toothCount, pitchCircleRadius, shaftRadius,
+ addendum, dedendum, gearThickness, gearThickness, 0.25f, null);
+ }
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param look the gear's appearance
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness,
+ Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius,
+ addendum, dedendum, gearThickness, gearThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param look the gear's appearance
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness, float toothTipThickness,
+ Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum,
+ dedendum, gearThickness, toothTipThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyRatio ratio of tooth valley to circular pitch
+ * (must be <= .25)
+ * @param look the gear's appearance object
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness, float toothTipThickness,
+ float toothToValleyAngleRatio, Appearance look) {
+
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum,
+ dedendum, gearThickness, toothTipThickness, 0.25f, look,
+ 0.6f * gearThickness, 0.75f * (pitchCircleRadius - shaftRadius));
+ }
+
+ /**
+ * Construct a SpurGearThinBody;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyRatio ratio of tooth valley to circular pitch
+ * (must be <= .25)
+ * @param look the gear's appearance object
+ * @param bodyThickness the thickness of the gear body
+ * @param crossSectionWidth the width of the depressed portion of the
+ * gear's body
+ */
+ public SpurGearThinBody(int toothCount, float pitchCircleRadius,
+ float shaftRadius, float addendum, float dedendum,
+ float gearThickness, float toothTipThickness,
+ float toothToValleyAngleRatio, Appearance look,
+ float bodyThickness, float crossSectionWidth) {
+
+ super(toothCount, pitchCircleRadius, addendum, dedendum,
+ toothToValleyAngleRatio);
+
+ float diskCrossSectionWidth =
+ (rootRadius - shaftRadius - crossSectionWidth)/ 2.0f;
+ float outerShaftRadius = shaftRadius + diskCrossSectionWidth;
+ float innerToothRadius = rootRadius - diskCrossSectionWidth;
+
+ // Generate the gear's body disks, first by the shaft, then in
+ // the body and, lastly, by the teeth
+ addBodyDisks(shaftRadius, outerShaftRadius,
+ gearThickness, look);
+ addBodyDisks(innerToothRadius, rootRadius,
+ gearThickness, look);
+ addBodyDisks(outerShaftRadius, innerToothRadius,
+ bodyThickness, look);
+
+ // Generate the gear's "shaft" equivalents the two at the teeth
+ // and the two at the shaft
+ addCylinderSkins(innerToothRadius, gearThickness, InwardNormals, look);
+ addCylinderSkins(outerShaftRadius, gearThickness, OutwardNormals, look);
+
+ // Generate the gear's interior shaft
+ addCylinderSkins(shaftRadius, gearThickness, InwardNormals, look);
+
+ // Generate the gear's teeth
+ addTeeth(pitchCircleRadius, rootRadius,
+ outsideRadius, gearThickness, toothTipThickness,
+ toothToValleyAngleRatio, look);
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java
new file mode 100644
index 0000000..f53c1ae
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java
@@ -0,0 +1,519 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_by_ref;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+import java.nio.*;
+
+public class GeometryByReferenceNIOBuffer extends JApplet implements ActionListener,
+GeometryUpdater {
+
+ RenderingAttributes ra;
+ ColoringAttributes ca;
+ Material mat;
+ Appearance app;
+ JComboBox geomType;
+ JComboBox vertexType;
+ JComboBox colorType;
+ JCheckBox transparency;
+ JComboBox updates;
+ Shape3D shape;
+ TransparencyAttributes transp;
+ int updateIndex = 0;
+ int colorCount = 0, vertexCount = 0;
+ int vertexIndex = 0, colorIndex = 0;
+
+ GeometryArray tetraRegular, tetraStrip, tetraIndexed, tetraIndexedStrip;
+ GeometryArray[] geoArrays = new GeometryArray[4];
+
+ private static final float sqrt3 = (float) Math.sqrt(3.0);
+ private static final float sqrt3_3 = sqrt3 / 3.0f;
+ private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;
+
+ private static final float ycenter = 0.5f * sqrt24_3;
+ private static final float zcenter = -sqrt3_3;
+
+ private static final Point3f p1 =
+ new Point3f(-1.0f, -ycenter, -zcenter);
+ private static final Point3f p2 =
+ new Point3f(1.0f, -ycenter, -zcenter);
+ private static final Point3f p3 =
+ new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
+ private static final Point3f p4 =
+ new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);
+
+ private static final float[] floatVerts = {
+ p1.x, p1.y, p1.z, // front face
+ p2.x, p2.y, p2.z,
+ p4.x, p4.y, p4.z,
+
+ p1.x, p1.y, p1.z,// left, back face
+ p4.x, p4.y, p4.z,
+ p3.x, p3.y, p3.z,
+
+ p2.x, p2.y, p2.z,// right, back face
+ p3.x, p3.y, p3.z,
+ p4.x, p4.y, p4.z,
+
+ p1.x, p1.y, p1.z,// bottom face
+ p3.x, p3.y, p3.z,
+ p2.x, p2.y, p2.z,
+ };
+
+ private static final Color3f c1 = new Color3f(0.6f, 0.0f, 0.0f);
+ private static final Color3f c2 = new Color3f(0.0f, 0.6f, 0.0f);
+ private static final Color3f c3 = new Color3f(0.0f, 0.6f, 0.6f);
+ private static final Color3f c4 = new Color3f(0.6f, 0.6f, 0.0f);
+
+
+
+ private static final float[] floatClrs = {
+ c1.x, c1.y, c1.z, // front face
+ c2.x, c2.y, c2.z,
+ c4.x, c4.y, c4.z,
+
+ c1.x, c1.y, c1.z,// left, back face
+ c4.x, c4.y, c4.z,
+ c3.x, c3.y, c3.z,
+
+ c2.x, c2.y, c2.z,// right, back face
+ c3.x, c3.y, c3.z,
+ c4.x, c4.y, c4.z,
+
+ c1.x, c1.y, c1.z,// bottom face
+ c3.x, c3.y, c3.z,
+ c2.x, c2.y, c2.z,
+ };
+
+ private static final float[] indexedFloatVerts = {
+ p1.x,p1.y,p1.z,
+ p2.x,p2.y,p2.z,
+ p3.x,p3.y,p3.z,
+ p4.x,p4.y,p4.z,
+
+ };
+
+
+ private static final float[] indexedFloatClrs = {
+ c1.x,c1.y,c1.z,
+ c2.x,c2.y,c2.z,
+ c3.x,c3.y,c3.z,
+ c4.x,c4.y,c4.z,
+ };
+
+ private static final int[] indices = {0,1,3,0,3,2,1,2,3,0,2,1};
+ private int[] stripVertexCounts = {3,3,3,3};
+
+ private SimpleUniverse u;
+
+ private J3DBuffer floatBufferCoord;
+ private J3DBuffer floatBufferColor;
+ private J3DBuffer indexedFloatBufferCoord;
+ private J3DBuffer indexedFloatBufferColor;
+
+ void createJ3DBuffers() {
+ int i;
+ ByteOrder order = ByteOrder.nativeOrder();
+
+ FloatBuffer coord = ByteBuffer.allocateDirect(36 * 4).order(order).asFloatBuffer();
+ coord.put(floatVerts, 0, 36);
+ floatBufferCoord = new J3DBuffer(coord);
+
+ FloatBuffer color = ByteBuffer.allocateDirect(36 * 4).order(order).asFloatBuffer();
+ color.put(floatClrs, 0, 36);
+ floatBufferColor = new J3DBuffer(color);
+
+ FloatBuffer indexedCoord = ByteBuffer.allocateDirect(12 * 4).order(order).asFloatBuffer();
+ indexedCoord.put(indexedFloatVerts, 0, 12);
+ indexedFloatBufferCoord = new J3DBuffer(indexedCoord);
+
+ FloatBuffer indexedColor = ByteBuffer.allocateDirect(12 * 4).order(order).asFloatBuffer();
+ indexedColor.put(indexedFloatClrs, 0, 12);
+ indexedFloatBufferColor = new J3DBuffer(indexedColor);
+ }
+
+ BranchGroup createSceneGraph() {
+ BranchGroup objRoot = new BranchGroup();
+
+ // Set up attributes to render lines
+ app = new Appearance();
+
+ transp = new TransparencyAttributes();
+ transp.setTransparency(0.5f);
+ transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
+ transp.setTransparencyMode(TransparencyAttributes.NONE);
+ app.setTransparencyAttributes(transp);
+
+ //create the direct nio buffer
+ createJ3DBuffers();
+
+ tetraRegular = createGeometry(1);
+ tetraStrip =createGeometry(2);
+ tetraIndexed = createGeometry(3);
+ tetraIndexedStrip = createGeometry(4);
+
+ geoArrays[0] = tetraRegular;
+ geoArrays[1] = tetraStrip;
+ geoArrays[2] = tetraIndexed;
+ geoArrays[3] = tetraIndexedStrip;
+
+ shape = new Shape3D(tetraRegular, app);
+ shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+ shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
+
+ Transform3D t = new Transform3D();
+ // move the object upwards
+ t.set(new Vector3f(0.0f, 0.3f, 0.0f));
+
+ // rotate the shape
+ Transform3D temp = new Transform3D();
+ temp.rotX(Math.PI/4.0d);
+ t.mul(temp);
+ temp.rotY(Math.PI/4.0d);
+ t.mul(temp);
+
+ // Shrink the object
+ t.setScale(0.6);
+
+ TransformGroup trans = new TransformGroup(t);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+
+ objRoot.addChild(trans);
+ trans.addChild(shape);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objRoot.addChild(aLgt);
+ objRoot.addChild(lgt1);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ JPanel createGeometryByReferencePanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Geometry Type"));
+
+ String values[] = {"Array", "Strip", "Indexed", "IndexedStrip"};
+ geomType = new JComboBox(values);
+ geomType.setLightWeightPopupEnabled(false);
+ geomType.addActionListener(this);
+ geomType.setSelectedIndex(0);
+ panel.add(new JLabel("Geometry Type"));
+ panel.add(geomType);
+
+ return panel;
+ }
+
+ JPanel createUpdatePanel() {
+
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Other Attributes"));
+
+ String updateComp[] = { "None","Geometry", "Color"};
+
+ transparency = new JCheckBox("EnableTransparency",
+ false);
+ transparency.addActionListener(this);
+ panel.add(transparency);
+
+
+ updates = new JComboBox(updateComp);
+ updates.setLightWeightPopupEnabled(false);
+ updates.addActionListener(this);
+ updates.setSelectedIndex(0);
+ panel.add(new JLabel("UpdateData"));
+ panel.add(updates);
+
+ return panel;
+ }
+
+
+
+ public GeometryByReferenceNIOBuffer() {
+ }
+
+ public void init() {
+ Container contentPane = getContentPane();
+
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ contentPane.add("Center", c);
+
+ BranchGroup scene = createSceneGraph();
+ // SimpleUniverse is a Convenience Utility class
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the viewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+ u.addBranchGraph(scene);
+
+ // add Orbit behavior to the ViewingPlatform
+ OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ // Create GUI
+ JPanel p = new JPanel();
+ BoxLayout boxlayout = new BoxLayout(p,
+ BoxLayout.Y_AXIS);
+ p.add(createGeometryByReferencePanel());
+ p.add(createUpdatePanel());
+ p.setLayout(boxlayout);
+
+ contentPane.add("South", p);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object target = e.getSource();
+ GeometryArray geo;
+ boolean setColor = false, setVertex = false;
+ if (target == geomType) {
+ geo = geoArrays[geomType.getSelectedIndex()];
+ // Set everything to null, and set it later ..
+ geo.setColorRefBuffer(null);
+ geo.setCoordRefBuffer(null);
+ shape.setGeometry(geoArrays[geomType.getSelectedIndex()]);
+
+ setColor = true;
+ setVertex= true;
+
+
+ }
+ else if (target == transparency) {
+ if (transparency.isSelected()) {
+ transp.setTransparencyMode(TransparencyAttributes.BLENDED);
+ }
+ else {
+ transp.setTransparencyMode(TransparencyAttributes.NONE);
+ }
+
+ }
+ else if (target == updates) {
+ updateIndex = updates.getSelectedIndex();
+ if (updateIndex == 1) {
+ System.out.println("Doing coordinate update");
+ ((GeometryArray)(shape.getGeometry())).updateData(this);
+ }
+ else if (updateIndex == 2) {
+ System.out.println("Doing color update");
+ ((GeometryArray)(shape.getGeometry())).updateData(this);
+ }
+
+ }
+
+ if (setVertex) {
+ geo = (GeometryArray) shape.getGeometry();
+ if (geo instanceof IndexedGeometryArray)
+ geo.setCoordRefBuffer(indexedFloatBufferCoord);
+ else
+ geo.setCoordRefBuffer(floatBufferCoord);
+
+ }
+ if (setColor) {
+ geo = (GeometryArray) shape.getGeometry();
+ if (geo instanceof IndexedGeometryArray)
+ geo.setColorRefBuffer(indexedFloatBufferColor);
+ else
+ geo.setColorRefBuffer(floatBufferColor);
+ }
+ }
+
+
+
+ public static void main(String[] args) {
+ Frame frame = new MainFrame(new GeometryByReferenceNIOBuffer(), 800, 800);
+ }
+
+ public GeometryArray createGeometry (int type) {
+ GeometryArray tetra = null;
+ if (type == 1) {
+ tetra =new TriangleArray(12,
+ TriangleArray.COORDINATES|
+ TriangleArray.COLOR_3|
+ TriangleArray.BY_REFERENCE|
+ TriangleArray.USE_NIO_BUFFER);
+
+ tetra.setCoordRefBuffer(floatBufferCoord);
+ tetra.setColorRefBuffer(floatBufferColor);
+
+ }
+ else if (type == 2) {
+ tetra = new TriangleStripArray(12,
+ TriangleStripArray.COORDINATES|
+ TriangleStripArray.COLOR_3|
+ TriangleStripArray.BY_REFERENCE|
+ TriangleStripArray.USE_NIO_BUFFER,
+ stripVertexCounts);
+ tetra.setCoordRefBuffer(floatBufferCoord);
+ tetra.setColorRefBuffer(floatBufferColor);
+
+ }
+ else if (type == 3) { // Indexed Geometry
+ tetra = new IndexedTriangleArray(4,
+ IndexedTriangleArray.COORDINATES|
+ IndexedTriangleArray.COLOR_3|
+ IndexedTriangleArray.BY_REFERENCE|
+ IndexedTriangleArray.USE_NIO_BUFFER,
+ //IndexedTriangleStripArray.USE_COORD_INDEX_ONLY,
+ 12);
+ tetra.setCoordRefBuffer(indexedFloatBufferCoord);
+ tetra.setColorRefBuffer(indexedFloatBufferColor);
+ ((IndexedTriangleArray)tetra).setCoordinateIndices(0, indices);
+ ((IndexedTriangleArray)tetra).setColorIndices(0, indices);
+ }
+ else if (type == 4) { // Indexed strip geometry
+ tetra = new IndexedTriangleStripArray(4,
+ IndexedTriangleStripArray.COORDINATES|
+ IndexedTriangleStripArray.COLOR_3|
+ IndexedTriangleStripArray.BY_REFERENCE|
+ IndexedTriangleStripArray.USE_NIO_BUFFER|
+ IndexedTriangleStripArray.USE_COORD_INDEX_ONLY,
+ 12,
+ stripVertexCounts);
+ tetra.setCoordRefBuffer(indexedFloatBufferCoord);
+ tetra.setColorRefBuffer(indexedFloatBufferColor);
+ ((IndexedTriangleStripArray)tetra).setCoordinateIndices(0, indices);
+ /*
+ // Do not set color indices in UCIO mode
+ ((IndexedTriangleStripArray)tetra).setColorIndices(0, indices);
+ */
+ }
+
+ if (tetra != null)
+ tetra.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE);
+ return tetra;
+ }
+
+ public void updateData(Geometry geometry) {
+ int i;
+ float val;
+ float val1;
+ if (updateIndex == 1) { // geometry
+ // Translate the geometry by a small amount in x
+ vertexCount++;
+ if ((vertexCount &1) == 1)
+ val = 0.2f;
+ else
+ val = -0.2f;
+
+ FloatBuffer indexedCoord = (FloatBuffer)indexedFloatBufferCoord.getBuffer();
+ indexedCoord.rewind();
+ FloatBuffer coord = (FloatBuffer)floatBufferCoord.getBuffer();
+ coord.rewind();
+
+ if (vertexIndex == 0) {
+ // Do Indexed geometry
+ for (i = 0; i < indexedCoord.limit(); i+=3) {
+ val1 = indexedCoord.get(i);
+ indexedCoord.put(i, val1 + val);
+ }
+ // Do non-indexed float geometry
+ for (i = 0; i < coord.limit(); i+=3) {
+ val1 = coord.get(i);
+ coord.put(i, val1 + val);
+ }
+ }
+ }
+ else if (updateIndex == 2) { // colors
+ colorCount++;
+ if ((colorCount & 1) == 1)
+ val = 0.4f;
+ else
+ val = -0.4f;
+
+ FloatBuffer indexedColors = (FloatBuffer)indexedFloatBufferColor.getBuffer();
+ indexedColors.rewind();
+ FloatBuffer colors = (FloatBuffer)floatBufferColor.getBuffer();
+ colors.rewind();
+
+ if (colorIndex == 0) {
+ // Do Indexed geometry
+ for (i = 0; i < indexedColors.limit(); i+=3) {
+ indexedColors.put(i, indexedColors.get(i) + val);
+ }
+ // Do non-indexed float geometry
+ for (i = 0; i < colors.limit(); i+=3) {
+ colors.put(i, colors.get(i) + val);
+ }
+ }
+
+ }
+
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java
new file mode 100644
index 0000000..a2f3b74
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java
@@ -0,0 +1,554 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_by_ref;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+
+public class GeometryByReferenceTest extends JApplet implements ActionListener,
+GeometryUpdater {
+
+ RenderingAttributes ra;
+ ColoringAttributes ca;
+ Material mat;
+ Appearance app;
+ JComboBox geomType;
+ JComboBox vertexType;
+ JComboBox colorType;
+ JCheckBox transparency;
+ JComboBox updates;
+ Shape3D shape;
+ TransparencyAttributes transp;
+ int updateIndex = 0;
+ int colorCount = 0, vertexCount = 0;
+ int vertexIndex = 0, colorIndex = 0;
+
+ GeometryArray tetraRegular, tetraStrip, tetraIndexed, tetraIndexedStrip;
+ GeometryArray[] geoArrays = new GeometryArray[4];
+
+ private static final float sqrt3 = (float) Math.sqrt(3.0);
+ private static final float sqrt3_3 = sqrt3 / 3.0f;
+ private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;
+
+ private static final float ycenter = 0.5f * sqrt24_3;
+ private static final float zcenter = -sqrt3_3;
+
+ private static final Point3f p1 =
+ new Point3f(-1.0f, -ycenter, -zcenter);
+ private static final Point3f p2 =
+ new Point3f(1.0f, -ycenter, -zcenter);
+ private static final Point3f p3 =
+ new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
+ private static final Point3f p4 =
+ new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);
+
+
+ private static final float[] floatVerts = {
+ p1.x, p1.y, p1.z, // front face
+ p2.x, p2.y, p2.z,
+ p4.x, p4.y, p4.z,
+
+ p1.x, p1.y, p1.z,// left, back face
+ p4.x, p4.y, p4.z,
+ p3.x, p3.y, p3.z,
+
+ p2.x, p2.y, p2.z,// right, back face
+ p3.x, p3.y, p3.z,
+ p4.x, p4.y, p4.z,
+
+ p1.x, p1.y, p1.z,// bottom face
+ p3.x, p3.y, p3.z,
+ p2.x, p2.y, p2.z,
+ };
+
+ private static final Color3f c1 = new Color3f(0.6f, 0.0f, 0.0f);
+ private static final Color3f c2 = new Color3f(0.0f, 0.6f, 0.0f);
+ private static final Color3f c3 = new Color3f(0.0f, 0.6f, 0.6f);
+ private static final Color3f c4 = new Color3f(0.6f, 0.6f, 0.0f);
+
+
+ private static final float[] floatClrs = {
+ c1.x, c1.y, c1.z, // front face
+ c2.x, c2.y, c2.z,
+ c4.x, c4.y, c4.z,
+
+ c1.x, c1.y, c1.z,// left, back face
+ c4.x, c4.y, c4.z,
+ c3.x, c3.y, c3.z,
+
+ c2.x, c2.y, c2.z,// right, back face
+ c3.x, c3.y, c3.z,
+ c4.x, c4.y, c4.z,
+
+ c1.x, c1.y, c1.z,// bottom face
+ c3.x, c3.y, c3.z,
+ c2.x, c2.y, c2.z,
+ } ;
+
+ private static final float[] indexedFloatVerts = {
+ p1.x,p1.y,p1.z,
+ p2.x,p2.y,p2.z,
+ p3.x,p3.y,p3.z,
+ p4.x,p4.y,p4.z,
+
+ };
+ private static final float[] indexedFloatClrs = {
+ c1.x,c1.y,c1.z,
+ c2.x,c2.y,c2.z,
+ c3.x,c3.y,c3.z,
+ c4.x,c4.y,c4.z,
+ };
+ private static final Point3f[] p3fVerts = {
+ p1, p2, p4, p1, p4, p3, p2, p3, p4, p1, p3, p2};
+
+ private static final Point3f[] indexedP3fVerts = {p1, p2, p3, p4};
+
+ private static final Color3f[] c3fClrs = {
+ c1, c2, c4, c1, c4, c3, c2, c3, c4, c1, c3, c2};
+
+ private static final Color3f[] indexedC3fClrs = {c1, c2, c3, c4};
+
+
+ private static final int[] indices = {0,1,3,0,3,2,1,2,3,0,2,1};
+ private int[] stripVertexCounts = {3,3,3,3};
+
+ private SimpleUniverse u;
+
+ BranchGroup createSceneGraph() {
+ BranchGroup objRoot = new BranchGroup();
+
+ // Set up attributes to render lines
+ app = new Appearance();
+
+ transp = new TransparencyAttributes();
+ transp.setTransparency(0.5f);
+ transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
+ transp.setTransparencyMode(TransparencyAttributes.NONE);
+ app.setTransparencyAttributes(transp);
+
+ tetraRegular = createGeometry(1);
+ tetraStrip =createGeometry(2);
+ tetraIndexed = createGeometry(3);
+ tetraIndexedStrip = createGeometry(4);
+
+ geoArrays[0] = tetraRegular;
+ geoArrays[1] = tetraStrip;
+ geoArrays[2] = tetraIndexed;
+ geoArrays[3] = tetraIndexedStrip;
+
+ shape = new Shape3D(tetraRegular, app);
+ shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+ shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
+
+ Transform3D t = new Transform3D();
+ // move the object upwards
+ t.set(new Vector3f(0.0f, 0.3f, 0.0f));
+
+ // rotate the shape
+ Transform3D temp = new Transform3D();
+ temp.rotX(Math.PI/4.0d);
+ t.mul(temp);
+ temp.rotY(Math.PI/4.0d);
+ t.mul(temp);
+
+ // Shrink the object
+ t.setScale(0.6);
+
+ TransformGroup trans = new TransformGroup(t);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+
+ objRoot.addChild(trans);
+ trans.addChild(shape);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objRoot.addChild(aLgt);
+ objRoot.addChild(lgt1);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ JPanel createGeometryByReferencePanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Geometry Type"));
+
+ String values[] = {"Array", "Strip", "Indexed", "IndexedStrip"};
+ geomType = new JComboBox(values);
+ geomType.setLightWeightPopupEnabled(false);
+ geomType.addActionListener(this);
+ geomType.setSelectedIndex(0);
+ panel.add(new JLabel("Geometry Type"));
+ panel.add(geomType);
+
+
+ String vertex_types[] = { "Float","P3F"};
+
+ vertexType = new JComboBox(vertex_types);
+ vertexType.setLightWeightPopupEnabled(false);
+ vertexType.addActionListener(this);
+ vertexType.setSelectedIndex(0);
+ panel.add(new JLabel("VertexType"));
+ panel.add(vertexType);
+
+
+ String color_types[] = { "Float","C3F"};
+
+ colorType = new JComboBox(color_types);
+ colorType.setLightWeightPopupEnabled(false);
+ colorType.addActionListener(this);
+ colorType.setSelectedIndex(0);
+ panel.add(new JLabel("ColorType"));
+ panel.add(colorType);
+
+
+
+
+ return panel;
+ }
+
+ JPanel createUpdatePanel() {
+
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Other Attributes"));
+
+ String updateComp[] = { "None","Geometry", "Color"};
+
+ transparency = new JCheckBox("EnableTransparency",
+ false);
+ transparency.addActionListener(this);
+ panel.add(transparency);
+
+
+ updates = new JComboBox(updateComp);
+ updates.setLightWeightPopupEnabled(false);
+ updates.addActionListener(this);
+ updates.setSelectedIndex(0);
+ panel.add(new JLabel("UpdateData"));
+ panel.add(updates);
+
+ return panel;
+ }
+
+
+
+ public GeometryByReferenceTest() {
+ }
+
+ public void init() {
+ Container contentPane = getContentPane();
+
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ contentPane.add("Center", c);
+
+ BranchGroup scene = createSceneGraph();
+ // SimpleUniverse is a Convenience Utility class
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the viewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+ u.addBranchGraph(scene);
+
+ // add Orbit behavior to the ViewingPlatform
+ OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ // Create GUI
+ JPanel p = new JPanel();
+ BoxLayout boxlayout = new BoxLayout(p,
+ BoxLayout.Y_AXIS);
+ p.add(createGeometryByReferencePanel());
+ p.add(createUpdatePanel());
+ p.setLayout(boxlayout);
+
+ contentPane.add("South", p);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object target = e.getSource();
+ GeometryArray geo;
+ boolean setColor = false, setVertex = false;
+ if (target == geomType) {
+ geo = geoArrays[geomType.getSelectedIndex()];
+ // Set everything to null, and set it later ..
+ geo.setColorRefFloat(null);
+ geo.setColorRef3f(null);
+ geo.setCoordRefFloat(null);
+ geo.setCoordRef3f(null);
+ shape.setGeometry(geoArrays[geomType.getSelectedIndex()]);
+
+ setColor = true;
+ setVertex= true;
+
+
+ }
+ else if (target == transparency) {
+ if (transparency.isSelected()) {
+ transp.setTransparencyMode(TransparencyAttributes.BLENDED);
+ }
+ else {
+ transp.setTransparencyMode(TransparencyAttributes.NONE);
+ }
+
+
+ }
+ else if (target == updates) {
+ updateIndex = updates.getSelectedIndex();
+ if (updateIndex == 1) {
+ System.out.println("Doing coordinate update");
+ ((GeometryArray)(shape.getGeometry())).updateData(this);
+ }
+ else if (updateIndex == 2) {
+ System.out.println("Doing color update");
+ ((GeometryArray)(shape.getGeometry())).updateData(this);
+ }
+
+ }
+ else if (target == vertexType) {
+ geo = ((GeometryArray)shape.getGeometry());
+ if (vertexIndex == 0) {
+ geo.setCoordRefFloat(null);
+ }
+ else if (vertexIndex == 1) {
+ geo.setCoordRef3f(null);
+ }
+ vertexIndex = vertexType.getSelectedIndex();
+ setVertex = true;
+ }
+ else if (target == colorType) {
+ geo = (GeometryArray) shape.getGeometry();
+ if (colorIndex == 0) {
+ geo.setColorRefFloat(null);
+ }
+ else if (colorIndex == 1) {
+ geo.setColorRef3f(null);
+ }
+ colorIndex = colorType.getSelectedIndex();
+ setColor = true;
+ }
+
+ if (setVertex) {
+ geo = (GeometryArray) shape.getGeometry();
+ if (vertexIndex == 0) {
+ if (geo instanceof IndexedGeometryArray)
+ geo.setCoordRefFloat(indexedFloatVerts);
+ else
+ geo.setCoordRefFloat(floatVerts);
+ }
+ else if (vertexIndex == 1) {
+ if (geo instanceof IndexedGeometryArray)
+ geo.setCoordRef3f(indexedP3fVerts);
+ else
+ geo.setCoordRef3f(p3fVerts);
+ }
+
+ }
+ if (setColor) {
+ geo = (GeometryArray) shape.getGeometry();
+ if (colorIndex == 0) {
+ if (geo instanceof IndexedGeometryArray)
+ geo.setColorRefFloat(indexedFloatClrs);
+ else
+ geo.setColorRefFloat(floatClrs);
+ }
+ else if (colorIndex == 1) {
+ if (geo instanceof IndexedGeometryArray)
+ geo.setColorRef3f(indexedC3fClrs);
+ else
+ geo.setColorRef3f(c3fClrs);
+ }
+ }
+
+ }
+
+
+
+ public static void main(String[] args) {
+ Frame frame = new MainFrame(new GeometryByReferenceTest(), 800, 800);
+ }
+
+ public GeometryArray createGeometry (int type) {
+ GeometryArray tetra = null;
+ if (type == 1) {
+ tetra =new TriangleArray(12,
+ TriangleArray.COORDINATES|
+ TriangleArray.COLOR_3|
+ TriangleArray.BY_REFERENCE);
+
+ tetra.setCoordRefFloat(floatVerts);
+ tetra.setColorRefFloat(floatClrs);
+
+ }
+ else if (type == 2) {
+ tetra = new TriangleStripArray(12,
+ TriangleStripArray.COORDINATES|
+ TriangleStripArray.COLOR_3|
+ TriangleStripArray.BY_REFERENCE,
+ stripVertexCounts);
+ tetra.setCoordRefFloat(floatVerts);
+ tetra.setColorRefFloat(floatClrs);
+
+ }
+ else if (type == 3) { // Indexed Geometry
+ tetra = new IndexedTriangleArray(4,
+ IndexedTriangleArray.COORDINATES|
+ IndexedTriangleArray.COLOR_3|
+ IndexedTriangleArray.BY_REFERENCE,
+ 12);
+ tetra.setCoordRefFloat(indexedFloatVerts);
+ tetra.setColorRefFloat(indexedFloatClrs);
+ ((IndexedTriangleArray)tetra).setCoordinateIndices(0, indices);
+ ((IndexedTriangleArray)tetra).setColorIndices(0, indices);
+ }
+ else if (type == 4) { // Indexed strip geometry
+ tetra = new IndexedTriangleStripArray(4,
+ IndexedTriangleStripArray.COORDINATES|
+ IndexedTriangleStripArray.COLOR_3|
+ IndexedTriangleStripArray.BY_REFERENCE,
+ 12,
+ stripVertexCounts);
+ tetra.setCoordRefFloat(indexedFloatVerts);
+ tetra.setColorRefFloat(indexedFloatClrs);
+ ((IndexedTriangleStripArray)tetra).setCoordinateIndices(0, indices);
+ ((IndexedTriangleStripArray)tetra).setColorIndices(0, indices);
+ }
+
+ if (tetra != null)
+ tetra.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE);
+ return tetra;
+ }
+
+ public void updateData(Geometry geometry) {
+ int i;
+ float val;
+
+
+ if (updateIndex == 1) { // geometry
+ // Translate the geometry by a small amount in x
+ vertexCount++;
+ if ((vertexCount &1) == 1)
+ val = 0.2f;
+ else
+ val = -0.2f;
+
+ if (vertexIndex == 0) {
+ // Do Indexed geometry
+ for (i = 0; i < indexedFloatVerts.length; i+=3) {
+ indexedFloatVerts[i] += val;
+ }
+ // Do non-indexed float geometry
+ for (i = 0; i < floatVerts.length; i+=3) {
+ floatVerts[i] += val;
+ }
+ }
+ else {
+ // If p3f do each point only once
+ for (i = 0; i < indexedP3fVerts.length; i++) {
+ indexedP3fVerts[i].x += val;
+ }
+ }
+
+ }
+ else if (updateIndex == 2) { // colors
+ colorCount++;
+ if ((colorCount & 1) == 1)
+ val = 0.4f;
+ else
+ val = -0.4f;
+ if (colorIndex == 0) {
+ // Do Indexed geometry
+ for (i = 0; i < indexedFloatClrs.length; i+=3) {
+ indexedFloatClrs[i] += val;
+ }
+ // Do non-indexed float geometry
+ for (i = 0; i < floatClrs.length; i+=3) {
+ floatClrs[i] += val;
+ }
+ }
+ else {
+ // If c3f do each point only once
+ for (i = 0; i < indexedC3fClrs.length; i++) {
+ indexedC3fClrs[i].x += val;
+ }
+ }
+
+ }
+
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java
new file mode 100644
index 0000000..aa649f7
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java
@@ -0,0 +1,330 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_by_ref;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.sun.j3d.utils.behaviors.mouse.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.geometry.Box;
+import com.sun.j3d.utils.geometry.ColorCube;
+import java.awt.image.*;
+import java.awt.color.ColorSpace;
+import com.sun.j3d.utils.geometry.*;
+
+public class ImageComponentByReferenceTest extends JApplet implements ActionListener {
+
+ Shape3D s1,s2;
+ TextureLoader t0, t1, t2;
+ int count = 0;
+
+ Appearance app = new Appearance();
+ BranchGroup objRoot = new BranchGroup();
+ TransformGroup objTrans = new TransformGroup();
+ BufferedImage bImage1;
+ TiledImage checkBoard;
+ boolean yUp = false;
+ boolean byRef = true;
+ JComboBox rasterType, texType;
+ ImageComponent2D[] image = new ImageComponent2D[8];
+ Appearance dummyApp = new Appearance();
+ Texture2D texOne, texCheckBoard;
+ javax.media.j3d.Raster raster;
+ Box textureCube;
+ Shape3D boxShape;
+ int w1 = 64, h1 = 32, checkw = 16 , checkh = 16;
+
+ private java.net.URL texImage = null;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ objRoot = new BranchGroup();
+
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(Group.ALLOW_CHILDREN_WRITE);
+
+ objRoot.addChild(objTrans);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ app.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
+
+
+ textureCube = new Box(0.4f, 0.4f, 0.4f,
+ Box.GENERATE_TEXTURE_COORDS|
+ Box.GENERATE_NORMALS, app);
+ boxShape = textureCube.getShape(Box.FRONT);
+ boxShape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ objTrans.addChild(textureCube);
+
+ checkBoard = new TiledImage();
+ TextureLoader texLoader = new TextureLoader( texImage, this);
+ ImageComponent2D oneImage = texLoader.getImage();
+ bImage1 = oneImage.getImage();
+
+ int index = 0;
+ image[index++] = new ImageComponent2D(oneImage.getFormat(),
+ (RenderedImage)bImage1,
+ false,
+ true);
+
+ image[index++] = new ImageComponent2D(oneImage.getFormat(),
+ (RenderedImage)bImage1,
+ true,
+ true);
+
+
+ image[index++] = new ImageComponent2D(oneImage.getFormat(),
+ (RenderedImage)bImage1,
+ false,
+ false);
+
+
+ image[index++] = new ImageComponent2D(oneImage.getFormat(),
+ (RenderedImage)bImage1,
+ true,
+ false);
+
+ createRaster(objRoot);
+
+ image[index++] = new ImageComponent2D(ImageComponent.FORMAT_RGBA,
+ checkBoard,
+ false,
+ true);
+
+ image[index++] = new ImageComponent2D(ImageComponent.FORMAT_RGBA,
+ checkBoard,
+ true,
+ true);
+
+
+ image[index++] = new ImageComponent2D(ImageComponent.FORMAT_RGBA,
+ checkBoard,
+ false,
+ false);
+
+
+ image[index++] = new ImageComponent2D(ImageComponent.FORMAT_RGBA,
+ checkBoard,
+ true,
+ false);
+
+
+
+ texOne = new Texture2D(Texture.BASE_LEVEL,
+ Texture.RGBA,
+ image[2].getWidth(), image[2].getHeight());
+
+ texOne.setCapability(Texture.ALLOW_IMAGE_WRITE);
+ texOne.setImage(0, image[2]);
+
+ app.setTexture(texOne);
+
+ texCheckBoard = new Texture2D(Texture.BASE_LEVEL,
+ Texture.RGBA,
+ image[4].getWidth(), image[4].getHeight());
+
+ texCheckBoard.setCapability(Texture.ALLOW_IMAGE_WRITE);
+ objRoot.compile();
+ return objRoot;
+ }
+
+ public void actionPerformed(ActionEvent e ) {
+ Object target = e.getSource();
+
+ if (target == rasterType) {
+ if (rasterType.getSelectedIndex() < 4) {
+ raster.setSize(w1, h1);
+ }
+ else {
+ raster.setSize(checkw, checkh);
+ }
+ raster.setImage(image[rasterType.getSelectedIndex()]);
+ }
+ else if (target == texType) {
+ boxShape.setAppearance(dummyApp);
+ if (texType.getSelectedIndex() < 4) {
+ texOne.setImage(0, image[texType.getSelectedIndex()]);
+ app.setTexture(texOne);
+ }
+ else {
+ texCheckBoard.setImage(0, image[texType.getSelectedIndex()]);
+ app.setTexture(texCheckBoard);
+ }
+
+ boxShape.setAppearance(app);
+ }
+
+
+ }
+
+ JPanel createImagePanel() {
+ JPanel panel = new JPanel();
+ String texVals[] = { "One_Yup_ByCopy",
+ "One_Yup_ByReference",
+ "One_Ydown_ByCopy",
+ "One_Ydown_ByReference",
+ "Checkered_Yup_ByCopy",
+ "Checkered_Yup_ByReference",
+ "Checkered_Ydown_ByCopy",
+ "Checkered_Ydown_ByReference"};
+
+ rasterType = new JComboBox(texVals);
+ rasterType.setLightWeightPopupEnabled(false);
+ rasterType.addActionListener(this);
+ rasterType.setSelectedIndex(2);
+ panel.add(new JLabel("Raster Image"));
+ panel.add(rasterType);
+
+ texType = new JComboBox(texVals);
+ texType.setLightWeightPopupEnabled(false);
+ texType.addActionListener(this);
+ texType.setSelectedIndex(2);
+ panel.add(new JLabel("Texture Image"));
+ panel.add(texType);
+ return panel;
+
+ }
+
+
+
+ public ImageComponentByReferenceTest()
+ {
+ }
+
+ public ImageComponentByReferenceTest(java.net.URL url) {
+ texImage = url;
+ }
+
+ public void init() {
+ if (texImage == null) {
+ // the path to the image for an applet
+ try {
+ texImage = new java.net.URL(getCodeBase().toString() +
+ "../images/one.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ BranchGroup scene = createSceneGraph();u = new SimpleUniverse(c);
+ u.getViewingPlatform().setNominalViewingTransform();
+ u.addBranchGraph(scene);
+ Container contentPane = getContentPane();
+ JPanel p = new JPanel();
+ BoxLayout boxlayout = new BoxLayout(p,
+ BoxLayout.Y_AXIS);
+ p.setLayout(boxlayout);
+ contentPane.add("Center", c);
+
+ contentPane.add("South", p);
+
+ p.add(createImagePanel());
+
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public static void main(String[] args) {
+ java.net.URL url = null;
+ // the path to the image file for an application
+ try {
+ url = new java.net.URL("file:../images/one.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+
+ new MainFrame(new ImageComponentByReferenceTest(url), 800, 700);
+ }
+
+ void createRaster( BranchGroup scene) {
+
+
+
+ // Create raster geometries and shapes
+ Vector3f trans = new Vector3f( );
+ Transform3D tr = new Transform3D( );
+ TransformGroup tg;
+
+ // Left
+ raster = new javax.media.j3d.Raster( );
+ raster.setCapability(javax.media.j3d.Raster.ALLOW_IMAGE_WRITE);
+ raster.setCapability(javax.media.j3d.Raster.ALLOW_SIZE_WRITE);
+ raster.setPosition( new Point3f( -0.9f, 0.75f, 0.0f ) );
+ raster.setType( javax.media.j3d.Raster.RASTER_COLOR );
+ raster.setOffset( 0, 0 );
+
+ raster.setSize( image[2].getWidth(), image[2].getHeight() );
+ raster.setImage( image[2] );
+ Shape3D sh = new Shape3D( raster, new Appearance( ) );
+ scene.addChild( sh );
+
+
+
+ }
+}
+
+
+
+
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java
new file mode 100644
index 0000000..78edf99
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java
@@ -0,0 +1,536 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_by_ref;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+import java.nio.*;
+
+public class InterleavedNIOBuffer extends JApplet implements ActionListener {
+
+ RenderingAttributes ra;
+ ColoringAttributes ca;
+ Material mat;
+ Appearance app;
+ JComboBox geomType;
+ JCheckBox transparency;
+ JCheckBox textureBox;
+ Shape3D shape;
+ TransparencyAttributes transp;
+
+ GeometryArray tetraRegular, tetraStrip, tetraIndexed, tetraIndexedStrip;
+ GeometryArray[] geoArrays = new GeometryArray[4];
+
+ // Globally used colors
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
+ Color3f[] colors = {white, red, green, blue};
+
+ private static final float sqrt3 = (float) Math.sqrt(3.0);
+ private static final float sqrt3_3 = sqrt3 / 3.0f;
+ private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;
+
+ private static final float ycenter = 0.5f * sqrt24_3;
+ private static final float zcenter = -sqrt3_3;
+
+ private static final Point3f p1 =
+ new Point3f(-1.0f, -ycenter, -zcenter);
+ private static final Point3f p2 =
+ new Point3f(1.0f, -ycenter, -zcenter);
+ private static final Point3f p3 =
+ new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
+ private static final Point3f p4 =
+ new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);
+
+ private static final Point2f t1 = new Point2f(0.0f, 0.0f);
+ private static final Point2f t2 = new Point2f(0.5f, 1.0f);
+ private static final Point2f t3 = new Point2f(1.0f, 0.0f);
+ private static final Point2f t4 = new Point2f(1.0f, 1.0f);
+
+ private static final Color3f c1 = new Color3f(1.0f, 0.0f, 0.0f);
+ private static final Color3f c2 = new Color3f(0.0f, 1.0f, 0.0f);
+ private static final Color3f c3 = new Color3f(0.0f, 1.0f, 1.0f);
+ private static final Color3f c4 = new Color3f(1.0f, 1.0f, 0.0f);
+
+
+ private static final float[] interleaved = {
+ t1.x, t1.y,
+ t1.x, t1.y,
+ c1.x, c1.y, c1.z, // front face
+ p1.x, p1.y, p1.z, // front face
+ t2.x, t2.y,
+ t2.x, t2.y,
+ c2.x, c2.y, c2.z,
+ p2.x, p2.y, p2.z,
+ t4.x, t4.y,
+ t4.x, t4.y,
+ c4.x, c4.y, c4.z,
+ p4.x, p4.y, p4.z,
+
+ t1.x, t1.y,
+ t1.x, t1.y,
+ c1.x, c1.y, c1.z,// left, back face
+ p1.x, p1.y, p1.z,// left, back face
+ t4.x, t4.y,
+ t4.x, t4.y,
+ c4.x, c4.y, c4.z,
+ p4.x, p4.y, p4.z,
+ t3.x, t3.y,
+ t3.x, t3.y,
+ c3.x, c3.y, c3.z,
+ p3.x, p3.y, p3.z,
+
+ t2.x, t2.y,
+ t2.x, t2.y,
+ c2.x, c2.y, c2.z,// right, back face
+ p2.x, p2.y, p2.z,// right, back face
+ t3.x, t3.y,
+ t3.x, t3.y,
+ c3.x, c3.y, c3.z,
+ p3.x, p3.y, p3.z,
+ t4.x, t4.y,
+ t4.x, t4.y,
+ c4.x, c4.y, c4.z,
+ p4.x, p4.y, p4.z,
+
+ t1.x, t1.y,
+ t1.x, t1.y,
+ c1.x, c1.y, c1.z,// bottom face
+ p1.x, p1.y, p1.z,// bottom face
+ t3.x, t3.y,
+ t3.x, t3.y,
+ c3.x, c3.y, c3.z,
+ p3.x, p3.y, p3.z,
+ t2.x, t2.y,
+ t2.x, t2.y,
+ c2.x, c2.y, c2.z,
+ p2.x, p2.y, p2.z,
+ };
+
+ private static final float[] indexedInterleaved = {
+ t1.x,t1.y,
+ t1.x,t1.y,
+ c1.x,c1.y,c1.z,
+ p1.x,p1.y,p1.z,
+ t2.x,t2.y,
+ t2.x,t2.y,
+ c2.x,c2.y,c2.z,
+ p2.x,p2.y,p2.z,
+ t3.x,t3.y,
+ t3.x,t3.y,
+ c3.x,c3.y,c3.z,
+ p3.x,p3.y,p3.z,
+ t4.x,t4.y,
+ t4.x,t4.y,
+ c4.x,c4.y,c4.z,
+ p4.x,p4.y,p4.z,
+ };
+
+
+ private static final int[] indices = {0,1,3,0,3,2,1,2,3,0,2,1};
+ private int[] stripVertexCounts = {3,3,3,3};
+
+ TextureUnitState textureUnitState[] = new TextureUnitState[2];
+ Texture tex1;
+ Texture tex2;
+
+ private java.net.URL texImage1 = null;
+ private java.net.URL texImage2 = null;
+
+ private SimpleUniverse u;
+
+ private J3DBuffer interleavedBuffer;
+ private J3DBuffer indexedInterleavedBuffer;
+
+ void createInterleavedBuffers() {
+ int size;
+ ByteOrder order = ByteOrder.nativeOrder();
+
+ size = (2 + 2 + 3 + 3 ) * 3 * 4;
+ FloatBuffer vertex = ByteBuffer.allocateDirect(size * 4).order(order).asFloatBuffer();
+ vertex.put(interleaved, 0, size);
+ interleavedBuffer = new J3DBuffer(vertex);
+
+ size = ( 2 + 2 + 3 + 3) * 4;
+ FloatBuffer indexedVertex = ByteBuffer.allocateDirect(size * 4).order(order).asFloatBuffer();
+ indexedVertex.put(indexedInterleaved, 0, size);
+ indexedInterleavedBuffer = new J3DBuffer(indexedVertex);
+ }
+
+ BranchGroup createSceneGraph() {
+ BranchGroup objRoot = new BranchGroup();
+
+ // Set up attributes to render lines
+ app = new Appearance();
+ app.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE);
+
+ transp = new TransparencyAttributes();
+ transp.setTransparency(0.5f);
+ transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
+ transp.setTransparencyMode(TransparencyAttributes.NONE);
+ app.setTransparencyAttributes(transp);
+
+ // load textures
+ TextureAttributes texAttr1 = new TextureAttributes();
+ texAttr1.setTextureMode(TextureAttributes.DECAL);
+ TextureAttributes texAttr2 = new TextureAttributes();
+ texAttr2.setTextureMode(TextureAttributes.MODULATE);
+
+ TextureLoader tex = new TextureLoader(texImage1, new String("RGB"), this);
+ if (tex == null)
+ return null;
+ tex1 = tex.getTexture();
+
+ tex = new TextureLoader(texImage2, new String("RGB"), this);
+ if (tex == null)
+ return null;
+ tex2 = tex.getTexture();
+
+ textureUnitState[0] = new TextureUnitState(tex1, texAttr1, null);
+ textureUnitState[1] = new TextureUnitState(tex2, texAttr2, null);
+
+ createInterleavedBuffers();
+
+ tetraRegular = createGeometry(1);
+ tetraStrip =createGeometry(2);
+ tetraIndexed = createGeometry(3);
+ tetraIndexedStrip = createGeometry(4);
+
+ geoArrays[0] = tetraRegular;
+ geoArrays[1] = tetraStrip;
+ geoArrays[2] = tetraIndexed;
+ geoArrays[3] = tetraIndexedStrip;
+
+ shape = new Shape3D(tetraRegular, app);
+ shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+
+ Transform3D t = new Transform3D();
+ // move the object upwards
+ t.set(new Vector3f(0.0f, 0.3f, 0.0f));
+
+ // rotate the shape
+ Transform3D temp = new Transform3D();
+ temp.rotX(Math.PI/4.0d);
+ t.mul(temp);
+ temp.rotY(Math.PI/4.0d);
+ t.mul(temp);
+
+ // Shrink the object
+ t.setScale(0.6);
+
+ TransformGroup trans = new TransformGroup(t);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+
+ objRoot.addChild(trans);
+ trans.addChild(shape);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objRoot.addChild(aLgt);
+ objRoot.addChild(lgt1);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ JPanel createGeometryByReferencePanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Geometry Type"));
+
+ String values[] = {"Array", "Strip", "Indexed", "IndexedStrip"};
+ geomType = new JComboBox(values);
+ geomType.setLightWeightPopupEnabled(false);
+ geomType.addActionListener(this);
+ geomType.setSelectedIndex(0);
+ panel.add(new JLabel("Geometry Type"));
+ panel.add(geomType);
+
+ transparency = new JCheckBox("EnableTransparency",
+ false);
+ transparency.addActionListener(this);
+ panel.add(transparency);
+
+ textureBox = new JCheckBox("EnableTexture", false);
+ textureBox.addActionListener(this);
+ panel.add(textureBox);
+
+ return panel;
+ }
+
+ public InterleavedNIOBuffer() {
+ }
+
+ public InterleavedNIOBuffer(java.net.URL texURL1, java.net.URL texURL2) {
+ texImage1 = texURL1;
+ texImage2 = texURL2;
+ }
+
+ public void init() {
+
+ // create textures
+
+ if (texImage1 == null) {
+ // the path to the image for an applet
+ try {
+ texImage1 = new java.net.URL(getCodeBase().toString() +
+ "../images/bg.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ if (texImage2 == null) {
+ // the path to the image for an applet
+ try {
+ texImage2 = new java.net.URL(getCodeBase().toString() +
+ "../images/one.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ Container contentPane = getContentPane();
+
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ contentPane.add("Center", c);
+
+ BranchGroup scene = createSceneGraph();
+ // SimpleUniverse is a Convenience Utility class
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the viewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ // add Orbit behavior to the viewing platform
+ OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene);
+
+
+ // Create GUI
+ JPanel p = new JPanel();
+ BoxLayout boxlayout = new BoxLayout(p,
+ BoxLayout.Y_AXIS);
+ p.add(createGeometryByReferencePanel());
+ p.setLayout(boxlayout);
+
+ contentPane.add("South", p);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object target = e.getSource();
+ if (target == geomType) {
+ shape.setGeometry(geoArrays[geomType.getSelectedIndex()]);
+
+ }
+ else if (target == transparency) {
+ if (transparency.isSelected()) {
+ transp.setTransparencyMode(TransparencyAttributes.BLENDED);
+ }
+ else {
+ transp.setTransparencyMode(TransparencyAttributes.NONE);
+ }
+ }
+ else if (target == textureBox) {
+ if (textureBox.isSelected()) {
+ app.setTextureUnitState(textureUnitState);
+ }
+ else {
+ app.setTextureUnitState(null);
+ }
+ }
+ }
+
+
+
+ public static void main(String[] args) {
+ java.net.URL texURL1 = null;
+ java.net.URL texURL2 = null;
+ // the path to the image for an application
+ try {
+ texURL1 = new java.net.URL("file:../images/bg.jpg");
+ texURL2 = new java.net.URL("file:../images/one.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+
+ Frame frame = new MainFrame(new InterleavedNIOBuffer(texURL1, texURL2),
+ 800, 800);
+ }
+
+ public GeometryArray createGeometry (int type) {
+ GeometryArray tetra = null;
+ int texCoordSetMap[] = {0, 0};
+
+ if (type == 1) {
+ tetra =new TriangleArray(12,
+ TriangleArray.COORDINATES|
+ TriangleArray.COLOR_3|
+ /*
+ TriangleArray.NORMAL_3|
+ */
+ TriangleArray.TEXTURE_COORDINATE_2 |
+ TriangleArray.INTERLEAVED|
+ TriangleArray.BY_REFERENCE|
+ TriangleArray.USE_NIO_BUFFER,
+ 2, texCoordSetMap);
+
+ tetra.setInterleavedVertexBuffer(interleavedBuffer);
+
+ }
+ else if (type == 2) {
+ tetra = new TriangleStripArray(12,
+ TriangleStripArray.COORDINATES|
+ TriangleStripArray.COLOR_3|
+ /*
+ TriangleArray.NORMAL_3|
+ */
+ TriangleArray.TEXTURE_COORDINATE_2 |
+ TriangleStripArray.INTERLEAVED|
+ TriangleStripArray.BY_REFERENCE|
+ TriangleStripArray.USE_NIO_BUFFER,
+ 2, texCoordSetMap,
+ stripVertexCounts);
+ tetra.setInterleavedVertexBuffer(interleavedBuffer);
+
+
+ }
+ else if (type == 3) { // Indexed Geometry
+ tetra = new IndexedTriangleArray(4,
+ IndexedTriangleArray.COORDINATES|
+ IndexedTriangleArray.COLOR_3|
+ /*
+ IndexedTriangleArray.NORMAL_3|
+ */
+ IndexedTriangleArray.TEXTURE_COORDINATE_2 |
+ IndexedTriangleArray.INTERLEAVED|
+ IndexedTriangleArray.BY_REFERENCE|
+ IndexedTriangleArray.USE_NIO_BUFFER|
+ IndexedTriangleArray.USE_COORD_INDEX_ONLY,
+ 2, texCoordSetMap,
+ 12);
+ tetra.setInterleavedVertexBuffer(indexedInterleavedBuffer);
+ ((IndexedTriangleArray)tetra).setCoordinateIndices(0, indices);
+ /*
+ // Do not set color or texcoord indices in UCIO mode
+ ((IndexedTriangleArray)tetra).setColorIndices(0, indices);
+ ((IndexedTriangleArray)tetra).setTextureCoordinateIndices(
+ 0, 0, indices);
+ ((IndexedTriangleArray)tetra).setTextureCoordinateIndices(
+ 1, 0, indices);
+ */
+ }
+ else if (type == 4) { // Indexed strip geometry
+ tetra = new IndexedTriangleStripArray(4,
+ IndexedTriangleStripArray.COORDINATES|
+ IndexedTriangleStripArray.COLOR_3|
+ /*
+ IndexedTriangleArray.NORMAL_3|
+ */
+ IndexedTriangleArray.TEXTURE_COORDINATE_2 |
+ IndexedTriangleStripArray.INTERLEAVED|
+ IndexedTriangleStripArray.BY_REFERENCE|
+ IndexedTriangleStripArray.USE_NIO_BUFFER,
+ //IndexedTriangleStripArray.USE_COORD_INDEX_ONLY,
+ 2, texCoordSetMap,
+ 12,
+ stripVertexCounts);
+ tetra.setInterleavedVertexBuffer(indexedInterleavedBuffer);
+ ((IndexedTriangleStripArray)tetra).setCoordinateIndices(0, indices);
+ ((IndexedTriangleStripArray)tetra).setColorIndices(0, indices);
+ ((IndexedTriangleStripArray)tetra).setTextureCoordinateIndices(
+ 0, 0, indices);
+ ((IndexedTriangleStripArray)tetra).setTextureCoordinateIndices(
+ 1, 0, indices);
+ }
+ else if (type == 5) { // Interleaved array
+ }
+ return tetra;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java
new file mode 100644
index 0000000..788e1f6
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java
@@ -0,0 +1,506 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_by_ref;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.border.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+
+public class InterleavedTest extends JApplet implements ActionListener {
+
+ RenderingAttributes ra;
+ ColoringAttributes ca;
+ Material mat;
+ Appearance app;
+ JComboBox geomType;
+ JCheckBox transparency;
+ JCheckBox textureBox;
+ Shape3D shape;
+ TransparencyAttributes transp;
+
+ GeometryArray tetraRegular, tetraStrip, tetraIndexed, tetraIndexedStrip;
+ GeometryArray[] geoArrays = new GeometryArray[4];
+
+ // Globally used colors
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f red = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f green = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f blue = new Color3f(0.0f, 0.0f, 1.0f);
+ Color3f[] colors = {white, red, green, blue};
+
+ private static final float sqrt3 = (float) Math.sqrt(3.0);
+ private static final float sqrt3_3 = sqrt3 / 3.0f;
+ private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;
+
+ private static final float ycenter = 0.5f * sqrt24_3;
+ private static final float zcenter = -sqrt3_3;
+
+ private static final Point3f p1 =
+ new Point3f(-1.0f, -ycenter, -zcenter);
+ private static final Point3f p2 =
+ new Point3f(1.0f, -ycenter, -zcenter);
+ private static final Point3f p3 =
+ new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
+ private static final Point3f p4 =
+ new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);
+
+ private static final Point2f t1 = new Point2f(0.0f, 0.0f);
+ private static final Point2f t2 = new Point2f(0.5f, 1.0f);
+ private static final Point2f t3 = new Point2f(1.0f, 0.0f);
+ private static final Point2f t4 = new Point2f(1.0f, 1.0f);
+
+ private static final Color3f c1 = new Color3f(1.0f, 0.0f, 0.0f);
+ private static final Color3f c2 = new Color3f(0.0f, 1.0f, 0.0f);
+ private static final Color3f c3 = new Color3f(0.0f, 1.0f, 1.0f);
+ private static final Color3f c4 = new Color3f(1.0f, 1.0f, 0.0f);
+
+
+ private static final float[] interleaved = {
+ t1.x, t1.y,
+ t1.x, t1.y,
+ c1.x, c1.y, c1.z, // front face
+ p1.x, p1.y, p1.z, // front face
+ t2.x, t2.y,
+ t2.x, t2.y,
+ c2.x, c2.y, c2.z,
+ p2.x, p2.y, p2.z,
+ t4.x, t4.y,
+ t4.x, t4.y,
+ c4.x, c4.y, c4.z,
+ p4.x, p4.y, p4.z,
+
+ t1.x, t1.y,
+ t1.x, t1.y,
+ c1.x, c1.y, c1.z,// left, back face
+ p1.x, p1.y, p1.z,// left, back face
+ t4.x, t4.y,
+ t4.x, t4.y,
+ c4.x, c4.y, c4.z,
+ p4.x, p4.y, p4.z,
+ t3.x, t3.y,
+ t3.x, t3.y,
+ c3.x, c3.y, c3.z,
+ p3.x, p3.y, p3.z,
+
+ t2.x, t2.y,
+ t2.x, t2.y,
+ c2.x, c2.y, c2.z,// right, back face
+ p2.x, p2.y, p2.z,// right, back face
+ t3.x, t3.y,
+ t3.x, t3.y,
+ c3.x, c3.y, c3.z,
+ p3.x, p3.y, p3.z,
+ t4.x, t4.y,
+ t4.x, t4.y,
+ c4.x, c4.y, c4.z,
+ p4.x, p4.y, p4.z,
+
+ t1.x, t1.y,
+ t1.x, t1.y,
+ c1.x, c1.y, c1.z,// bottom face
+ p1.x, p1.y, p1.z,// bottom face
+ t3.x, t3.y,
+ t3.x, t3.y,
+ c3.x, c3.y, c3.z,
+ p3.x, p3.y, p3.z,
+ t2.x, t2.y,
+ t2.x, t2.y,
+ c2.x, c2.y, c2.z,
+ p2.x, p2.y, p2.z,
+ };
+
+ private static final float[] indexedInterleaved = {
+ t1.x,t1.y,
+ t1.x,t1.y,
+ c1.x,c1.y,c1.z,
+ p1.x,p1.y,p1.z,
+ t2.x,t2.y,
+ t2.x,t2.y,
+ c2.x,c2.y,c2.z,
+ p2.x,p2.y,p2.z,
+ t3.x,t3.y,
+ t3.x,t3.y,
+ c3.x,c3.y,c3.z,
+ p3.x,p3.y,p3.z,
+ t4.x,t4.y,
+ t4.x,t4.y,
+ c4.x,c4.y,c4.z,
+ p4.x,p4.y,p4.z,
+ };
+
+
+ private static final int[] indices = {0,1,3,0,3,2,1,2,3,0,2,1};
+ private int[] stripVertexCounts = {3,3,3,3};
+
+ TextureUnitState textureUnitState[] = new TextureUnitState[2];
+ Texture tex1;
+ Texture tex2;
+
+ private java.net.URL texImage1 = null;
+ private java.net.URL texImage2 = null;
+
+ private SimpleUniverse u;
+
+ BranchGroup createSceneGraph() {
+ BranchGroup objRoot = new BranchGroup();
+
+ // Set up attributes to render lines
+ app = new Appearance();
+ app.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE);
+
+ transp = new TransparencyAttributes();
+ transp.setTransparency(0.5f);
+ transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
+ transp.setTransparencyMode(TransparencyAttributes.NONE);
+ app.setTransparencyAttributes(transp);
+
+ // load textures
+ TextureAttributes texAttr1 = new TextureAttributes();
+ texAttr1.setTextureMode(TextureAttributes.DECAL);
+ TextureAttributes texAttr2 = new TextureAttributes();
+ texAttr2.setTextureMode(TextureAttributes.MODULATE);
+
+ TextureLoader tex = new TextureLoader(texImage1, new String("RGB"), this);
+ if (tex == null)
+ return null;
+ tex1 = tex.getTexture();
+
+ tex = new TextureLoader(texImage2, new String("RGB"), this);
+ if (tex == null)
+ return null;
+ tex2 = tex.getTexture();
+
+ textureUnitState[0] = new TextureUnitState(tex1, texAttr1, null);
+ textureUnitState[1] = new TextureUnitState(tex2, texAttr2, null);
+
+ tetraRegular = createGeometry(1);
+ tetraStrip =createGeometry(2);
+ tetraIndexed = createGeometry(3);
+ tetraIndexedStrip = createGeometry(4);
+
+ geoArrays[0] = tetraRegular;
+ geoArrays[1] = tetraStrip;
+ geoArrays[2] = tetraIndexed;
+ geoArrays[3] = tetraIndexedStrip;
+
+ shape = new Shape3D(tetraRegular, app);
+ shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+
+ Transform3D t = new Transform3D();
+ // move the object upwards
+ t.set(new Vector3f(0.0f, 0.3f, 0.0f));
+
+ // rotate the shape
+ Transform3D temp = new Transform3D();
+ temp.rotX(Math.PI/4.0d);
+ t.mul(temp);
+ temp.rotY(Math.PI/4.0d);
+ t.mul(temp);
+
+ // Shrink the object
+ t.setScale(0.6);
+
+ TransformGroup trans = new TransformGroup(t);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+
+ objRoot.addChild(trans);
+ trans.addChild(shape);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objRoot.addChild(aLgt);
+ objRoot.addChild(lgt1);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ JPanel createGeometryByReferencePanel() {
+ JPanel panel = new JPanel();
+ panel.setBorder(new TitledBorder("Geometry Type"));
+
+ String values[] = {"Array", "Strip", "Indexed", "IndexedStrip"};
+ geomType = new JComboBox(values);
+ geomType.setLightWeightPopupEnabled(false);
+ geomType.addActionListener(this);
+ geomType.setSelectedIndex(0);
+ panel.add(new JLabel("Geometry Type"));
+ panel.add(geomType);
+
+ transparency = new JCheckBox("EnableTransparency",
+ false);
+ transparency.addActionListener(this);
+ panel.add(transparency);
+
+ textureBox = new JCheckBox("EnableTexture", false);
+ textureBox.addActionListener(this);
+ panel.add(textureBox);
+
+ return panel;
+ }
+
+ public InterleavedTest() {
+ }
+
+ public InterleavedTest(java.net.URL texURL1, java.net.URL texURL2) {
+ texImage1 = texURL1;
+ texImage2 = texURL2;
+ }
+
+ public void init() {
+
+ // create textures
+
+ if (texImage1 == null) {
+ // the path to the image for an applet
+ try {
+ texImage1 = new java.net.URL(getCodeBase().toString() +
+ "../images/bg.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ if (texImage2 == null) {
+ // the path to the image for an applet
+ try {
+ texImage2 = new java.net.URL(getCodeBase().toString() +
+ "../images/one.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ Container contentPane = getContentPane();
+
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ contentPane.add("Center", c);
+
+ BranchGroup scene = createSceneGraph();
+ // SimpleUniverse is a Convenience Utility class
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the viewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ // add Orbit behavior to the viewing platform
+ OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene);
+
+
+ // Create GUI
+ JPanel p = new JPanel();
+ BoxLayout boxlayout = new BoxLayout(p,
+ BoxLayout.Y_AXIS);
+ p.add(createGeometryByReferencePanel());
+ p.setLayout(boxlayout);
+
+ contentPane.add("South", p);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object target = e.getSource();
+ if (target == geomType) {
+ shape.setGeometry(geoArrays[geomType.getSelectedIndex()]);
+
+ }
+ else if (target == transparency) {
+ if (transparency.isSelected()) {
+ transp.setTransparencyMode(TransparencyAttributes.BLENDED);
+ }
+ else {
+ transp.setTransparencyMode(TransparencyAttributes.NONE);
+ }
+ }
+ else if (target == textureBox) {
+ if (textureBox.isSelected()) {
+ app.setTextureUnitState(textureUnitState);
+ }
+ else {
+ app.setTextureUnitState(null);
+ }
+ }
+ }
+
+
+
+ public static void main(String[] args) {
+ java.net.URL texURL1 = null;
+ java.net.URL texURL2 = null;
+ // the path to the image for an application
+ try {
+ texURL1 = new java.net.URL("file:../images/bg.jpg");
+ texURL2 = new java.net.URL("file:../images/one.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+
+ Frame frame = new MainFrame(new InterleavedTest(texURL1, texURL2),
+ 800, 800);
+ }
+
+ public GeometryArray createGeometry (int type) {
+ GeometryArray tetra = null;
+ int texCoordSetMap[] = {0, 0};
+
+ if (type == 1) {
+ tetra =new TriangleArray(12,
+ TriangleArray.COORDINATES|
+ TriangleArray.COLOR_3|
+ /*
+ TriangleArray.NORMAL_3|
+ */
+ TriangleArray.TEXTURE_COORDINATE_2 |
+ TriangleArray.INTERLEAVED|
+ TriangleArray.BY_REFERENCE,
+ 2, texCoordSetMap);
+
+ tetra.setInterleavedVertices(interleaved);
+
+ }
+ else if (type == 2) {
+ tetra = new TriangleStripArray(12,
+ TriangleStripArray.COORDINATES|
+ TriangleStripArray.COLOR_3|
+ /*
+ TriangleArray.NORMAL_3|
+ */
+ TriangleArray.TEXTURE_COORDINATE_2 |
+ TriangleStripArray.INTERLEAVED|
+ TriangleStripArray.BY_REFERENCE,
+ 2, texCoordSetMap,
+ stripVertexCounts);
+ tetra.setInterleavedVertices(interleaved);
+
+
+ }
+ else if (type == 3) { // Indexed Geometry
+ tetra = new IndexedTriangleArray(4,
+ IndexedTriangleArray.COORDINATES|
+ IndexedTriangleArray.COLOR_3|
+ /*
+ IndexedTriangleArray.NORMAL_3|
+ */
+ IndexedTriangleArray.TEXTURE_COORDINATE_2 |
+ IndexedTriangleArray.INTERLEAVED|
+ IndexedTriangleArray.BY_REFERENCE,
+ 2, texCoordSetMap,
+ 12);
+ tetra.setInterleavedVertices(indexedInterleaved);
+ ((IndexedTriangleArray)tetra).setCoordinateIndices(0, indices);
+ ((IndexedTriangleArray)tetra).setColorIndices(0, indices);
+ ((IndexedTriangleArray)tetra).setTextureCoordinateIndices(
+ 0, 0, indices);
+ ((IndexedTriangleArray)tetra).setTextureCoordinateIndices(
+ 1, 0, indices);
+ }
+ else if (type == 4) { // Indexed strip geometry
+ tetra = new IndexedTriangleStripArray(4,
+ IndexedTriangleStripArray.COORDINATES|
+ IndexedTriangleStripArray.COLOR_3|
+ /*
+ IndexedTriangleArray.NORMAL_3|
+ */
+ IndexedTriangleArray.TEXTURE_COORDINATE_2 |
+ IndexedTriangleStripArray.INTERLEAVED|
+ IndexedTriangleStripArray.BY_REFERENCE,
+ 2, texCoordSetMap,
+ 12,
+ stripVertexCounts);
+ tetra.setInterleavedVertices(indexedInterleaved);
+ ((IndexedTriangleStripArray)tetra).setCoordinateIndices(0, indices);
+ ((IndexedTriangleStripArray)tetra).setColorIndices(0, indices);
+ ((IndexedTriangleStripArray)tetra).setTextureCoordinateIndices(
+ 0, 0, indices);
+ ((IndexedTriangleStripArray)tetra).setTextureCoordinateIndices(
+ 1, 0, indices);
+ }
+ else if (type == 5) { // Interleaved array
+ }
+ return tetra;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java
new file mode 100644
index 0000000..fcc51e4
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java
@@ -0,0 +1,358 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_by_ref;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.util.Vector;
+import java.awt.color.ColorSpace;
+
+public class TiledImage extends Object implements RenderedImage {
+
+
+ WritableRaster[][] tile = new WritableRaster[3][3];
+
+ WritableRaster bigTile;
+ ComponentColorModel colorModel;
+ BufferedImage checkBoard;
+ int minX = -2;
+ int minY = -1;
+
+ TiledImage() {
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ int[] nBits = {8, 8, 8, 8};
+ int i, j, k, cc = 255;
+ int[] bandOffset = new int[4];
+ colorModel =
+ new ComponentColorModel(cs, nBits, true, false, Transparency.OPAQUE, 0);
+ // Create 9 tiles
+ bandOffset[0] = 3;
+ bandOffset[1] = 2;
+ bandOffset[2] = 1;
+ bandOffset[3] = 0;
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ tile[i][j] = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, 8, 8 , 32, 4, bandOffset, null);
+ }
+ }
+
+ // tile {-2, -1}
+ byte[] byteData = ((DataBufferByte)tile[0][0].getDataBuffer()).getData();
+ for (i=4, k = 8 * 4 * 4+4 * 4;i < 8;i++, k+= 16){
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)cc;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+
+ // tile {-1, -1}
+ byteData = ((DataBufferByte)tile[1][0].getDataBuffer()).getData();
+ for (i=4, k = 8 * 4 * 4;i < 8;i++){
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)cc;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+
+ // tile {1, -1}
+ byteData = ((DataBufferByte)tile[2][0].getDataBuffer()).getData();
+ for (i=4, k = 8 * 4 * 4;i < 8;i++, k+= 16){
+ for (j=0;j < 4;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+
+ // tile {-2, 0}
+ byteData = ((DataBufferByte)tile[0][1].getDataBuffer()).getData();
+ for (i=0, k = 16;i < 4;i++, k+=16){
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)cc;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+ for (i=4, k = 8*4*4+16;i < 8;i++, k+=16){
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)0 ;
+ }
+ }
+ // tile {-1, 0}
+ byteData = ((DataBufferByte)tile[1][1].getDataBuffer()).getData();
+ for (i=0, k = 0;i < 4;i++){
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)cc;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+ for (i=0, k = 8 * 4 * 4;i < 4;i++){
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)0 ;
+ }
+
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)cc ;
+ }
+
+ }
+
+
+ // tile {0, 0}
+ byteData = ((DataBufferByte)tile[2][1].getDataBuffer()).getData();
+ for (i=0, k = 0;i < 4;i++, k+= 16) {
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+ for (i=4, k = 8 * 4* 4;i < 8;i++, k+= 16) {
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+
+
+ // tile {-2, 1}
+ byteData = ((DataBufferByte)tile[0][2].getDataBuffer()).getData();
+ for (i=4, k = 16;i < 8;i++, k+= 16) {
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)0 ;
+ }
+ }
+
+
+ // tile {-1, 1}
+ byteData = ((DataBufferByte)tile[1][2].getDataBuffer()).getData();
+ for (i=0, k = 0;i < 8;i++) {
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)0 ;
+ }
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+
+
+
+ // tile {0, 1}
+ byteData = ((DataBufferByte)tile[2][2].getDataBuffer()).getData();
+ for (i=4, k = 0;i < 8;i++, k+= 16) {
+ for (j=4;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+
+ bigTile = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, 16, 16 , 64, 4, bandOffset, null);;
+ byteData = ((DataBufferByte)bigTile.getDataBuffer()).getData();
+ for (i=0, k = 0;i < 8;i++){
+ for (j=0;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)cc;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ for (;j < 16;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)0;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+ for (;i < 16;i++){
+ for (j=0;j < 8;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)0;
+ }
+ for (;j < 16;j++, k+=4){
+ byteData[k] = (byte)0;
+ byteData[k+1] = (byte)0;
+ byteData[k+2] = (byte)cc;
+ byteData[k+3] = (byte)cc ;
+ }
+ }
+ checkBoard = new BufferedImage(colorModel, bigTile, false, null);
+ }
+
+
+
+ // create four tiles {r, g, b, y}
+ public WritableRaster copyData(WritableRaster raster) {
+ return checkBoard.copyData(raster);
+ }
+
+ public ColorModel getColorModel() {
+ return checkBoard.getColorModel();
+ }
+
+ public Raster getData() {
+ return checkBoard.getData();
+ }
+
+ public Raster getData(Rectangle rect) {
+ return checkBoard.getData(rect);
+ }
+
+ public int getHeight() {
+ return 16;
+ }
+
+ public int getMinTileX() {
+ return minX;
+ }
+
+ public int getMinTileY() {
+ return minY;
+ }
+
+ public int getMinX () {
+ return -8;
+ }
+
+ public int getMinY () {
+ return -8;
+ }
+
+ public int getNumXTiles() {
+ return 3;
+ }
+
+ public int getNumYTiles() {
+ return 3;
+ }
+
+ public Object getProperty(String name) {
+ return checkBoard.getProperty(name);
+ }
+
+ public String[] getPropertyNames() {
+ return checkBoard.getPropertyNames();
+ }
+
+
+ public SampleModel getSampleModel() {
+ return checkBoard.getSampleModel();
+ }
+
+ public Vector getSources() {
+ return null;
+ }
+
+ public Raster getTile(int tileX, int tileY) {
+ return tile[tileX- minX][tileY - minY];
+ }
+
+ public int getTileGridXOffset() {
+ return 4;
+ }
+
+ public int getTileGridYOffset() {
+ return -4;
+ }
+
+
+ public int getTileHeight() {
+ return 8;
+ }
+
+
+ public int getTileWidth() {
+ return 8;
+ }
+
+ public int getWidth() {
+ return 16;
+ }
+}
+
+
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java b/src/classes/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java
new file mode 100644
index 0000000..57267eb
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java
@@ -0,0 +1,249 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_compression;
+
+import com.sun.j3d.utils.compression.* ;
+import com.sun.j3d.loaders.objectfile.ObjectFile ;
+import com.sun.j3d.loaders.ParsingErrorException ;
+import com.sun.j3d.loaders.IncorrectFormatException ;
+import com.sun.j3d.loaders.Scene ;
+import javax.media.j3d.* ;
+import java.util.* ;
+import java.net.* ;
+import java.io.* ;
+
+/**
+ * This extension of ObjectFile provides the methods setQuantization() and
+ * compress() to compress Wavefront .obj files into the format described by
+ * appendix B of the Java 3D specification.
+ */
+public class ObjectFileCompressor extends ObjectFile {
+ private GeometryCompressor compressor = null ;
+
+ public ObjectFileCompressor() {
+ super(STRIPIFY | TRIANGULATE) ;
+ compressor = new GeometryCompressor() ;
+ }
+
+ public ObjectFileCompressor(int flags) {
+ super(flags | STRIPIFY | TRIANGULATE) ;
+ compressor = new GeometryCompressor() ;
+ }
+
+ public ObjectFileCompressor(int flags, float radians) {
+ super(flags | STRIPIFY | TRIANGULATE, radians) ;
+ compressor = new GeometryCompressor() ;
+ }
+
+ public void setFlags(int flags) {
+ super.setFlags(flags | STRIPIFY | TRIANGULATE) ;
+ }
+
+ private int positionQuant = 10 ;
+ private int colorQuant = 8 ;
+ private int normalQuant = 3 ;
+
+ /**
+ * Set the position, normal, and color quantization values for compression.
+ * @param positionQuant number of bits to quantize each position's X, Y,
+ * and Z components, ranging from 1 to 16 with a default of 10
+ * @param colorQuant number of bits to quantize each color's R, G, B, and
+ * alpha components, ranging from 2 to 16 with a default of 8
+ * @param normalQuant number of bits for quantizing each normal's U and V
+ * components, ranging from 0 to 6 with a default of 3
+ */
+ public void setQuantization(int positionQuant,
+ int colorQuant,
+ int normalQuant) {
+
+ this.positionQuant = positionQuant ;
+ this.colorQuant = colorQuant ;
+ this.normalQuant = normalQuant ;
+ }
+
+ /**
+ * Compress the specified .obj file into a CompressedGeometry node
+ * component.
+ * @param objFileName String object representing the path to a .obj file
+ * @return a CompressedGeometry node component
+ */
+ public CompressedGeometry compress(String objFileName) {
+ return compressScene(getScene(objFileName)) ;
+ }
+
+ /**
+ * Compress the specified .obj file and add it to the end of an open
+ * compressed geometry file.
+ * @param objFileName String object representing the path to a .obj file
+ * @param file a currently open CompressedGeometryFile object
+ * @exception IOException - if write fails
+ */
+ public void compress(String objFileName, CompressedGeometryFile file)
+ throws IOException {
+ compressScene(getScene(objFileName), file) ;
+ }
+
+ /**
+ * Compress the specified .obj file into a CompressedGeometry node
+ * component.
+ * @param reader an open .obj file
+ * @return a CompressedGeometry node component
+ */
+ public CompressedGeometry compress(Reader reader) {
+ return compressScene(getScene(reader)) ;
+ }
+
+ /**
+ * Compress the specified .obj file and add it to the end of an open
+ * compressed geometry file.
+ * @param reader an open .obj file
+ * @param file an open CompressedGeometryFile object
+ * @exception IOException - if write fails
+ */
+ public void compress(Reader reader, CompressedGeometryFile file)
+ throws IOException {
+ compressScene(getScene(reader), file) ;
+ }
+
+ /**
+ * Compress the specified .obj file into a CompressedGeometry node
+ * component.
+ * @param url Uniform Resource Locator for the .obj file
+ * @return a CompressedGeometry node component
+ */
+ public CompressedGeometry compress(URL url) {
+ return compressScene(getScene(url)) ;
+ }
+
+ /**
+ * Compress the specified .obj file and add it to the end of an open
+ * compressed geometry file.
+ * @param url Uniform Resource Locator for the .obj file
+ * @param file a currently open CompressedGeometryFile object
+ * @exception IOException - if write fails
+ */
+ public void compress(URL url, CompressedGeometryFile file)
+ throws IOException {
+ compressScene(getScene(url), file) ;
+ }
+
+ private CompressedGeometry compressScene(Scene scene) {
+ return compressor.compress(getStream(scene)) ;
+ }
+
+ private void compressScene(Scene scene, CompressedGeometryFile file)
+ throws IOException {
+ compressor.compress(getStream(scene), file) ;
+ }
+
+ private CompressionStream getStream(Scene scene) {
+ Hashtable objs = scene.getNamedObjects() ;
+ Shape3D shapes[] = new Shape3D[objs.size()] ;
+
+ objs.values().toArray(shapes) ;
+ return new CompressionStream(positionQuant, colorQuant, normalQuant,
+ shapes) ;
+ }
+
+ private Scene getScene(String objFileName) {
+ Scene scene = null ;
+ try {
+ scene = load(objFileName) ;
+ }
+ catch (FileNotFoundException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ catch (ParsingErrorException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ catch (IncorrectFormatException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ return scene ;
+ }
+
+ private Scene getScene(Reader reader) {
+ Scene scene = null ;
+ try {
+ scene = load(reader) ;
+ }
+ catch (FileNotFoundException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ catch (ParsingErrorException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ catch (IncorrectFormatException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ return scene ;
+ }
+
+ private Scene getScene(URL url) {
+ Scene scene = null ;
+ try {
+ scene = load(url) ;
+ }
+ catch (FileNotFoundException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ catch (ParsingErrorException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ catch (IncorrectFormatException e) {
+ System.err.println(e) ;
+ System.exit(1) ;
+ }
+ return scene ;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_compression/README.txt b/src/classes/org/jdesktop/j3d/examples/geometry_compression/README.txt
new file mode 100644
index 0000000..1cab35b
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_compression/README.txt
@@ -0,0 +1,23 @@
+This directory contains example code for using compressed geometry in
+Java 3D through the com.sun.j3d.utils.compression package.
+
+Applications:
+
+ obj2cg -- takes the names of .obj files to compress followed by the name
+ of a .cg compressed geometry resource file. If the .cg file
+ doesn't exist, then an attempt is made to create it; otherwise,
+ new compressed geometry objects are appended to the end.
+
+ The .obj files are compressed and stored into the .cg file in
+ the order in which they appear in the command line, and can be
+ accessed through indices [0 .. fileCount-1]
+
+ cgview -- takes the name of a .cg file and the index of the object to
+ display, which can range from [0 .. objectCount-1]. The object
+ may rotated, scaled, and translated in response to mouse drags.
+
+
+Utility classes:
+
+ ObjectFileCompressor.java --
+ Extends ObjectFile with compression methods.
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_compression/cgview.java b/src/classes/org/jdesktop/j3d/examples/geometry_compression/cgview.java
new file mode 100644
index 0000000..2efc221
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_compression/cgview.java
@@ -0,0 +1,214 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_compression;
+
+import com.sun.j3d.utils.compression.* ;
+import com.sun.j3d.utils.behaviors.vp.* ;
+import com.sun.j3d.utils.applet.MainFrame ;
+import com.sun.j3d.utils.universe.* ;
+import javax.media.j3d.* ;
+import javax.vecmath.* ;
+import java.applet.Applet ;
+import java.awt.BorderLayout ;
+import java.awt.event.* ;
+import java.io.* ;
+
+public class cgview extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(CompressedGeometry cg) {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup() ;
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup() ;
+ Transform3D t3d = new Transform3D() ;
+ t3d.setScale(0.7) ;
+ objScale.setTransform(t3d) ;
+ objRoot.addChild(objScale) ;
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup() ;
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE) ;
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ) ;
+ objScale.addChild(objTrans) ;
+
+ // Add compressed geometry to the scene graph.
+ CompressedGeometryHeader hdr = new CompressedGeometryHeader() ;
+ cg.getCompressedGeometryHeader(hdr) ;
+
+ // There isn't really enough information in the compressed geometry
+ // header to unamiguously determine the proper rendering attributes.
+ // The bufferDataPresent field specifies whether or not normals are
+ // bundled with vertices, but the compressed buffer can still contain
+ // normals that should be lit. Assume that any surface geometry
+ // should be lit and that lines and points should not unless the
+ // header contains the NORMAL_IN_BUFFER bit.
+ Material m = new Material() ;
+ if ((hdr.bufferType == hdr.TRIANGLE_BUFFER) ||
+ ((hdr.bufferDataPresent & hdr.NORMAL_IN_BUFFER) == 1))
+ m.setLightingEnable(true) ;
+ else
+ m.setLightingEnable(false) ;
+
+ Appearance a = new Appearance() ;
+ a.setMaterial(m) ;
+
+ objTrans.addChild(new Shape3D(cg, a)) ;
+
+ // Create mouse behavior scheduling bounds.
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0) ;
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor) ;
+ bgNode.setApplicationBounds(bounds) ;
+ objRoot.addChild(bgNode) ;
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f) ;
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor) ;
+ ambientLightNode.setInfluencingBounds(bounds) ;
+ objRoot.addChild(ambientLightNode) ;
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f) ;
+ Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f) ;
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f) ;
+ Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -0.9f) ;
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction) ;
+ light1.setInfluencingBounds(bounds) ;
+ objRoot.addChild(light1) ;
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction) ;
+ light2.setInfluencingBounds(bounds) ;
+ objRoot.addChild(light2) ;
+
+ return objRoot ;
+ }
+
+ private void usage() {
+ System.out.println("Usage: cgview <.cg file> <object index>") ;
+ System.exit(0) ;
+ }
+
+ public cgview(String args[]) {
+ if (args.length < 1)
+ usage() ;
+
+ int index ;
+ if (args.length < 2)
+ index = 0 ;
+ else
+ index = Integer.parseInt(args[1]) ;
+
+ String filename = args[0] ;
+ if (filename == null)
+ usage() ;
+
+ // Read the compressed geometry.
+ CompressedGeometry cg = null ;
+ try {
+ CompressedGeometryFile cgf ;
+ cgf = new CompressedGeometryFile(filename, false) ;
+
+ if (cgf.getObjectCount() == 0) {
+ System.out.println("no objects were found in " + filename) ;
+ System.exit(0) ;
+ }
+
+ cg = cgf.read(index) ;
+ cgf.close() ;
+
+ } catch (IOException e) {
+ System.out.println(e) ;
+ System.exit(0) ;
+ }
+
+ setLayout(new BorderLayout()) ;
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ add("Center", c) ;
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph(cg) ;
+ u = new SimpleUniverse(c) ;
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene) ;
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows cgview to be run as an application
+ // as well as an applet.
+ //
+ public static void main(String[] args) {
+ new MainFrame(new cgview(args), 700, 700) ;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java b/src/classes/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java
new file mode 100644
index 0000000..e863dbc
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java
@@ -0,0 +1,73 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.geometry_compression;
+
+import com.sun.j3d.utils.compression.* ;
+import javax.media.j3d.* ;
+import java.io.* ;
+
+class obj2cg {
+
+ public static void main(String args[]) throws IOException {
+ if (args.length < 2) {
+ System.out.println
+ ("obj2cg wants the names of .obj files to compress,\n" +
+ "followed by the name of a .cg file to create or to\n" +
+ "which to append.") ;
+ System.exit(0) ;
+ }
+
+ CompressedGeometryFile file ;
+ file = new CompressedGeometryFile(args[args.length-1], true) ;
+
+ ObjectFileCompressor compressor ;
+ compressor = new ObjectFileCompressor() ;
+
+ for (int i = 0 ; i < args.length-1 ; i++)
+ compressor.compress(args[i], file) ;
+
+ file.close() ;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java
new file mode 100644
index 0000000..9841a52
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java
@@ -0,0 +1,342 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.glsl_shader;
+
+import com.sun.j3d.loaders.objectfile.ObjectFile;
+import com.sun.j3d.loaders.ParsingErrorException;
+import com.sun.j3d.loaders.IncorrectFormatException;
+import com.sun.j3d.loaders.Scene;
+import com.sun.j3d.utils.shader.StringIO;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+import java.io.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+public class ObjLoadGLSL extends Applet {
+
+ private String shaderName = "polkadot3d";
+ private boolean spin = false;
+ private boolean noTriangulate = false;
+ private boolean noStripify = false;
+ private double creaseAngle = 60.0;
+ private URL filename = null;
+ private SimpleUniverse u;
+ private BoundingSphere bounds;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.7);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(objTrans);
+
+ int flags = ObjectFile.RESIZE;
+ if (!noTriangulate) flags |= ObjectFile.TRIANGULATE;
+ if (!noStripify) flags |= ObjectFile.STRIPIFY;
+ ObjectFile f = new ObjectFile(flags,
+ (float)(creaseAngle * Math.PI / 180.0));
+ Scene s = null;
+ try {
+ s = f.load(filename);
+ }
+ catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ catch (ParsingErrorException e) {
+ throw new RuntimeException(e);
+ }
+ catch (IncorrectFormatException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Set vertex and fragment shader program for all Shape3D nodes in scene
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try {
+ vertexProgram = StringIO.readFully(shaderName + ".vert");
+ fragmentProgram = StringIO.readFully(shaderName + ".frag");
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_VERTEX,
+ vertexProgram);
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_FRAGMENT,
+ fragmentProgram);
+ ShaderProgram shaderProgram = new GLSLShaderProgram();
+ shaderProgram.setShaders(shaders);
+ setShaderProgram(s.getSceneGroup(), shaderProgram);
+
+ objTrans.addChild(s.getSceneGroup());
+
+ bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ if (spin) {
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+ }
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objRoot.addChild(bgNode);
+
+ return objRoot;
+ }
+
+ private void usage()
+ {
+ System.out.println(
+ "Usage: java ObjLoadGLSL [-s] [-S shaderName] [-n] [-t] [-c degrees] <.obj file>");
+ System.out.println(" -s Spin (no user interaction)");
+ System.out.println(" -S Set shader name (default is 'simple')");
+ System.out.println(" -n No triangulation");
+ System.out.println(" -t No stripification");
+ System.out.println(
+ " -c Set crease angle for normal generation (default is 60 without");
+ System.out.println(
+ " smoothing group info, otherwise 180 within smoothing groups)");
+ System.exit(0);
+ } // End of usage
+
+
+
+ public void init() {
+ if (filename == null) {
+ // Applet
+ try {
+ URL path = getCodeBase();
+ filename = new URL(path.toString() + "./galleon.obj");
+ }
+ catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ PlatformGeometry pg = new PlatformGeometry();
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ pg.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 0.2f, 0.4f);
+ Vector3f light1Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light2Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ pg.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ pg.addChild(light2);
+
+ viewingPlatform.setPlatformGeometry( pg );
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ if (!spin) {
+ OrbitBehavior orbit = new OrbitBehavior(c,
+ OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+ }
+
+ /*
+ // Limit the frame rate to 100 Hz
+ u.getViewer().getView().setMinimumFrameCycleTime(10);
+ */
+
+ u.addBranchGraph(scene);
+ }
+
+ // Set shader program for all nodes in specified branch graph
+ private void setShaderProgram(BranchGroup g, ShaderProgram shaderProgram) {
+ ShaderAppearance myApp = new ShaderAppearance();
+ Material mat = new Material();
+ myApp.setShaderProgram(shaderProgram);
+ myApp.setMaterial(mat);
+ setShaderProgram(g, myApp);
+ }
+
+ // Recursively set shader program for all children of specified group
+ private void setShaderProgram(Group g,
+ ShaderAppearance myApp) {
+
+ Enumeration e = g.getAllChildren();
+ while (e.hasMoreElements()) {
+ Node n = (Node)(e.nextElement());
+ if (n instanceof Group) {
+ setShaderProgram((Group)n, myApp);
+ }
+ else if (n instanceof Shape3D) {
+ Shape3D s = (Shape3D)n;
+ s.setAppearance(myApp);
+ }
+ }
+ }
+
+ // Caled if running as a program
+ public ObjLoadGLSL(String[] args) {
+ if (args.length != 0) {
+ for (int i = 0 ; i < args.length ; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].equals("-s")) {
+ spin = true;
+ } else if (args[i].equals("-n")) {
+ noTriangulate = true;
+ } else if (args[i].equals("-t")) {
+ noStripify = true;
+ } else if (args[i].equals("-c")) {
+ if (i < args.length - 1) {
+ creaseAngle = (new Double(args[++i])).doubleValue();
+ } else usage();
+ } else if (args[i].equals("-S")) {
+ if (i < args.length - 1) {
+ shaderName = args[++i];
+ } else usage();
+ } else {
+ usage();
+ }
+ } else {
+ try {
+ if ((args[i].indexOf("file:") == 0) ||
+ (args[i].indexOf("http") == 0)) {
+ filename = new URL(args[i]);
+ }
+ else if (args[i].charAt(0) != '/') {
+ filename = new URL("file:./" + args[i]);
+ }
+ else {
+ filename = new URL("file:" + args[i]);
+ }
+ }
+ catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ // Running as an applet
+ public ObjLoadGLSL() {
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+
+ //
+ // The following allows ObjLoadGLSL to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new ObjLoadGLSL(args), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form b/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form
new file mode 100644
index 0000000..dcccf73
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <NonVisualComponents>
+ <Component class="javax.swing.ButtonGroup" name="shaderButtonGroup">
+ </Component>
+ <Menu class="javax.swing.JMenuBar" name="jMenuBar1">
+ <SubComponents>
+ <Menu class="javax.swing.JMenu" name="fileMenu">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="File"/>
+ </Properties>
+ <SubComponents>
+ <MenuItem class="javax.swing.JMenuItem" name="exitMenuItem">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Exit"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exitMenuItemActionPerformed"/>
+ </Events>
+ </MenuItem>
+ </SubComponents>
+ </Menu>
+ </SubComponents>
+ </Menu>
+ </NonVisualComponents>
+ <Properties>
+ <Property name="defaultCloseOperation" type="int" value="3"/>
+ <Property name="title" type="java.lang.String" value="Phong Shading Test"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="menuBar" type="java.lang.String" value="jMenuBar1"/>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="guiPanel">
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="North"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="jPanel1">
+ <Properties>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+ <TitledBorder title="Shader"/>
+ </Border>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="4" insetsRight="4" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JRadioButton" name="gouraudButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="shaderButtonGroup"/>
+ </Property>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String" value="Per-Vertex Lighting (Gouraud)"/>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
+ <EmptyBorder bottom="0" left="0" right="0" top="0"/>
+ </Border>
+ </Property>
+ <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
+ <Insets value="[0, 0, 0, 0]"/>
+ </Property>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="gouraudButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="2" insetsBottom="2" insetsRight="2" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JRadioButton" name="phongButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="shaderButtonGroup"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Per-Pixel Lighting (Phong)"/>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
+ <EmptyBorder bottom="0" left="0" right="0" top="0"/>
+ </Border>
+ </Property>
+ <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
+ <Insets value="[0, 0, 0, 0]"/>
+ </Property>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="phongButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="2" insetsBottom="2" insetsRight="2" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JPanel" name="drawingPanel">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[500, 500]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java b/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java
new file mode 100644
index 0000000..4f93a77
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java
@@ -0,0 +1,450 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.glsl_shader;
+
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.shader.StringIO;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.GraphicsConfiguration;
+import java.io.IOException;
+
+/**
+ *
+ * @author kcr
+ */
+public class PhongShadingGLSL extends javax.swing.JFrame {
+
+ // Constants for type of light to use
+ private static final int DIRECTIONAL_LIGHT = 0;
+ private static final int POINT_LIGHT = 1;
+ private static final int SPOT_LIGHT = 2;
+
+ // Flag indicates type of lights: directional, point, or spot lights.
+ private static int lightType = DIRECTIONAL_LIGHT;
+
+ private SimpleUniverse u = null;
+
+ private ShaderAppearance sApp = null;
+ private ShaderProgram gouraudSP = null;
+ private ShaderProgram phongSP = null;
+
+ public BranchGroup createSceneGraph() {
+ Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f);
+// Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f);
+// Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f lColor1 = new Color3f(1.0f, 1.0f, 0.5f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+
+ Transform3D t;
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.5);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objRoot.addChild(bg);
+
+ // Create the TransformGroup node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at run time. Add it to
+ // the root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(objTrans);
+
+ // Create a Sphere object, generate one copy of the sphere,
+ // and add it into the scene graph.
+ sApp = new ShaderAppearance();
+ sApp.setCapability(ShaderAppearance.ALLOW_SHADER_PROGRAM_WRITE);
+ Material m = new Material(objColor, eColor, objColor, sColor, 100.0f);
+ sApp.setMaterial(m);
+
+ // Create Gouraud and Phong shader programs
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ Shader[] shaders = new Shader[2];
+ String[] attrNames = { "numLights" };
+
+ try {
+ vertexProgram = StringIO.readFully("./gouraud.vert");
+ fragmentProgram = StringIO.readFully("./gouraud.frag");
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_VERTEX,
+ vertexProgram);
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_FRAGMENT,
+ fragmentProgram);
+ gouraudSP = new GLSLShaderProgram();
+ gouraudSP.setShaders(shaders);
+
+ try {
+ vertexProgram = StringIO.readFully("./phong.vert");
+ fragmentProgram = StringIO.readFully("./phong.frag");
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_VERTEX,
+ vertexProgram);
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_FRAGMENT,
+ fragmentProgram);
+ phongSP = new GLSLShaderProgram();
+ phongSP.setShaders(shaders);
+
+ if (gouraudButton.isSelected()) {
+ sApp.setShaderProgram(gouraudSP);
+ } else if (phongButton.isSelected()) {
+ sApp.setShaderProgram(phongSP);
+ }
+ Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS, 30, sApp);
+ objTrans.addChild(sph);
+
+ // Create a new Behavior object that will perform the
+ // desired operation on the specified transform and add
+ // it into the scene graph.
+ Transform3D yAxis = new Transform3D();
+ yAxis.rotZ(Math.PI);
+ Alpha rotationAlpha = new Alpha(-1, 10000);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objRoot.addChild(rotator);
+
+ // Create the transform group node for the each light and initialize
+ // it to the identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add them to the root
+ // of the subgraph.
+ TransformGroup l1RotTrans = new TransformGroup();
+ l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(l1RotTrans);
+
+ TransformGroup l2RotTrans = new TransformGroup();
+ l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(l2RotTrans);
+
+ // Create transformations for the positional lights
+ t = new Transform3D();
+ Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0);
+ t.set(lPos1);
+ TransformGroup l1Trans = new TransformGroup(t);
+ l1RotTrans.addChild(l1Trans);
+
+// t = new Transform3D();
+// Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0);
+// t.set(lPos2);
+// TransformGroup l2Trans = new TransformGroup(t);
+// l2RotTrans.addChild(l2Trans);
+
+ // Create Geometry for point lights
+ ColoringAttributes caL1 = new ColoringAttributes();
+// ColoringAttributes caL2 = new ColoringAttributes();
+ caL1.setColor(lColor1);
+// caL2.setColor(lColor2);
+ Appearance appL1 = new Appearance();
+// Appearance appL2 = new Appearance();
+ appL1.setColoringAttributes(caL1);
+// appL2.setColoringAttributes(caL2);
+ l1Trans.addChild(new Sphere(0.05f, appL1));
+// l2Trans.addChild(new Sphere(0.05f, appL2));
+
+ // Create lights
+ AmbientLight aLgt = new AmbientLight(alColor);
+
+ Light lgt1 = null;
+// Light lgt2 = null;
+
+ Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f atten = new Point3f(1.0f, 0.0f, 0.0f);
+ Vector3f lDirect1 = new Vector3f(lPos1);
+// Vector3f lDirect2 = new Vector3f(lPos2);
+ lDirect1.negate();
+// lDirect2.negate();
+
+ switch (lightType) {
+ case DIRECTIONAL_LIGHT:
+ lgt1 = new DirectionalLight(lColor1, lDirect1);
+// lgt2 = new DirectionalLight(lColor2, lDirect2);
+ break;
+ case POINT_LIGHT:
+ assert false : "can't get here";
+ lgt1 = new PointLight(lColor1, lPoint, atten);
+// lgt2 = new PointLight(lColor2, lPoint, atten);
+ break;
+ case SPOT_LIGHT:
+ assert false : "can't get here";
+ lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1,
+ 25.0f * (float)Math.PI / 180.0f, 10.0f);
+// lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2,
+// 25.0f * (float)Math.PI / 180.0f, 10.0f);
+ break;
+ }
+
+ // Set the influencing bounds
+ aLgt.setInfluencingBounds(bounds);
+ lgt1.setInfluencingBounds(bounds);
+// lgt2.setInfluencingBounds(bounds);
+
+ // Add the lights into the scene graph
+ objScale.addChild(aLgt);
+ l1Trans.addChild(lgt1);
+// l2Trans.addChild(lgt2);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ yAxis = new Transform3D();
+ Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator1 =
+ new RotationInterpolator(rotor1Alpha,
+ l1RotTrans,
+ yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator1.setSchedulingBounds(bounds);
+ l1RotTrans.addChild(rotator1);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Alpha rotor2Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 1000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator2 =
+ new RotationInterpolator(rotor2Alpha,
+ l2RotTrans,
+ yAxis,
+ 0.0f, 0.0f);
+ bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator2.setSchedulingBounds(bounds);
+ l2RotTrans.addChild(rotator2);
+
+ return objRoot;
+ }
+
+ private Canvas3D initScene() {
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ BranchGroup scene = createSceneGraph();
+ u.addBranchGraph(scene);
+
+ return c;
+ }
+
+ /**
+ * Creates new form PhongShadingGLSL
+ */
+ public PhongShadingGLSL() {
+ // Initialize the GUI components
+ initComponents();
+
+ // Create the scene and add the Canvas3D to the drawing panel
+ Canvas3D c = initScene();
+ drawingPanel.add(c, java.awt.BorderLayout.CENTER);
+ }
+
+ // ----------------------------------------------------------------
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ shaderButtonGroup = new javax.swing.ButtonGroup();
+ guiPanel = new javax.swing.JPanel();
+ jPanel1 = new javax.swing.JPanel();
+ gouraudButton = new javax.swing.JRadioButton();
+ phongButton = new javax.swing.JRadioButton();
+ drawingPanel = new javax.swing.JPanel();
+ jMenuBar1 = new javax.swing.JMenuBar();
+ fileMenu = new javax.swing.JMenu();
+ exitMenuItem = new javax.swing.JMenuItem();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("Phong Shading Test");
+ guiPanel.setLayout(new java.awt.GridBagLayout());
+
+ jPanel1.setLayout(new java.awt.GridBagLayout());
+
+ jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Shader"));
+ shaderButtonGroup.add(gouraudButton);
+ gouraudButton.setSelected(true);
+ gouraudButton.setText("Per-Vertex Lighting (Gouraud)");
+ gouraudButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ gouraudButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
+ gouraudButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ gouraudButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
+ jPanel1.add(gouraudButton, gridBagConstraints);
+
+ shaderButtonGroup.add(phongButton);
+ phongButton.setText("Per-Pixel Lighting (Phong)");
+ phongButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ phongButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
+ phongButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ phongButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
+ jPanel1.add(phongButton, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
+ guiPanel.add(jPanel1, gridBagConstraints);
+
+ getContentPane().add(guiPanel, java.awt.BorderLayout.NORTH);
+
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(500, 500));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ fileMenu.setText("File");
+ exitMenuItem.setText("Exit");
+ exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ exitMenuItemActionPerformed(evt);
+ }
+ });
+
+ fileMenu.add(exitMenuItem);
+
+ jMenuBar1.add(fileMenu);
+
+ setJMenuBar(jMenuBar1);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void phongButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_phongButtonActionPerformed
+ sApp.setShaderProgram(phongSP);
+ }//GEN-LAST:event_phongButtonActionPerformed
+
+ private void gouraudButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gouraudButtonActionPerformed
+ sApp.setShaderProgram(gouraudSP);
+ }//GEN-LAST:event_gouraudButtonActionPerformed
+
+ private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
+ System.exit(0);
+ }//GEN-LAST:event_exitMenuItemActionPerformed
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new PhongShadingGLSL().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+ private javax.swing.JMenuItem exitMenuItem;
+ private javax.swing.JMenu fileMenu;
+ private javax.swing.JRadioButton gouraudButton;
+ private javax.swing.JPanel guiPanel;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JRadioButton phongButton;
+ private javax.swing.ButtonGroup shaderButtonGroup;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form
new file mode 100644
index 0000000..714273d
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.2" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <NonVisualComponents>
+ <Component class="javax.swing.ButtonGroup" name="densityButtonGroup">
+ </Component>
+ <Component class="javax.swing.ButtonGroup" name="colorButtonGroup">
+ </Component>
+ <Component class="javax.swing.ButtonGroup" name="sceneGraphButtonGroup">
+ </Component>
+ <Menu class="javax.swing.JMenuBar" name="jMenuBar1">
+ <SubComponents>
+ <Menu class="javax.swing.JMenu" name="fileMenu">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="File"/>
+ </Properties>
+ <SubComponents>
+ <MenuItem class="javax.swing.JMenuItem" name="exitMenuItem">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Exit"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exitMenuItemActionPerformed"/>
+ </Events>
+ </MenuItem>
+ </SubComponents>
+ </Menu>
+ </SubComponents>
+ </Menu>
+ </NonVisualComponents>
+ <Properties>
+ <Property name="title" type="java.lang.String" value="Window Title"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="menuBar" type="java.lang.String" value="jMenuBar1"/>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <Events>
+ <EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="exitForm"/>
+ </Events>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-85,0,0,2,0"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="mainPanel">
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="guiPanel">
+ <Properties>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
+ <LineBorder/>
+ </Border>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="North"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="densityPanel">
+ <Properties>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+ <TitledBorder title="Density"/>
+ </Border>
+ </Property>
+ </Properties>
+ <AccessibilityProperties>
+ <Property name="AccessibleContext.accessibleName" type="java.lang.String" value="ShaderAttributeValue &#xa;"/>
+ </AccessibilityProperties>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JRadioButton" name="zeroButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="densityButtonGroup"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Zero"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="zeroButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JRadioButton" name="halfButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="densityButtonGroup"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Half"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="halfButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JRadioButton" name="fullButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="densityButtonGroup"/>
+ </Property>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String" value="Full"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="fullButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JPanel" name="colorPanel">
+ <Properties>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+ <TitledBorder title="Color"/>
+ </Border>
+ </Property>
+ </Properties>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JRadioButton" name="goldButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="colorButtonGroup"/>
+ </Property>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String" value="Gold"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="goldButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JRadioButton" name="silverButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="colorButtonGroup"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Silver"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="silverButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JPanel" name="sceneGraphPanel">
+ <Properties>
+ <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+ <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+ <TitledBorder title="Scene Graph"/>
+ </Border>
+ </Property>
+ </Properties>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JToggleButton" name="DetachButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="sceneGraphButtonGroup"/>
+ </Property>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String" value="Detach"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="DetachButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JToggleButton" name="AttachButton">
+ <Properties>
+ <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+ <ComponentRef name="sceneGraphButtonGroup"/>
+ </Property>
+ <Property name="text" type="java.lang.String" value="Create"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="AttachButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JButton" name="replaceSPButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Replace Shader"/>
+ <Property name="enabled" type="boolean" value="false"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="replaceSPButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JPanel" name="drawingPanel">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[500, 500]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ </Container>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java
new file mode 100644
index 0000000..ba4e0f6
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java
@@ -0,0 +1,668 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.glsl_shader;
+
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.shader.StringIO;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.GraphicsConfiguration;
+import java.io.IOException;
+
+public class ShaderTestGLSL extends javax.swing.JFrame {
+
+ static final int GOLD = 1;
+ static final int SILVER = 2;
+
+ static final int DIMPLE_SHADER = 1;
+ static final int BRICK_SHADER = 2;
+ static final int WOOD_SHADER = 3;
+ static final int POLKADOT3D_SHADER = 4;
+
+ static final String[] shaderAttrNames1 = {
+ "Density", "Size", "LightPosition", "Color"
+ };
+
+ static final String[] shaderAttrNames2 = {
+ "BrickColor", "LightPosition"
+ };
+
+ private SimpleUniverse u = null;
+ private View view;
+ private BranchGroup transpObj;
+ private BranchGroup scene = null;
+ private int shaderSelected = DIMPLE_SHADER;
+ private float density = 16.0f;
+ private int color = GOLD;
+
+ private Color3f eColor = new Color3f(0.2f, 0.2f, 0.2f);
+ private Color3f sColor = new Color3f(0.8f, 0.8f, 0.8f);
+ private Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f);
+ private Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+ private Color3f gold = new Color3f(0.7f, 0.6f, 0.18f);
+ private Color3f silver = new Color3f(0.75f, 0.75f, 0.75f);
+
+ // Handlers for doing update
+ private ShaderAppearance sApp1 = null;
+ private ShaderAppearance sApp2 = null;
+ private ShaderAppearance sApp3 = null;
+ private ShaderAppearance sApp4 = null;
+ private ShaderProgram sp1 = null;
+ private ShaderProgram sp2 = null;
+ private ShaderProgram sp3 = null;
+ private ShaderProgram sp4 = null;
+ private ShaderAttributeSet sas1 = null;
+ private ShaderAttributeSet sas2 = null;
+ private ShaderAttributeObject sao1 = null;
+ private ShaderAttributeObject sao2 = null;
+ private Sphere sphere = null;
+ private Shape3D s3d = null;
+
+ private Material createMaterial() {
+ Material m;
+ m = new Material(objColor, eColor, objColor, sColor, 100.0f);
+ m.setLightingEnable(true);
+ return m;
+ }
+
+ private ShaderProgram createGLSLShaderProgram(int index) {
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try {
+ switch (index) {
+ case DIMPLE_SHADER:
+ vertexProgram = StringIO.readFully("./dimple.vert");
+ fragmentProgram = StringIO.readFully("./dimple.frag");
+ break;
+ case BRICK_SHADER:
+ vertexProgram = StringIO.readFully("./aabrick.vert");
+ fragmentProgram = StringIO.readFully("./aabrick.frag");
+ break;
+ case WOOD_SHADER:
+ vertexProgram = StringIO.readFully("./wood.vert");
+ fragmentProgram = StringIO.readFully("./wood.frag");
+ break;
+ case POLKADOT3D_SHADER:
+ vertexProgram = StringIO.readFully("./polkadot3d.vert");
+ fragmentProgram = StringIO.readFully("./polkadot3d.frag");
+ break;
+ default:
+ }
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_VERTEX,
+ vertexProgram);
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_FRAGMENT,
+ fragmentProgram);
+ ShaderProgram shaderProgram = new GLSLShaderProgram();
+ shaderProgram.setShaders(shaders);
+ return shaderProgram;
+ }
+
+ private ShaderAttributeSet createShaderAttributeSet(int index) {
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ ShaderAttributeObject shaderAttribute = null;
+
+ switch (index) {
+ case DIMPLE_SHADER:
+ // "Density", "Size", "Scale", "Color", "LightPosition"
+ shaderAttribute = new ShaderAttributeValue("Size", new Float(0.25));
+ shaderAttributeSet.put(shaderAttribute);
+ shaderAttribute = new ShaderAttributeValue("LightPosition",
+ new Point3f(0.0f, 0.0f, 0.5f));
+ shaderAttributeSet.put(shaderAttribute);
+
+ sao1 = new ShaderAttributeValue("Density", new Float(density));
+ sao1.setCapability(ShaderAttributeObject.ALLOW_VALUE_READ);
+ sao1.setCapability(ShaderAttributeObject.ALLOW_VALUE_WRITE);
+ shaderAttributeSet.put(sao1);
+
+ if(color == GOLD) {
+ sao2 = new ShaderAttributeValue("Color", gold);
+ }
+ else if (color == SILVER) {
+ sao2 = new ShaderAttributeValue("Color", silver);
+ }
+ sao2.setCapability(ShaderAttributeObject.ALLOW_VALUE_READ);
+ sao2.setCapability(ShaderAttributeObject.ALLOW_VALUE_WRITE);
+ shaderAttributeSet.put(sao2);
+ break;
+
+ case BRICK_SHADER:
+ // "BrickColor", "LightPosition"
+ shaderAttribute = new ShaderAttributeValue("BrickColor",
+ new Color3f(1.0f, 0.3f, 0.2f));
+ shaderAttributeSet.put(shaderAttribute);
+ shaderAttribute = new ShaderAttributeValue("LightPosition",
+ new Point3f(0.0f, 0.0f, 0.5f));
+ shaderAttributeSet.put(shaderAttribute);
+ break;
+ default:
+ assert false;
+ }
+ return shaderAttributeSet;
+ }
+
+ private ShaderAppearance createShaderAppearance() {
+ ShaderAppearance sApp = new ShaderAppearance();
+ sApp.setMaterial(createMaterial());
+ return sApp;
+ }
+
+
+ private BranchGroup createSubSceneGraph() {
+ // Create the sub-root of the branch graph
+ BranchGroup subRoot = new BranchGroup();
+
+ //
+ // Create 1 spheres with a GLSLShader and add it into the scene graph.
+ //
+ sApp1 = createShaderAppearance();
+ sApp1.setCapability(ShaderAppearance.ALLOW_SHADER_PROGRAM_READ);
+ sApp1.setCapability(ShaderAppearance.ALLOW_SHADER_PROGRAM_WRITE);
+ sApp1.setCapability(ShaderAppearance.ALLOW_SHADER_ATTRIBUTE_SET_READ);
+ sApp1.setCapability(ShaderAppearance.ALLOW_SHADER_ATTRIBUTE_SET_WRITE);
+
+ sp1 = createGLSLShaderProgram(1);
+ sp1.setShaderAttrNames(shaderAttrNames1);
+ sas1 = createShaderAttributeSet(1);
+ sas1.setCapability(ShaderAttributeSet.ALLOW_ATTRIBUTES_READ);
+ sas1.setCapability(ShaderAttributeSet.ALLOW_ATTRIBUTES_WRITE);
+ sApp1.setShaderProgram(sp1);
+ sApp1.setShaderAttributeSet(sas1);
+
+ // Setup Brick shader
+ sp2 = createGLSLShaderProgram(2);
+ sp2.setShaderAttrNames(shaderAttrNames2);
+ sas2 = createShaderAttributeSet(2);
+ sApp2 = createShaderAppearance();
+ sApp2.setShaderProgram(sp2);
+ sApp2.setShaderAttributeSet(sas2);
+
+ // Setup Wood shader
+ sp3 = createGLSLShaderProgram(3);
+ sApp3 = createShaderAppearance();
+ sApp3.setShaderProgram(sp3);
+
+ // Setup Polkadot3d shader
+ sp4 = createGLSLShaderProgram(4);
+ sApp4 = createShaderAppearance();
+ sApp4.setShaderProgram(sp4);
+
+ sphere = new Sphere(1.5f, Sphere.GENERATE_NORMALS, 200, null);
+ s3d = (Shape3D)sphere.getShape();
+ s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ s3d.setAppearance(sApp1);
+
+ TransformGroup objTG;
+ Transform3D t = new Transform3D();
+ t.set(new Vector3d(0.0, 0.0, 0.0));
+ objTG = new TransformGroup(t);
+ objTG.addChild(sphere);
+ subRoot.addChild(objTG);
+
+ return subRoot;
+ }
+
+ private BranchGroup createSceneGraph(int selectedScene) {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+ objRoot.setCapability(BranchGroup.ALLOW_DETACH);
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ objScale.addChild(createSubSceneGraph());
+
+ // Create a position interpolator and attach it to the view
+ // platform
+ TransformGroup vpTrans =
+ u.getViewingPlatform().getViewPlatformTransform();
+ Transform3D axisOfTranslation = new Transform3D();
+ Alpha transAlpha = new Alpha(-1,
+ Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 5000, 0, 0,
+ 5000, 0, 0);
+ axisOfTranslation.rotY(-Math.PI/2.0);
+ PositionInterpolator translator =
+ new PositionInterpolator(transAlpha,
+ vpTrans,
+ axisOfTranslation,
+ 2.0f, 3.5f);
+ translator.setSchedulingBounds(bounds);
+ objScale.addChild(translator);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ private Canvas3D initScene() {
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ u = new SimpleUniverse(c);
+
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ view = u.getViewer().getView();
+
+ return c;
+ }
+
+ /**
+ * Creates new form ShaderTestGLSL
+ */
+ public ShaderTestGLSL() {
+ // Initialize the GUI components
+ initComponents();
+
+ // Create the scene and add the Canvas3D to the drawing panel
+ Canvas3D c = initScene();
+ drawingPanel.add(c, java.awt.BorderLayout.CENTER);
+ }
+
+
+ // ----------------------------------------------------------------
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ densityButtonGroup = new javax.swing.ButtonGroup();
+ colorButtonGroup = new javax.swing.ButtonGroup();
+ sceneGraphButtonGroup = new javax.swing.ButtonGroup();
+ mainPanel = new javax.swing.JPanel();
+ guiPanel = new javax.swing.JPanel();
+ densityPanel = new javax.swing.JPanel();
+ zeroButton = new javax.swing.JRadioButton();
+ halfButton = new javax.swing.JRadioButton();
+ fullButton = new javax.swing.JRadioButton();
+ colorPanel = new javax.swing.JPanel();
+ goldButton = new javax.swing.JRadioButton();
+ silverButton = new javax.swing.JRadioButton();
+ sceneGraphPanel = new javax.swing.JPanel();
+ DetachButton = new javax.swing.JToggleButton();
+ AttachButton = new javax.swing.JToggleButton();
+ replaceSPButton = new javax.swing.JButton();
+ drawingPanel = new javax.swing.JPanel();
+ jMenuBar1 = new javax.swing.JMenuBar();
+ fileMenu = new javax.swing.JMenu();
+ exitMenuItem = new javax.swing.JMenuItem();
+
+ setTitle("Window Title");
+ addWindowListener(new java.awt.event.WindowAdapter() {
+ public void windowClosing(java.awt.event.WindowEvent evt) {
+ exitForm(evt);
+ }
+ });
+
+ mainPanel.setLayout(new java.awt.BorderLayout());
+
+ guiPanel.setLayout(new javax.swing.BoxLayout(guiPanel, javax.swing.BoxLayout.X_AXIS));
+
+ guiPanel.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
+ densityPanel.setLayout(new java.awt.GridBagLayout());
+
+ densityPanel.setBorder(new javax.swing.border.TitledBorder("Density"));
+ densityButtonGroup.add(zeroButton);
+ zeroButton.setText("Zero");
+ zeroButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ zeroButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ densityPanel.add(zeroButton, gridBagConstraints);
+
+ densityButtonGroup.add(halfButton);
+ halfButton.setText("Half");
+ halfButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ halfButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ densityPanel.add(halfButton, gridBagConstraints);
+
+ densityButtonGroup.add(fullButton);
+ fullButton.setSelected(true);
+ fullButton.setText("Full");
+ fullButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ fullButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ densityPanel.add(fullButton, gridBagConstraints);
+
+ guiPanel.add(densityPanel);
+ densityPanel.getAccessibleContext().setAccessibleName("ShaderAttributeValue \n");
+
+ colorPanel.setLayout(new java.awt.GridBagLayout());
+
+ colorPanel.setBorder(new javax.swing.border.TitledBorder("Color"));
+ colorButtonGroup.add(goldButton);
+ goldButton.setSelected(true);
+ goldButton.setText("Gold");
+ goldButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ goldButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ colorPanel.add(goldButton, gridBagConstraints);
+
+ colorButtonGroup.add(silverButton);
+ silverButton.setText("Silver");
+ silverButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ silverButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ colorPanel.add(silverButton, gridBagConstraints);
+
+ guiPanel.add(colorPanel);
+
+ sceneGraphPanel.setLayout(new java.awt.GridBagLayout());
+
+ sceneGraphPanel.setBorder(new javax.swing.border.TitledBorder("Scene Graph"));
+ sceneGraphButtonGroup.add(DetachButton);
+ DetachButton.setSelected(true);
+ DetachButton.setText("Detach");
+ DetachButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ DetachButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ sceneGraphPanel.add(DetachButton, gridBagConstraints);
+
+ sceneGraphButtonGroup.add(AttachButton);
+ AttachButton.setText("Create");
+ AttachButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ AttachButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ sceneGraphPanel.add(AttachButton, gridBagConstraints);
+
+ replaceSPButton.setText("Replace Shader");
+ replaceSPButton.setEnabled(false);
+ replaceSPButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ replaceSPButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ sceneGraphPanel.add(replaceSPButton, gridBagConstraints);
+
+ guiPanel.add(sceneGraphPanel);
+
+ mainPanel.add(guiPanel, java.awt.BorderLayout.NORTH);
+
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(500, 500));
+ mainPanel.add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ getContentPane().add(mainPanel, java.awt.BorderLayout.CENTER);
+
+ fileMenu.setText("File");
+ exitMenuItem.setText("Exit");
+ exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ exitMenuItemActionPerformed(evt);
+ }
+ });
+
+ fileMenu.add(exitMenuItem);
+
+ jMenuBar1.add(fileMenu);
+
+ setJMenuBar(jMenuBar1);
+
+ pack();
+ }
+ // </editor-fold>//GEN-END:initComponents
+
+ private void silverButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_silverButtonActionPerformed
+ color = SILVER;
+ if(scene != null) {
+ sao2.setValue(silver);
+ }
+ }//GEN-LAST:event_silverButtonActionPerformed
+
+ private void goldButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goldButtonActionPerformed
+ color = GOLD;
+ if(scene != null) {
+ sao2.setValue(gold);
+ }
+ }//GEN-LAST:event_goldButtonActionPerformed
+
+ private void replaceSPButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_replaceSPButtonActionPerformed
+ if (shaderSelected != DIMPLE_SHADER) {
+ goldButton.setEnabled(false);
+ silverButton.setEnabled(false);
+ zeroButton.setEnabled(false);
+ halfButton.setEnabled(false);
+ fullButton.setEnabled(false);
+ }
+
+ switch(shaderSelected) {
+ case DIMPLE_SHADER:
+ s3d.setAppearance(sApp1);
+ goldButton.setEnabled(true);
+ silverButton.setEnabled(true);
+ zeroButton.setEnabled(true);
+ halfButton.setEnabled(true);
+ fullButton.setEnabled(true);
+ shaderSelected = BRICK_SHADER;
+ break;
+ case BRICK_SHADER:
+ s3d.setAppearance(sApp2);
+ shaderSelected = WOOD_SHADER;
+ break;
+ case WOOD_SHADER:
+ s3d.setAppearance(sApp3);
+ shaderSelected = POLKADOT3D_SHADER;
+ break;
+ case POLKADOT3D_SHADER:
+ s3d.setAppearance(sApp4);
+ shaderSelected = DIMPLE_SHADER;
+ break;
+ default:
+ assert false;
+ }
+
+ }//GEN-LAST:event_replaceSPButtonActionPerformed
+
+ private void fullButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fullButtonActionPerformed
+ density = 16.0f;
+ if (scene != null) {
+ sao1.setValue(new Float(density));
+ }
+ }//GEN-LAST:event_fullButtonActionPerformed
+
+ private void DetachButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DetachButtonActionPerformed
+ if (scene != null) {
+ scene.detach();
+ scene = null;
+ replaceSPButton.setEnabled(false);
+ goldButton.setEnabled(true);
+ silverButton.setEnabled(true);
+ zeroButton.setEnabled(true);
+ halfButton.setEnabled(true);
+ fullButton.setEnabled(true);
+ shaderSelected = DIMPLE_SHADER;
+ }
+ }//GEN-LAST:event_DetachButtonActionPerformed
+
+ private void AttachButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AttachButtonActionPerformed
+ if (scene == null) {
+ scene = createSceneGraph(1);
+ u.addBranchGraph(scene);
+ replaceSPButton.setEnabled(true);
+ shaderSelected = BRICK_SHADER;
+ }
+ }//GEN-LAST:event_AttachButtonActionPerformed
+
+ private void halfButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_halfButtonActionPerformed
+ density = 8.0f;
+ if(scene != null) {
+ sao1.setValue(new Float(density));
+ }
+ }//GEN-LAST:event_halfButtonActionPerformed
+
+ private void zeroButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zeroButtonActionPerformed
+ density = 0.0f;
+ if(scene != null) {
+ sao1.setValue(new Float(density));
+ }
+
+ }//GEN-LAST:event_zeroButtonActionPerformed
+
+ private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
+ System.exit(0);
+ }//GEN-LAST:event_exitMenuItemActionPerformed
+
+ /** Exit the Application */
+ private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
+ System.exit(0);
+ }//GEN-LAST:event_exitForm
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ new ShaderTestGLSL().setVisible(true);
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JToggleButton AttachButton;
+ private javax.swing.JToggleButton DetachButton;
+ private javax.swing.ButtonGroup colorButtonGroup;
+ private javax.swing.JPanel colorPanel;
+ private javax.swing.ButtonGroup densityButtonGroup;
+ private javax.swing.JPanel densityPanel;
+ private javax.swing.JPanel drawingPanel;
+ private javax.swing.JMenuItem exitMenuItem;
+ private javax.swing.JMenu fileMenu;
+ private javax.swing.JRadioButton fullButton;
+ private javax.swing.JRadioButton goldButton;
+ private javax.swing.JPanel guiPanel;
+ private javax.swing.JRadioButton halfButton;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JPanel mainPanel;
+ private javax.swing.JButton replaceSPButton;
+ private javax.swing.ButtonGroup sceneGraphButtonGroup;
+ private javax.swing.JPanel sceneGraphPanel;
+ private javax.swing.JRadioButton silverButton;
+ private javax.swing.JRadioButton zeroButton;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java b/src/classes/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java
new file mode 100644
index 0000000..0865f93
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java
@@ -0,0 +1,341 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.glsl_shader;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.io.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.shader.StringIO;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+/**
+ * Simple GLSL Shader test program
+ */
+public class SphereGLSL extends Applet {
+
+ // Constants for type of light to use
+ private static final int DIRECTIONAL_LIGHT = 0;
+ private static final int POINT_LIGHT = 1;
+ private static final int SPOT_LIGHT = 2;
+
+ // Flag indicates type of lights: directional, point, or spot
+ // lights. This flag is set based on command line argument
+ private static int lightType = DIRECTIONAL_LIGHT;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(SimpleUniverse u) {
+ Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f);
+ Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+
+ Transform3D t;
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ // Create a Sphere object, generate one copy of the sphere,
+ // and add it into the scene graph.
+ ShaderAppearance a = new ShaderAppearance();
+ Material m = new Material(objColor, eColor, objColor, sColor, 100.0f);
+ m.setLightingEnable(true);
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try {
+ vertexProgram = StringIO.readFully("./simple.vert");
+ fragmentProgram = StringIO.readFully("./simple.frag");
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_VERTEX,
+ vertexProgram);
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_FRAGMENT,
+ fragmentProgram);
+ ShaderProgram shaderProgram = new GLSLShaderProgram();
+ shaderProgram.setShaders(shaders);
+
+ a.setShaderProgram(shaderProgram);
+ a.setMaterial(m);
+ Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS, 200, a);
+ objScale.addChild(sph);
+
+ // Create the transform group node for the each light and initialize
+ // it to the identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add them to the root
+ // of the subgraph.
+ TransformGroup l1RotTrans = new TransformGroup();
+ l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(l1RotTrans);
+
+ TransformGroup l2RotTrans = new TransformGroup();
+ l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(l2RotTrans);
+
+ // Create transformations for the positional lights
+ t = new Transform3D();
+ Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0);
+ t.set(lPos1);
+ TransformGroup l1Trans = new TransformGroup(t);
+ l1RotTrans.addChild(l1Trans);
+
+ t = new Transform3D();
+ Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0);
+ t.set(lPos2);
+ TransformGroup l2Trans = new TransformGroup(t);
+ l2RotTrans.addChild(l2Trans);
+
+ // Create Geometry for point lights
+ ColoringAttributes caL1 = new ColoringAttributes();
+ ColoringAttributes caL2 = new ColoringAttributes();
+ caL1.setColor(lColor1);
+ caL2.setColor(lColor2);
+ Appearance appL1 = new Appearance();
+ Appearance appL2 = new Appearance();
+ appL1.setColoringAttributes(caL1);
+ appL2.setColoringAttributes(caL2);
+ l1Trans.addChild(new Sphere(0.05f, appL1));
+ l2Trans.addChild(new Sphere(0.05f, appL2));
+
+ // Create lights
+ AmbientLight aLgt = new AmbientLight(alColor);
+
+ Light lgt1 = null;
+ Light lgt2 = null;
+
+ Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f atten = new Point3f(1.0f, 0.0f, 0.0f);
+ Vector3f lDirect1 = new Vector3f(lPos1);
+ Vector3f lDirect2 = new Vector3f(lPos2);
+ lDirect1.negate();
+ lDirect2.negate();
+
+ switch (lightType) {
+ case DIRECTIONAL_LIGHT:
+ lgt1 = new DirectionalLight(lColor1, lDirect1);
+ lgt2 = new DirectionalLight(lColor2, lDirect2);
+ break;
+ case POINT_LIGHT:
+ lgt1 = new PointLight(lColor1, lPoint, atten);
+ lgt2 = new PointLight(lColor2, lPoint, atten);
+ break;
+ case SPOT_LIGHT:
+ lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1,
+ 25.0f * (float)Math.PI / 180.0f, 10.0f);
+ lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2,
+ 25.0f * (float)Math.PI / 180.0f, 10.0f);
+ break;
+ }
+
+ // Set the influencing bounds
+ aLgt.setInfluencingBounds(bounds);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+
+ // Add the lights into the scene graph
+ objScale.addChild(aLgt);
+ l1Trans.addChild(lgt1);
+ l2Trans.addChild(lgt2);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator1 =
+ new RotationInterpolator(rotor1Alpha,
+ l1RotTrans,
+ yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator1.setSchedulingBounds(bounds);
+ l1RotTrans.addChild(rotator1);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Alpha rotor2Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 1000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator2 =
+ new RotationInterpolator(rotor2Alpha,
+ l2RotTrans,
+ yAxis,
+ 0.0f, 0.0f);
+ bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator2.setSchedulingBounds(bounds);
+ l2RotTrans.addChild(rotator2);
+
+ // Create a position interpolator and attach it to the view
+ // platform
+ TransformGroup vpTrans =
+ u.getViewingPlatform().getViewPlatformTransform();
+ Transform3D axisOfTranslation = new Transform3D();
+ Alpha transAlpha = new Alpha(-1,
+ Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 5000, 0, 0,
+ 5000, 0, 0);
+ axisOfTranslation.rotY(-Math.PI/2.0);
+ PositionInterpolator translator =
+ new PositionInterpolator(transAlpha,
+ vpTrans,
+ axisOfTranslation,
+ 2.0f, 3.5f);
+ translator.setSchedulingBounds(bounds);
+ objScale.addChild(translator);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public SphereGLSL() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ u = new SimpleUniverse(c);
+ BranchGroup scene = createSceneGraph(u);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ /*
+ // Limit the frame rate to 100 Hz
+ u.getViewer().getView().setMinimumFrameCycleTime(10);
+ */
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows SphereGLSL to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ // Parse the Input Arguments
+ String usage = "Usage: java SphereGLSL [-point | -spot | -dir]";
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].equals("-point")) {
+ /*
+ System.out.println("Using point lights");
+ lightType = POINT_LIGHT;
+ */
+ System.out.println("Point lights not yet implemented, option ignored");
+ }
+ else if (args[i].equals("-spot")) {
+ /*
+ System.out.println("Using spot lights");
+ lightType = SPOT_LIGHT;
+ */
+ System.out.println("Spot lights not yet implemented, option ignored");
+ }
+ else if (args[i].equals("-dir")) {
+ System.out.println("Using directional lights");
+ lightType = DIRECTIONAL_LIGHT;
+ }
+ else {
+ System.out.println(usage);
+ System.exit(0);
+ }
+ }
+ else {
+ System.out.println(usage);
+ System.exit(0);
+ }
+ }
+
+ new MainFrame(new SphereGLSL(), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag
new file mode 100644
index 0000000..7c9aab8
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag
@@ -0,0 +1,55 @@
+//
+// Fragment shader for antialiased procedural bricks
+//
+// Authors: Dave Baldwin, Randi Rost
+// based on a shader by Darwyn Peachey
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+uniform vec3 BrickColor;
+//uniform vec3 MortarColor;
+//uniform vec2 BrickSize;
+//uniform vec2 BrickPct;
+//uniform vec2 MortarPct;
+
+//const vec3 BrickColor = vec3 (1, 0.3, 0.2);
+const vec3 MortarColor = vec3 (0.85, 0.86, 0.84);
+const vec2 BrickSize = vec2 (0.3, 0.15);
+const vec2 BrickPct = vec2 (0.9, 0.85);
+const vec2 MortarPct = vec2 (0.1, 0.15);
+
+varying vec2 MCposition;
+varying float LightIntensity;
+
+#define Integral(x, p, notp) ((floor(x)*(p)) + max(fract(x)-(notp), 0.0))
+
+void main(void)
+{
+ vec2 position, fw, useBrick;
+ vec3 color;
+
+ // Determine position within the brick pattern
+ position = MCposition / BrickSize;
+
+ // Adjust every other row by an offset of half a brick
+ if (fract(position.y * 0.5) > 0.5)
+ position.x += 0.5;
+
+ // Calculate filter size
+ //fw = fwidth(position); //fwidth not implemented on WildcatVP
+ fw = (abs(dFdx(MCposition)) + abs(dFdy(MCposition))) / BrickSize;
+
+ // Perform filtering by integrating the 2D pulse made by the
+ // brick pattern over the filter width and height
+ useBrick = (Integral(position + fw, BrickPct, MortarPct) -
+ Integral(position, BrickPct, MortarPct)) / fw;
+
+ // Determine final color
+ color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y);
+ color *= LightIntensity;
+
+ gl_FragColor = vec4 (color, 1.0);
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert
new file mode 100644
index 0000000..226dbe4
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert
@@ -0,0 +1,42 @@
+//
+// Vertex shader for antialiased procedural bricks
+//
+// Authors: Dave Baldwin, Steve Koren, Randi Rost
+// based on a shader by Darwyn Peachey
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+uniform vec3 LightPosition;
+//const vec3 LightPosition = vec3 (0, 4, 4);
+
+const float SpecularContribution = 0.3;
+const float DiffuseContribution = 1.0 - SpecularContribution;
+
+varying float LightIntensity;
+varying vec2 MCposition;
+
+void main(void)
+{
+ vec3 ecPosition = vec3 (gl_ModelViewMatrix * gl_Vertex);
+ vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
+ vec3 lightVec = normalize(LightPosition - ecPosition);
+ vec3 reflectVec = reflect(-lightVec, tnorm);
+ vec3 viewVec = normalize(-ecPosition);
+ float diffuse = max(dot(lightVec, tnorm), 0.0);
+ float spec = 0.0;
+
+ if (diffuse > 0.0)
+ {
+ spec = max(dot(reflectVec, viewVec), 0.0);
+ spec = pow(spec, 16.0);
+ }
+
+ LightIntensity = DiffuseContribution * diffuse +
+ SpecularContribution * spec;
+
+ MCposition = gl_Vertex.xy;
+ gl_Position = ftransform();
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.frag
new file mode 100644
index 0000000..282add7
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.frag
@@ -0,0 +1,61 @@
+
+//
+// dimple.frag: Fragment shader for bump mapping dimples (bumps)
+//
+// author: John Kessenich
+//
+// Copyright (c) 2002: 3Dlabs, Inc.
+//
+//
+varying vec3 LightDir;
+varying vec3 EyeDir;
+varying vec3 Normal;
+
+//const vec3 Color = vec3(0.7, 0.6, 0.18);
+
+//const float Density = 16.0;
+//const float Size = 0.25;
+
+uniform vec3 Color;
+uniform float Density;
+uniform float Size;
+// uniform float SpecularFactor;
+
+//float Density = 27.6;
+//float Size = 0.13025;
+
+
+//uniform float Scale;
+
+const float SpecularFactor = 0.4;
+
+void main (void)
+{
+ vec3 litColor;
+
+ vec2 c = Density * (gl_TexCoord[0].xy);
+ vec2 p = fract(c) - vec2(0.5);
+ float d = (p.x * p.x) + (p.y * p.y);
+ if (d >= Size)
+ p = vec2(0.0);
+
+ vec3 normDelta = vec3(-p.x, -p.y, 1.0);
+
+ litColor = Color * max(0.0, dot(normDelta, LightDir));
+
+ float t = 2.0 * dot(LightDir, normDelta);
+ vec3 reflectDir = t * normDelta;
+ reflectDir = LightDir - reflectDir;
+
+// vec3 reflectDir = LightDir - 2.0 * dot(LightDir, normDelta) * normDelta;
+
+ float spec = max(dot(EyeDir, reflectDir), 0.0);
+ spec = spec * spec;
+ spec = spec * spec;
+ spec *= SpecularFactor;
+
+ litColor = min(litColor + spec, vec3(1.0));
+ gl_FragColor = vec4(litColor, gl_Color.a);
+// gl_FragColor = vec4(litColor, 1.0);
+// gl_FragColor = vec4(Scale);
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.vert
new file mode 100644
index 0000000..e45796b
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.vert
@@ -0,0 +1,42 @@
+
+//
+// dimple.vert: Vertex shader for bump mapping dimples (bumps)
+//
+// author: John Kessenich
+//
+// Copyright (c) 2002: 3Dlabs, Inc.
+//
+
+varying vec3 LightDir;
+varying vec3 EyeDir;
+varying vec3 Normal;
+
+uniform vec3 LightPosition;
+// uniform float Scale;
+// vec3 LightPosition = vec3(0.0, 0.0, 5.0);
+float Scale = 1.0;
+
+void main(void)
+{
+ vec4 pos = gl_ModelViewMatrix * gl_Vertex;
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+ vec3 eyeDir = vec3(pos);
+// gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[0] = gl_Vertex;
+ gl_FrontColor = gl_Color;
+
+ vec3 n = normalize(gl_NormalMatrix * gl_Normal);
+ vec3 t = normalize(cross(vec3(1.141, 2.78, 3.14), n));
+ vec3 b = cross(n, t);
+
+ vec3 v;
+ v.x = dot(LightPosition, t);
+ v.y = dot(LightPosition, b);
+ v.z = dot(LightPosition, n);
+ LightDir = normalize(v);
+
+ v.x = dot(eyeDir, t);
+ v.y = dot(eyeDir, b);
+ v.z = dot(eyeDir, n);
+ EyeDir = normalize(v);
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag
new file mode 100644
index 0000000..951ee8e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag
@@ -0,0 +1,50 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+// Simple GLSL fragment program to add the primary and secondary (specular) colors
+
+void main()
+{
+ gl_FragColor = gl_Color + gl_SecondaryColor;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert
new file mode 100644
index 0000000..fd49c18
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert
@@ -0,0 +1,100 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+// A GLSL vertex program for handling 1 directional light with specular.
+// This implements per-vertex lighting (Gouraud shading).
+
+void directionalLight0(
+ in vec3 normal,
+ inout vec4 ambient,
+ inout vec4 diffuse,
+ inout vec4 specular)
+{
+ // Normalized light direction and half vector
+ vec3 lightDirection = normalize(vec3(gl_LightSource[0].position));
+ vec3 halfVector = normalize(vec3(gl_LightSource[0].halfVector));
+
+ float nDotVP; // normal . light_direction
+ float nDotHV; // normal . light_half_vector
+ float pf; // power factor
+
+ nDotVP = max(0.0, dot(normal, lightDirection));
+ nDotHV = max(0.0, dot(normal, halfVector));
+
+ if (nDotVP == 0.0) {
+ pf = 0.0;
+ }
+ else {
+ pf = pow(nDotHV, gl_FrontMaterial.shininess);
+ }
+
+ ambient += gl_LightSource[0].ambient;
+ diffuse += gl_LightSource[0].diffuse * nDotVP;
+ specular += gl_LightSource[0].specular * pf;
+}
+
+
+void main()
+{
+ vec3 tnorm = normalize(vec3(gl_NormalMatrix * gl_Normal));
+ vec4 amb = vec4(0.0);
+ vec4 diff = vec4(0.0);
+ vec4 spec = vec4(0.0);
+ int i;
+
+ // Transform the vertex
+ vec4 outPosition = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+ directionalLight0(tnorm, amb, diff, spec);
+
+ // Apply the result of the lighting equation
+ vec4 outSecondaryColor = vec4(vec3(spec * gl_FrontMaterial.specular), 1.0);
+ vec4 outColor = vec4(vec3(gl_FrontLightModelProduct.sceneColor +
+ amb * gl_FrontMaterial.ambient +
+ diff * gl_FrontMaterial.diffuse), 1.0);
+
+ gl_FrontColor = outColor;
+ gl_FrontSecondaryColor = outSecondaryColor;
+ gl_Position = outPosition;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.frag
new file mode 100644
index 0000000..41de179
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.frag
@@ -0,0 +1,98 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+// A GLSL fragment program for handling 1 directional light with specular.
+// This implements per-pixel lighting (Phong shading)
+
+void directionalLight0(
+ in vec3 normal,
+ inout vec4 ambient,
+ inout vec4 diffuse,
+ inout vec4 specular)
+{
+ // Normalized light direction and half vector
+ vec3 lightDirection = normalize(vec3(gl_LightSource[0].position));
+ vec3 halfVector = normalize(vec3(gl_LightSource[0].halfVector));
+
+ float nDotVP; // normal . light_direction
+ float nDotHV; // normal . light_half_vector
+ float pf; // power factor
+
+ nDotVP = max(0.0, dot(normal, lightDirection));
+ nDotHV = max(0.0, dot(normal, halfVector));
+
+ if (nDotVP == 0.0) {
+ pf = 0.0;
+ }
+ else {
+ pf = pow(nDotHV, gl_FrontMaterial.shininess);
+ }
+
+ ambient += gl_LightSource[0].ambient;
+ diffuse += gl_LightSource[0].diffuse * nDotVP;
+ specular += gl_LightSource[0].specular * pf;
+}
+
+
+// Per-pixel normal (input from vertex shader)
+varying vec3 Normal;
+
+void main()
+{
+ vec3 unitNorm = normalize(Normal);
+ vec4 amb = vec4(0.0);
+ vec4 diff = vec4(0.0);
+ vec4 spec = vec4(0.0);
+ int i;
+
+ directionalLight0(unitNorm, amb, diff, spec);
+
+ // Apply the result of the lighting equation
+ vec4 secondaryColor = vec4(vec3(spec * gl_FrontMaterial.specular), 1.0);
+ vec4 color = vec4(vec3(gl_FrontLightModelProduct.sceneColor +
+ amb * gl_FrontMaterial.ambient +
+ diff * gl_FrontMaterial.diffuse), 1.0);
+
+ gl_FragColor = color + secondaryColor;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.vert
new file mode 100644
index 0000000..9a67c8b
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.vert
@@ -0,0 +1,56 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+// A GLSL vertex program for doing Phone shading (per-fragment lighting)
+
+// Per-pixel normal (output to fragment shader)
+varying vec3 Normal;
+
+void main()
+{
+ Normal = normalize(vec3(gl_NormalMatrix * gl_Normal));
+
+ // Transform the vertex
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag
new file mode 100644
index 0000000..b341454
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag
@@ -0,0 +1,48 @@
+//
+// Fragment shader for 3 dimensional polka dot shader.
+//
+// Author: Joshua Doss
+//
+// Copyright (C) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+varying float LightIntensity;
+varying vec3 MCPosition;
+
+//Create uniform variables so dots can be spaced and scaled by user
+//uniform vec3 Spacing;
+//uniform float DotSize;
+const vec3 Spacing = vec3 (0.314, 0.36, 0.261);
+const float DotSize = 0.123;
+
+//Create colors as uniform variables so they can be easily changed
+//uniform vec3 ModelColor, PolkaDotColor;
+const vec3 ModelColor = vec3 (0.75, 0.2, 0.1);
+const vec3 PolkaDotColor = vec3 (1, 1, 1);
+
+void main(void)
+{
+ float insidesphere, sphereradius, scaledpointlength;
+ vec3 scaledpoint, finalcolor;
+
+ // Scale the coordinate system
+ // The following line of code is not yet implemented in current drivers:
+ // mcpos = mod(Spacing, MCposition);
+ // We will use a workaround found below for now
+ scaledpoint = MCPosition - (Spacing * floor(MCPosition/Spacing));
+
+ // Bring the scaledpoint vector into the center of the scaled coordinate system
+ scaledpoint = scaledpoint - Spacing/2.0;
+
+ // Find the length of the scaledpoint vector and compare it to the dotsize
+ scaledpointlength = length(scaledpoint);
+ insidesphere = step(scaledpointlength,DotSize);
+
+ // Determine final output color before lighting
+ finalcolor = vec3(mix(ModelColor, PolkaDotColor, insidesphere));
+
+ // Output final color and factor in lighting
+ gl_FragColor = clamp((vec4( finalcolor, 1.0 ) * LightIntensity), vec4(0.0), vec4(1.0));
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert
new file mode 100644
index 0000000..86f432f
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert
@@ -0,0 +1,58 @@
+// This is the Vertex Shader for three dimensional polka dots.
+//
+// author(s): Joshua Doss
+//
+// Copyright (C) 2002-2004 3Dlabs Inc. Ltd.
+
+//Create uniform variables for lighting to allow user interaction
+//uniform float SpecularContribution;
+//uniform vec3 LightPosition;
+
+const float SpecularContribution = 0.36;
+const vec3 LightPosition = vec3 (0, 4, 5);
+
+varying vec3 MCPosition;
+varying float LightIntensity;
+
+void main(void)
+{
+ float diffusecontribution = 1.0 - SpecularContribution;
+
+ // compute the vertex position in eye coordinates
+ vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
+
+ // compute the transformed normal
+ vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
+
+ // compute a vector from the model to the light position
+ vec3 lightVec = normalize(LightPosition - ecPosition);
+
+ // compute the reflection vector
+ vec3 reflectVec = reflect(-lightVec, tnorm);
+
+ // compute a unit vector in direction of viewing position
+ vec3 viewVec = normalize(-ecPosition);
+
+ // calculate amount of diffuse light based on normal and light angle
+ float diffuse = max(dot(lightVec, tnorm), 0.0);
+ float spec = 0.0;
+
+ // if there is diffuse lighting, calculate specular
+ if(diffuse > 0.0)
+ {
+ spec = max(dot(reflectVec, viewVec), 0.0);
+ spec = pow(spec, 16.0);
+ }
+
+ // add up the light sources, since this is a varying (global) it will pass to frag shader
+ LightIntensity = diffusecontribution * diffuse * 1.5 +
+ SpecularContribution * spec;
+
+ // the varying variable MCPosition will be used by the fragment shader to determine where
+ // in model space the current pixel is
+ MCPosition = vec3 (gl_Vertex);
+
+ // send vertex information
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.frag
new file mode 100644
index 0000000..6542b34
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.frag
@@ -0,0 +1,62 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+// Simple GLSL fragment program to attenuate the input fragment color as a
+// function of the distance of the fragment position from the center
+// of the window
+
+const float windowSize = 700.0; // TODO: this should be a built-in parameter!
+
+void main()
+{
+ // Compute distance from center in range [0.0, 1.0]
+ vec2 dist = min(abs((gl_FragCoord.xy - (windowSize)/2.0) / windowSize), 1.0);
+ vec2 invDist = 1.0 - dist;
+
+ // Compute attenuation
+ float atten = invDist.x * invDist.y;
+ vec4 outcolor = (gl_Color + gl_SecondaryColor) * atten;
+
+ gl_FragColor = outcolor;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.vert
new file mode 100644
index 0000000..7d3e152
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.vert
@@ -0,0 +1,129 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+// A simple GLSL vertex program for handling 2 directional lights with
+// separate specular
+
+void directionalLight(
+ in int i,
+ in vec3 normal,
+ inout vec4 ambient,
+ inout vec4 diffuse,
+ inout vec4 specular)
+{
+ // Normalized light direction and half vector
+ // (shouldn't they be pre-normalized?!)
+ vec3 lightDirection = normalize(vec3(gl_LightSource[i].position));
+ vec3 halfVector = normalize(vec3(gl_LightSource[i].halfVector));
+
+ float nDotVP; // normal . light_direction
+ float nDotHV; // normal . light_half_vector
+ float pf; // power factor
+
+ nDotVP = max(0.0, dot(normal, lightDirection));
+ nDotHV = max(0.0, dot(normal, halfVector));
+
+ if (nDotVP == 0.0) {
+ pf = 0.0;
+ }
+ else {
+ pf = pow(nDotHV, gl_FrontMaterial.shininess);
+ }
+
+ ambient += gl_LightSource[i].ambient;
+ diffuse += gl_LightSource[i].diffuse * nDotVP;
+ specular += gl_LightSource[i].specular * pf;
+}
+
+
+const int numEnabledLights = 2; // TODO: this should be a built-in parameter!
+
+void main()
+{
+ //vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
+ //vec3 ecPosition3 = ecPosition.xyz / ecPosition.w;
+ vec3 tnorm = normalize(vec3(gl_NormalMatrix * gl_Normal));
+ vec4 amb = vec4(0.0);
+ vec4 diff = vec4(0.0);
+ vec4 spec = vec4(0.0);
+ int i;
+
+ // Transform the vertex
+ vec4 outPosition = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+ for (i = 0; i < numEnabledLights; i++) {
+ directionalLight(i, tnorm, amb, diff, spec);
+ }
+
+ // Apply the result of the lighting equation
+ vec4 outSecondaryColor = vec4(vec3(spec * gl_FrontMaterial.specular), 1.0);
+ vec3 color0 = vec3(gl_FrontLightModelProduct.sceneColor +
+ amb * gl_FrontMaterial.ambient +
+ diff * gl_FrontMaterial.diffuse);
+
+ // Generate a pseudo-random noise pattern
+ vec3 xyz = clamp((outPosition.xyz + 1.0) * 0.5, 0.0, 1.0);
+
+ xyz = fract(xyz * 262144.0);
+ float randSeed = fract(3.0 * xyz.x + 5.0 * xyz.y + 7.0 * xyz.z);
+
+ vec3 altColor;
+
+ randSeed = fract(37.0 * randSeed);
+ altColor.x = randSeed * 0.5 + 0.5;
+ randSeed = fract(37.0 * randSeed);
+ altColor.y = randSeed * 0.5 + 0.5;
+ randSeed = fract(37.0 * randSeed);
+ altColor.z = randSeed * 0.5 + 0.5;
+ randSeed = fract(37.0 * randSeed);
+ float altAlpha = randSeed * 0.5;
+
+ // Apply noise and output final vertex color
+ vec4 outColor;
+ outColor = vec4(mix(color0, altColor, altAlpha), 1.0);
+
+ gl_FrontColor = outColor;
+ gl_FrontSecondaryColor = outSecondaryColor;
+ gl_Position = outPosition;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.frag
new file mode 100644
index 0000000..fa50453
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.frag
@@ -0,0 +1,34 @@
+//
+// Fragment shader for cartoon-style shading
+//
+// Author: Philip Rideout
+//
+// Copyright (c) 2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+//uniform vec3 DiffuseColor;
+//uniform vec3 PhongColor;
+//uniform float Edge;
+//uniform float Phong;
+
+vec3 DiffuseColor = vec3(0.5,0.5,1.0);
+vec3 PhongColor = vec3(0.75,0.75,1.0);
+float Edge = 0.64;
+float Phong = 0.90;
+
+varying vec3 Normal;
+varying vec3 LightDir;
+
+void main (void)
+{
+ vec3 color = DiffuseColor;
+ float f = max( 0.0, dot(LightDir,Normal));
+ if (abs(f) < Edge)
+ color = DiffuseColor * 0.2;
+ if (f > Phong)
+ color = PhongColor;
+
+ gl_FragColor = vec4(color, 1);
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.vert
new file mode 100644
index 0000000..d044af7
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.vert
@@ -0,0 +1,19 @@
+//
+// Vertex shader for cartoon-style shading
+//
+// Author: Philip Rideout
+//
+// Copyright (c) 2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+varying vec3 Normal;
+varying vec3 LightDir;
+
+void main(void)
+{
+ Normal = normalize(gl_NormalMatrix * gl_Normal);
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+ LightDir = vec3(normalize(gl_LightSource[0].position));
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.frag
new file mode 100644
index 0000000..eecf91f
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.frag
@@ -0,0 +1,66 @@
+//
+// Simple fragment shader for wood
+//
+// Author: John Kessenich
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+//uniform float GrainSizeRecip;
+//uniform vec3 DarkColor;
+//uniform vec3 spread;
+const float GrainSizeRecip = 1.0;
+const vec3 DarkColor = vec3 (0.6, 0.3, 0.1);
+const vec3 spread = vec3 (0.15, 0.075, 0.0);
+
+varying float lightIntensity;
+varying vec3 Position;
+
+void main (void)
+{
+ //
+ // cheap noise
+ //
+ vec3 location = Position;
+ vec3 floorvec = vec3(floor(10.0 * Position.x), 0.0, floor(10.0 * Position.z));
+ vec3 noise = Position * 10.0 - floorvec - 0.5;
+ noise *= noise;
+ location += noise * 0.12;
+
+ //
+ // distance from axis
+ //
+ float dist = location.x * location.x + location.z * location.z;
+ float grain = dist * GrainSizeRecip;
+
+ //
+ // grain effects as function of distance
+ //
+ float brightness = fract(grain);
+ if (brightness > 0.5)
+ brightness = (1.0 - brightness);
+ vec3 color = DarkColor + brightness * spread;
+
+ brightness = fract(grain * 7.0);
+ if (brightness > 0.5)
+ brightness = 1.0 - brightness;
+ color -= brightness * spread;
+
+ //
+ // also as a function of lines parallel to the axis
+ //
+ brightness = fract(grain * 47.0) * 0.60;
+ float line = fract(Position.z + Position.x);
+ float snap = floor(line * 20.0) * (1.0/20.0);
+ if (line < snap + 0.006)
+ color -= brightness * spread;
+
+ //
+ // apply lighting effects from vertex processor
+ //
+ color = clamp(color * lightIntensity, 0.0, 1.0);
+
+ gl_FragColor = vec4(color, 1.0);
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.vert
new file mode 100644
index 0000000..84651aa
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.vert
@@ -0,0 +1,25 @@
+//
+// Simple vertex shader for wood
+//
+// Author: John Kessenich
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+varying float lightIntensity;
+varying vec3 Position;
+//uniform vec3 LightPosition;
+//uniform float Scale;
+const vec3 LightPosition = vec3 (0.0,0.0,0.4);
+const float Scale = 1.0;
+
+void main(void)
+{
+ vec4 pos = gl_ModelViewMatrix * gl_Vertex;
+ Position = vec3(gl_Vertex) * Scale;
+ vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
+ lightIntensity = max(dot(normalize(LightPosition - vec3(pos)), tnorm), 0.0) * 1.5;
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form b/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form
new file mode 100644
index 0000000..48fadea
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <Properties>
+ <Property name="defaultCloseOperation" type="int" value="3"/>
+ <Property name="title" type="java.lang.String" value="HelloUniverse"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="drawingPanel">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[250, 250]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java b/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java
new file mode 100644
index 0000000..8fe0f49
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java
@@ -0,0 +1,169 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.hello_universe;
+
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.geometry.ColorCube;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.GraphicsConfiguration;
+
+/**
+ * Simple Java 3D example program to display a spinning cube.
+ */
+public class HelloUniverse extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create the TransformGroup node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at run time. Add it to
+ // the root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // Create a simple Shape3D node; add it to the scene graph.
+ objTrans.addChild(new ColorCube(0.4));
+
+ // Create a new Behavior object that will perform the
+ // desired operation on the specified transform and add
+ // it into the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, 4000);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objRoot.addChild(rotator);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ private Canvas3D createUniverse() {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ // Create a Canvas3D using the preferred configuration
+ Canvas3D c = new Canvas3D(config);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ univ.getViewingPlatform().setNominalViewingTransform();
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return c;
+ }
+
+ /**
+ * Creates new form HelloUniverse
+ */
+ public HelloUniverse() {
+ // Initialize the GUI components
+ initComponents();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ Canvas3D c = createUniverse();
+ drawingPanel.add(c, java.awt.BorderLayout.CENTER);
+
+ // Create the content branch and add it to the universe
+ scene = createSceneGraph();
+ univ.addBranchGraph(scene);
+ }
+
+ // ----------------------------------------------------------------
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents() {
+ drawingPanel = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("HelloUniverse");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(250, 250));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new HelloUniverse().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/lightwave/README.txt b/src/classes/org/jdesktop/j3d/examples/lightwave/README.txt
new file mode 100644
index 0000000..c37f4d9
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/lightwave/README.txt
@@ -0,0 +1,321 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+ Release Notes for the Lightwave 3D Java3D Loader
+ ------------------------------------------------
+ Updated May 13, 1998
+
+
+
+These release notes are intended to document the known working and
+non-working features of the loader. This is important because the loader
+implements an important subset of Lightwave functionality, but it definitely
+skips many major features of Lightwave files. Please read these notes
+to make sure that the features you need are actually implemented. Or
+if you see differences between Lightwave display of your file and
+the Java3D version of that file, take a look at these notes to see
+what might not be working properly.
+
+
+Testing the Loader
+------------------
+The application in this directory (Viewer) is intended to be a very
+basic test application for loading/viewing Lightwave 3D models. To
+use the program, type:
+ java Viewer <filename>
+where <filename> is the name of a valid Lightwave 3D scene file that is
+reachable from the current directory. There is a very basic test file
+included in this directory called ballcone.lws. To load/view that file,
+type:
+ java Viewer ballcone.lws
+Note that Lightwave scene files (*.lws) embed the pathnames to object
+files (*.lwo) within them, and that object files have pathnames
+to image files (for textures) embedded in them. Whatever those
+pathnames are in those files must be valid for the directory in which
+you are running the application that loads the scene file. For example,
+if I was loading in a scene file that referred to an object file
+called "data/object.lwo", then the file "object.lwo" should be located in
+a subdirectory of this current directory called "data".
+
+
+Summary of Loader
+-----------------
+The Lw3d loader was intended to implement a major subset of the features in
+Lightwave 3D that would be used for realtime 3D animations. That is, any
+features (such as Bones and other high-end rendering
+options) which would require significant rendering time were simply
+not doable. These more advanced features are intended to be rendered
+off-line, saving each frame separately and later compositing them
+together into an animation. But Java3D is a realtime 3D rendering
+system, so these type of animations just do not map into a Java3D viewer
+very well.
+
+Another category of non-implemented items are those that we simply have not
+yet gotten to. There are a few known features of Lightwave files that
+would work well through Java3D but just haven't been implemented in the
+loader yet.
+
+Although there are a lot of features that are not yet implemented,
+the basics of Lightwave 3D functionality (scene creation, animating
+objects/lights/cameras, different surface properties) all work pretty
+much as expected. So try it out and let us know non-documented items
+that didn't work properly.
+
+
+Details of Non-Implemented Features
+-----------------------------------
+This list is probably not comprehensive, but hopefully points out most of
+the features or areas where the implementation is incomplete (or not
+there at all).
+
+
+Limitations of Scene Files (*.lws)
+----------------------------------
+1) Bones/Skeleton
+Bones functionality is not implemented at all. Unfortunately, this
+great feature of Lightwave 3D is not currently implementable in the
+loader because the processing time that it would take to compute
+frames based on Bones data would be far more than a real-time rendering
+system can afford.
+
+The loader may, at some future point, provide a mechanism to read
+in frames of geometry that were saved from Lightwave Bones descriptions.
+That is, there are plug-ins available for Lightwave 3D that allow you
+to save out files with Bones information as a series of files with
+pre-calculated geometry for each frame; eventually we would like the
+Lightwave 3D loader to support those files.
+
+Workaround: None; the best and only workaround is to find a different
+method of animating your objects.
+
+
+2) Spline paths
+Spline paths will be interpreted as linear piecewise paths instead,
+traveling between each control point specified for the spline.
+
+Workaround: Specify linear paths. If your path looks too hard-jointed
+through the loader, specify more keyframes for the path to smooth it out.
+
+
+3) Object Scaling
+Scaling objects in the scene (versus the object files) is currently
+ignored.
+
+Workaround: scale the objects in their individual object files.
+
+
+4) Shadows
+Shadows options are ignored in the loader.
+
+Workaround: None.
+
+
+5) Envelopes
+Most envelopes are ignored. There are a couple of exceptions to this,
+such as light intensity envelopes, but even those features have not been
+completely implemented and tested.
+
+Workaround: None.
+
+
+6) Camera effects
+All advanced-rendering camera effects are ignored in the loader. This
+includes the following items in Lightwave 3D files:
+ - Lens Flare
+ - F-stop
+ - Focal Distance
+ - Blur Length
+ - Dissolves
+ - Glow
+ - Zoom
+ - Intensity Falloff
+ - Antialiasing
+
+Workaround: None.
+
+
+7) Inverse Kinematics
+IK options such as Goal Objects and Anchors are ignored.
+
+Workaround: Animate objects directly instead of indirectly via IK.
+
+
+8) Morphs
+All morph options are ignored.
+
+Workaround: None.
+
+
+9) Display properties
+Lightwave allows you to specify surface properties for different rendering
+modes (e.g., wireframe color). All of these parameters are ignored and
+the full properties of any item are used at all times.
+
+Workaround: None.
+
+
+10) Various Surface Properties
+Various minor surface properties are currently ignored, including:
+ - Polygon size
+ - Dissolves
+ - Clip map
+ - Unaffected by fog
+ - Edge parameters
+
+Workaround: None.
+
+
+11) Lights
+The following items are currently ignored for Light objects:
+ - Target objects
+ - Flare parameters
+ - Shadow options
+
+Workaround: None for flares or shadows. For targeting problems, animate the
+light directly (versus indirectly through using Target).
+
+
+12) Camera Targeting
+The Target option for Camera objects is currently ignored by the loader.
+
+Workaround: Animate the camera directly (versus indirectly through using
+Target).
+
+
+13) Effects
+Most effects (from the Effects dialog box in the layout program) are
+ignored, save for fog (which should accept all parameters) and
+backdrop colors (solid backdrops only - gradient backdrops are
+ignored).
+
+Workaround: None.
+
+
+14) Render Options
+Most options from the Render dialog box are ignored - most of these pertain
+to saving the animation in any case (something that doesn't happen through
+the Loader).
+
+Workaround: None.
+
+
+
+Limitations of Object Files (*.lwo)
+-----------------------------------
+1) MetaNURBS
+Geometry stored in MetaNURBS format will be ignored by the loader.
+
+Workaround: pre-tessellate your MetaNURBS surfaces and save your
+geometry (object) files in that format.
+
+
+2) Layered Object Files
+There is currently no support for the "Layered Object File Format"
+of Lightwave 3D.
+
+Workaround: None.
+
+
+3) Reflectivity
+There is no way to reproduce the reflective properties of surfaces
+through Java3D, so any reflectivity settings in Lightwave object files
+will be ignored.
+
+Workaround: None.
+
+
+4) Refraction
+Refractive properties of surfaces are ignored.
+
+Workaround: None.
+
+
+5) Edge Transparency
+Edge transparency properties are ignored.
+
+Workaround. None.
+
+
+6) Texture types
+Texture mapping is currently somewhat limited in the loader. The following
+types of texture mapping effects should work:
+ - Diffuse (the texture modifies the Diffuse aspects of the surface)
+ - Color (the texture modifies the Color properties of the surface).
+Textures that attempt to modify other parameters of the surface will
+be ignored.
+
+Also, the following texture types should work:
+ - Planar Image Map
+ - Spherical Image Map
+ - Cylindrical Image Map
+Other kinds of mappings will not work (including Marble, Grid, Dots, etc.)
+
+Some Texture parameters will not work. The following should work correctly:
+ - size
+ - center
+Advanced texture parameters such as falloff and velocity will be ignored.
+
+Summary: There are so many texture mapping parameters in Lightwave 3D that
+it's difficult to produce a list of all of the items that won't work
+properly. In a nutshell, basic decal-type (color modifying) or brightness
+(diffuse modifying) textures that are mapped as planes, spheres, or
+cylinders should work correctly. Anything else will probably not work.
+
+Workaround: Use the basics.
+
+
+7) Plug-ins
+There is currently no support for any plug-in capabilities. For example,
+if there are plug-in shaders specified for your file, those shaders will be
+ignored.
+
+Workaround: None.
+
+
+8) Image Sequences
+There is no support for image sequences - textures must be static files.
+
+Workaround: None.
+
+
diff --git a/src/classes/org/jdesktop/j3d/examples/lightwave/Viewer.java b/src/classes/org/jdesktop/j3d/examples/lightwave/Viewer.java
new file mode 100644
index 0000000..8959d4d
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/lightwave/Viewer.java
@@ -0,0 +1,209 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.lightwave;
+
+import java.applet.Applet;
+import java.awt.*;
+
+import javax.media.j3d.BranchGroup;
+import javax.media.j3d.Canvas3D;
+import javax.media.j3d.Transform3D;
+import javax.media.j3d.TransformGroup;
+import javax.media.j3d.View;
+import javax.vecmath.Matrix4d;
+
+import com.sun.j3d.loaders.lw3d.Lw3dLoader;
+import com.sun.j3d.loaders.Loader;
+import com.sun.j3d.loaders.Scene;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.SimpleUniverse;
+
+
+/**
+ * This class loads in a Lightwave3D file and displays it in an applet
+ * window. The application is fairly basic; a more complete version
+ * of a Lightwave 3D loader might incorporate features such as
+ * settable clip plane distances and animated views (these are both
+ * possible with the current Lightwave 3D loader, they just need to
+ * be implemented in the application).
+ */
+public class Viewer extends Applet {
+
+ private java.net.URL filename;
+ private SimpleUniverse u;
+
+ public Viewer(java.net.URL url) {
+ filename = url;
+ }
+
+ public Viewer() {}
+
+ public void init() {
+ if (filename == null) {
+ // the path to the file for an applet
+ try {
+ java.net.URL path = getCodeBase();
+ filename = new java.net.URL(path.toString() +
+ "./ballcone.lws");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.err.println(ex.getMessage());
+ ex.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ // Construct the Lw3d loader and load the file
+ Loader lw3dLoader = new Lw3dLoader(Loader.LOAD_ALL);
+ Scene loaderScene = null;
+ try {
+ loaderScene = lw3dLoader.load(filename);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ // Construct the applet canvas
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a basic universe setup and the root of our scene
+ u = new SimpleUniverse(c);
+ BranchGroup sceneRoot = new BranchGroup();
+
+ // Change the back clip distance; the default is small for
+ // some lw3d worlds
+ View theView = u.getViewer().getView();
+ theView.setBackClipDistance(50000f);
+
+ // Now add the scene graph defined in the lw3d file
+ if (loaderScene.getSceneGroup() != null) {
+ // Instead of using the default view location (which may be
+ // completely bogus for the particular file you're loading),
+ // let's use the initial view from the file. We can get
+ // this by getting the view groups from the scene (there's
+ // only one for Lightwave 3D), then using the inverse of the
+ // transform on that view as the transform for the entire scene.
+
+ // First, get the view groups (shouldn't be null unless there
+ // was something wrong in the load
+ TransformGroup viewGroups[] = loaderScene.getViewGroups();
+
+ // Get the Transform3D from the view and invert it
+ Transform3D t = new Transform3D();
+ viewGroups[0].getTransform(t);
+ Matrix4d m = new Matrix4d();
+ t.get(m);
+ m.invert();
+ t.set(m);
+
+ // Now we've got the transform we want. Create an
+ // appropriate TransformGroup and parent the scene to it.
+ // Then insert the new group into the main BranchGroup.
+ TransformGroup sceneTransform = new TransformGroup(t);
+ sceneTransform.addChild(loaderScene.getSceneGroup());
+ sceneRoot.addChild(sceneTransform);
+ }
+
+ // Make the scene graph live by inserting the root into the universe
+ u.addBranchGraph(sceneRoot);
+ }
+
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ /**
+ * The main method of the application takes one argument in the
+ * args array; the filname that you want to load. Note that the
+ * file must be reachable from the directory in which you're running
+ * this application.
+ */
+ public static void main(String args[]) {
+ java.net.URL url = null;
+ java.net.URL pathUrl = null;
+ if (args.length > 0) {
+ try {
+ if ((args[0].indexOf("file:") == 0) ||
+ (args[0].indexOf("http") == 0)) {
+ url = new java.net.URL(args[0]);
+ }
+ else if (args[0].charAt(0) != '/') {
+ url = new java.net.URL("file:./" + args[0]);
+ }
+ else {
+ url = new java.net.URL("file:" + args[0]);
+ }
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.err.println(ex.getMessage());
+ ex.printStackTrace();
+ System.exit(1);
+ }
+ }
+ else {
+ // the path to the image for an application
+ try {
+ url = new java.net.URL("file:./ballcone.lws");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.err.println(ex.getMessage());
+ ex.printStackTrace();
+ System.exit(1);
+ }
+ }
+ new MainFrame(new Viewer(url), 500, 500);
+ }
+}
+
+
+
+
diff --git a/src/classes/org/jdesktop/j3d/examples/lod/LOD.java b/src/classes/org/jdesktop/j3d/examples/lod/LOD.java
new file mode 100644
index 0000000..45381f4
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/lod/LOD.java
@@ -0,0 +1,181 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.lod;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class LOD extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ createLights(objRoot);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objRoot.addChild(objTrans);
+
+ // Create a switch to hold the different levels of detail
+ Switch sw = new Switch(0);
+ sw.setCapability(javax.media.j3d.Switch.ALLOW_SWITCH_READ);
+ sw.setCapability(javax.media.j3d.Switch.ALLOW_SWITCH_WRITE);
+
+
+ // Create several levels for the switch, with less detailed
+ // spheres for the ones which will be used when the sphere is
+ // further away
+ sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 40));
+ sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 20));
+ sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 10));
+ sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 3));
+
+ // Add the switch to the main group
+ objTrans.addChild(sw);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // set up the DistanceLOD behavior
+ float[] distances = new float[3];
+ distances[0] = 5.0f;
+ distances[1] = 10.0f;
+ distances[2] = 25.0f;
+ DistanceLOD lod = new DistanceLOD(distances);
+ lod.addSwitch(sw);
+ lod.setSchedulingBounds(bounds);
+ objTrans.addChild(lod);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ private void createLights(BranchGroup graphRoot) {
+
+ // Create a bounds for the light source influence
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the global, ambient light
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ graphRoot.addChild(aLgt);
+
+ // Set up the directional (infinite) light source
+ Color3f lColor1 = new Color3f(0.9f, 0.9f, 0.9f);
+ Vector3f lDir1 = new Vector3f(1.0f, 1.0f, -1.0f);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ graphRoot.addChild(lgt1);
+ }
+
+
+ public LOD() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // only add zoom mouse behavior to viewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ // add orbit behavior to the ViewingPlatform, but disable rotate
+ // and translate
+ OrbitBehavior orbit = new OrbitBehavior(c,
+ OrbitBehavior.REVERSE_ZOOM |
+ OrbitBehavior.DISABLE_ROTATE |
+ OrbitBehavior.DISABLE_TRANSLATE);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows LOD to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new LOD(), 512, 512);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java b/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java
new file mode 100644
index 0000000..790806c
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java
@@ -0,0 +1,176 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.model_clip;
+
+import com.sun.j3d.utils.behaviors.mouse.*;
+import com.sun.j3d.utils.geometry.Cylinder;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+/**
+ * ModelClipTest draws a cylinder and creates two clip planes
+ * to see the interior of the cylinder.
+ */
+public class ModelClipTest extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph()
+ {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // This Transformgroup is used by the mouse manipulators to
+ // move the CYlinder.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(objTrans);
+
+ //Create Model Clip
+ ModelClip mc = new ModelClip();
+ boolean enables[] = {false, false, false, false, false, false};
+ Vector4d eqn1 = new Vector4d(0.0, 1.0, 0.0, 0.0);
+ Vector4d eqn2 = new Vector4d(1.0, 1.0, 0.0, 0.0);
+ mc.setEnables(enables);
+ mc.setPlane(1, eqn1);
+ mc.setPlane(2, eqn2);
+ mc.setEnable(1, true);
+ mc.setEnable(2, true);
+ mc.setInfluencingBounds(bounds);
+ objTrans.addChild(mc);
+
+ //Create a cylinder
+ PolygonAttributes attr = new PolygonAttributes();
+ attr.setCullFace(PolygonAttributes.CULL_NONE);
+ Appearance ap = new Appearance();
+ Material mat = new Material();
+ mat.setLightingEnable(true);
+ ap.setMaterial(mat);
+ ap.setPolygonAttributes(attr);
+
+ Cylinder CylinderObj = new Cylinder(1.0f, 2.0f, ap);
+ objTrans.addChild(CylinderObj);
+
+ // Create the rotate behavior node
+ MouseRotate behavior = new MouseRotate(objTrans);
+ objTrans.addChild(behavior);
+ behavior.setSchedulingBounds(bounds);
+
+ // Create the zoom behavior node
+ MouseZoom behavior2 = new MouseZoom(objTrans);
+ objTrans.addChild(behavior2);
+ behavior2.setSchedulingBounds(bounds);
+
+ //Shine it with two colored lights.
+ Color3f lColor1 = new Color3f(0.5f, 0.0f, 0.5f);
+ Color3f lColor2 = new Color3f(0.7f, 0.7f, 0.0f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, 1.0f);
+ Vector3f lDir2 = new Vector3f(0.0f, 0.0f, -1.0f);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+ objScale.addChild(lgt1);
+ objScale.addChild(lgt2);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public ModelClipTest (){
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+ public static void main(String argv[])
+ {
+
+ BranchGroup group;
+
+ new MainFrame(new ModelClipTest(), 500, 500);
+ }
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java b/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java
new file mode 100644
index 0000000..be3e832
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java
@@ -0,0 +1,197 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.model_clip;
+
+import com.sun.j3d.utils.behaviors.mouse.*;
+import com.sun.j3d.utils.geometry.Cylinder;
+import com.sun.j3d.utils.geometry.Box;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+/**
+ * ModelClipTest2 draws a cylinder and creates two clip planes
+ * to see the interior of the cylinder. It also has a behavior to
+ * move the clip planes.
+ */
+public class ModelClipTest2 extends Applet {
+
+ private SimpleUniverse u;
+
+ public BranchGroup createSceneGraph()
+ {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ //Shine it with two colored lights.
+ Color3f lColor0 = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f lColor1 = new Color3f(0.5f, 0.0f, 0.5f);
+ Color3f lColor2 = new Color3f(0.7f, 0.7f, 0.0f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, 1.0f);
+ Vector3f lDir2 = new Vector3f(0.0f, 0.0f, -1.0f);
+
+ AmbientLight lgt0 = new AmbientLight(true, lColor2);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2);
+ lgt0.setInfluencingBounds(bounds);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+ objScale.addChild(lgt0);
+ objScale.addChild(lgt1);
+ objScale.addChild(lgt2);
+
+ // Create a Transformgroup for the geometry
+ TransformGroup objRot = new TransformGroup();
+ Transform3D t3d1 = new Transform3D();
+ AxisAngle4f rot1 = new AxisAngle4f(0.0f, 1.0f, 0.0f, 45.0f);
+ t3d1.setRotation(rot1);
+ objRot.setTransform(t3d1);
+ objScale.addChild(objRot);
+
+
+ //Create a cylinder
+ PolygonAttributes attr = new PolygonAttributes();
+ attr.setCullFace(PolygonAttributes.CULL_NONE);
+ Appearance ap = new Appearance();
+ Material mat = new Material();
+ mat.setLightingEnable(true);
+ ap.setMaterial(mat);
+ ap.setPolygonAttributes(attr);
+
+ Cylinder CylinderObj = new Cylinder(0.5f, 2.2f, ap);
+ objRot.addChild(CylinderObj);
+
+ //Create a box
+ Box BoxObj = new Box(0.8f, 0.8f, 0.8f, ap);
+ objRot.addChild(BoxObj);
+
+
+ // This Transformgroup is used by the mouse manipulators to
+ // move the model clip planes.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objRot.addChild(objTrans);
+
+ // Create the rotate behavior node
+ MouseRotate behavior = new MouseRotate(objTrans);
+ objTrans.addChild(behavior);
+ behavior.setSchedulingBounds(bounds);
+
+ // Create the zoom behavior node
+ MouseZoom behavior2 = new MouseZoom(objTrans);
+ objTrans.addChild(behavior2);
+ behavior2.setSchedulingBounds(bounds);
+
+ //Create Model Clip
+ ModelClip mc = new ModelClip();
+ boolean enables[] = {false, false, false, false, false, false};
+ Vector4d eqn = new Vector4d(0.0, 1.0, 1.0, 0.0);
+ mc.setEnables(enables);
+ mc.setPlane(1, eqn);
+ mc.setEnable(1, true);
+ mc.setInfluencingBounds(bounds);
+ objTrans.addChild(mc);
+
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public ModelClipTest2 (){
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+
+ public static void main(String argv[])
+ {
+
+ BranchGroup group;
+
+ new MainFrame(new ModelClipTest2(), 500, 500);
+ }
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/ColorCube.java b/src/classes/org/jdesktop/j3d/examples/morphing/ColorCube.java
new file mode 100644
index 0000000..fd3fbda
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/morphing/ColorCube.java
@@ -0,0 +1,123 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.morphing;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class ColorCube extends QuadArray {
+ private static final float[] verts = {
+ // front face
+ 1.0f, -1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f,
+ -1.0f, -1.0f, 1.0f,
+ // back face
+ -1.0f, -1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ // right face
+ 1.0f, -1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 1.0f,
+ // left face
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, -1.0f,
+ -1.0f, -1.0f, -1.0f,
+ // top face
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, 1.0f,
+ // bottom face
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, 1.0f,
+ };
+
+ private static final float[] colors = {
+ // front face (red)
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ // back face (green)
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ // right face (blue)
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ // left face (yellow)
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ // top face (magenta)
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ // bottom face (cyan)
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ };
+
+ ColorCube() {
+ super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
+
+ setCoordinates(0, verts);
+ setColors(0, colors);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java b/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java
new file mode 100644
index 0000000..0957e19
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java
@@ -0,0 +1,123 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.morphing;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class ColorPyramidDown extends QuadArray {
+ private static final float[] verts = {
+ // front face
+ 0.0f, -1.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f,
+ 0.0f, -1.0f, 0.0f,
+ // back face
+ 0.0f, -1.0f, 0.0f,
+ -1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f,
+ 0.0f, -1.0f, 0.0f,
+ // right face
+ 0.0f, -1.0f, 0.0f,
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 0.0f, -1.0f, 0.0f,
+ // left face
+ 0.0f, -1.0f, 0.0f,
+ -1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, -1.0f,
+ 0.0f, -1.0f, 0.0f,
+ // top face
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, 1.0f,
+ // bottom face
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ };
+
+ private static final float[] colors = {
+ // front face (green)
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ // back face (red)
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ // right face (yellow)
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ // left face (magenta)
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ // top face (blue)
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ // bottom face (cyan)
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ };
+
+ ColorPyramidDown() {
+ super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
+
+ setCoordinates(0, verts);
+ setColors(0, colors);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java b/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java
new file mode 100644
index 0000000..407c8bb
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java
@@ -0,0 +1,125 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.morphing;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class ColorPyramidUp extends QuadArray {
+ private static final float[] verts = {
+ // front face
+ 1.0f, -1.0f, 1.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ -1.0f, -1.0f, 1.0f,
+ // back face
+ -1.0f, -1.0f, -1.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 1.0f, -1.0f, -1.0f,
+ // right face
+ 1.0f, -1.0f, -1.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 1.0f, -1.0f, 1.0f,
+ // left face
+ -1.0f, -1.0f, 1.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ -1.0f, -1.0f, -1.0f,
+ // top face
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ // bottom face
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, 1.0f,
+ };
+
+ private static final float[] colors = {
+
+ // front face (cyan)
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ // back face (magenta)
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ // right face (yellow)
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ // left face (blue)
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ // top face (green)
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ // bottom face (red)
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+
+ };
+
+ ColorPyramidUp() {
+ super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
+
+ setCoordinates(0, verts);
+ setColors(0, colors);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/Morphing.java b/src/classes/org/jdesktop/j3d/examples/morphing/Morphing.java
new file mode 100644
index 0000000..cbca643
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/morphing/Morphing.java
@@ -0,0 +1,262 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.morphing;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.io.*;
+import com.sun.j3d.loaders.objectfile.ObjectFile;
+import com.sun.j3d.loaders.Scene;
+import com.sun.j3d.loaders.ParsingErrorException;
+import com.sun.j3d.loaders.IncorrectFormatException;
+
+public class Morphing extends Applet {
+
+ private java.net.URL[] objFiles = null;
+
+ private SimpleUniverse u = null;
+
+ private BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objScale.addChild(aLgt);
+ objScale.addChild(lgt1);
+
+ //
+ // Create the transform group nodes for the 3 original objects
+ // and the morphed object. Add them to the root of the
+ // branch graph.
+ //
+ TransformGroup objTrans[] = new TransformGroup[4];
+
+ for(int i=0; i<4; i++) {
+ objTrans[i] = new TransformGroup();
+ objScale.addChild(objTrans[i]);
+ }
+
+ Transform3D tr = new Transform3D();
+ Transform3D rotX90 = new Transform3D();
+ rotX90.rotX(90.0 * Math.PI / 180.0);
+
+ objTrans[0].getTransform(tr);
+ tr.setTranslation(new Vector3d(-2.0, 1.5, -2.0));
+ tr.mul(rotX90);
+ objTrans[0].setTransform(tr);
+
+ objTrans[1].getTransform(tr);
+ tr.setTranslation(new Vector3d(0.0, 1.5, -2.0));
+ tr.mul(rotX90);
+ objTrans[1].setTransform(tr);
+
+ objTrans[2].getTransform(tr);
+ tr.setTranslation(new Vector3d(2.0, 1.5, -2.0));
+ tr.mul(rotX90);
+ objTrans[2].setTransform(tr);
+
+ objTrans[3].getTransform(tr);
+ tr.setTranslation(new Vector3d(0.0, -2.0, -2.0));
+ tr.mul(rotX90);
+ objTrans[3].setTransform(tr);
+
+
+ // Now load the object files
+ Scene s[] = new Scene[3];
+ GeometryArray g[] = new GeometryArray[3];
+ Shape3D shape[] = new Shape3D[3];
+ ObjectFile loader = new ObjectFile(ObjectFile.RESIZE);
+ for(int i=0; i<3; i++) {
+ s[i] = null;
+ g[i] = null;
+ shape[i] = null;
+ }
+
+ for(int i=0; i<3;i++) {
+ try {
+ s[i] = loader.load(objFiles[i]);
+ }
+ catch (FileNotFoundException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ catch (ParsingErrorException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ catch (IncorrectFormatException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+
+ BranchGroup b = s[i].getSceneGroup();
+ shape[i] = (Shape3D) b.getChild(0);
+ g[i] = (GeometryArray) shape[i].getGeometry();
+
+ shape[i].setGeometry(g[i]);
+ objTrans[i].addChild(b);
+ }
+
+ //
+ // Create a Morph node, and set the appearance and input geometry
+ // arrays. Set the Morph node's capability bits to allow the weights
+ // to be modified at runtime.
+ //
+ Appearance app = new Appearance();
+ Color3f objColor = new Color3f(1.0f, 0.7f, 0.8f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor, black, 80.0f));
+ Morph morph = new Morph(g, app);
+ morph.setCapability(Morph.ALLOW_WEIGHTS_READ);
+ morph.setCapability(Morph.ALLOW_WEIGHTS_WRITE);
+
+ objTrans[3].addChild(morph);
+
+ // Now create the Alpha object that controls the speed of the
+ // morphing operation.
+ Alpha morphAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 2000, 1000, 200,
+ 2000, 1000, 200);
+
+ // Finally, create the morphing behavior
+ MorphingBehavior mBeh = new MorphingBehavior(morphAlpha, morph);
+ mBeh.setSchedulingBounds(bounds);
+ objScale.addChild(mBeh);
+
+ return objRoot;
+ }
+
+ public Morphing() {}
+
+ public Morphing(java.net.URL[] urls) {
+ objFiles = urls;
+ }
+
+ public void init() {
+ if (objFiles == null) {
+ objFiles = new java.net.URL[3];
+ // the path to the image for an applet
+ String path = getCodeBase().toString();
+ try {
+ objFiles[0] = new java.net.URL(path + "hand1.obj");
+ objFiles[1] = new java.net.URL(path + "hand2.obj");
+ objFiles[2] = new java.net.URL(path + "hand3.obj");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public static void main(String[] args) {
+ java.net.URL[] urls = new java.net.URL[3];
+ // the path to the image file for an application
+ try {
+ urls[0] = new java.net.URL("file:./hand1.obj");
+ urls[1] = new java.net.URL("file:./hand2.obj");
+ urls[2] = new java.net.URL("file:./hand3.obj");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ new MainFrame(new Morphing(urls), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java b/src/classes/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java
new file mode 100644
index 0000000..3353329
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java
@@ -0,0 +1,99 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.morphing;
+
+import java.util.Enumeration;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+// User-defined morphing behavior class
+public class MorphingBehavior extends Behavior {
+
+ Alpha alpha;
+ Morph morph;
+ double weights[];
+
+ WakeupOnElapsedFrames w = new WakeupOnElapsedFrames(0);
+
+ // Override Behavior's initialize method to setup wakeup criteria
+ public void initialize() {
+ alpha.setStartTime(System.currentTimeMillis());
+
+ // Establish initial wakeup criteria
+ wakeupOn(w);
+ }
+
+ // Override Behavior's stimulus method to handle the event
+ public void processStimulus(Enumeration criteria) {
+
+ // NOTE: This assumes 3 objects. It should be generalized to
+ // "n" objects.
+
+ double val = alpha.value();
+ if (val < 0.5) {
+ double a = val * 2.0;
+ weights[0] = 1.0 - a;
+ weights[1] = a;
+ weights[2] = 0.0;
+ }
+ else {
+ double a = (val - 0.5) * 2.0;
+ weights[0] = 0.0;
+ weights[1] = 1.0f - a;
+ weights[2] = a;
+ }
+
+ morph.setWeights(weights);
+
+ // Set wakeup criteria for next time
+ wakeupOn(w);
+ }
+
+ public MorphingBehavior(Alpha a, Morph m) {
+ alpha = a;
+ morph = m;
+ weights = morph.getWeights();
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java b/src/classes/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java
new file mode 100644
index 0000000..e4d86ee
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java
@@ -0,0 +1,194 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.morphing;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Pyramid2Cube extends Applet {
+
+ private SimpleUniverse u = null;
+
+ private BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+
+ // Create a bounds for the background and behavior
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ //
+ // Create the transform group nodes for the 3 original objects
+ // and the morphed object. Add them to the root of the
+ // branch graph.
+ //
+ TransformGroup objTrans[] = new TransformGroup[4];
+
+ for(int i=0; i<4; i++) {
+ objTrans[i] = new TransformGroup();
+ objScale.addChild(objTrans[i]);
+ }
+
+ Transform3D tr = new Transform3D();
+ Transform3D rotY15 = new Transform3D();
+ rotY15.rotY(15.0 * Math.PI / 180.0);
+
+ objTrans[0].getTransform(tr);
+ tr.setTranslation(new Vector3d(-3.0, 1.5, -6.5));
+ tr.mul(rotY15);
+ objTrans[0].setTransform(tr);
+
+ objTrans[1].getTransform(tr);
+ tr.setTranslation(new Vector3d(0.0, 1.5, -6.5));
+ tr.mul(rotY15);
+ objTrans[1].setTransform(tr);
+
+ objTrans[2].getTransform(tr);
+ tr.setTranslation(new Vector3d(3.0, 1.5, -6.5));
+ tr.mul(rotY15);
+ objTrans[2].setTransform(tr);
+
+ objTrans[3].getTransform(tr);
+ tr.setTranslation(new Vector3d(0.0, -2.0, -5.0));
+ tr.mul(rotY15);
+ objTrans[3].setTransform(tr);
+
+ // Now create simple geometries.
+
+ QuadArray g[] = new QuadArray[3];
+ Shape3D shape[] = new Shape3D[3];
+ for(int i=0; i<3; i++) {
+ g[i] = null;
+ shape[i] = null;
+ }
+
+ g[0] = new ColorPyramidUp();
+ g[1] = new ColorCube();
+ g[2] = new ColorPyramidDown();
+
+ Appearance a = new Appearance();
+
+ for(int i=0; i<3;i++) {
+ shape[i] = new Shape3D(g[i],a);
+ objTrans[i].addChild(shape[i]);
+ }
+
+ //
+ // Create a Morph node, and set the appearance and input geometry
+ // arrays. Set the Morph node's capability bits to allow the weights
+ // to be modified at runtime.
+ //
+ Morph morph = new Morph((GeometryArray[]) g, a);
+ morph.setCapability(Morph.ALLOW_WEIGHTS_READ);
+ morph.setCapability(Morph.ALLOW_WEIGHTS_WRITE);
+
+ objTrans[3].addChild(morph);
+
+ // Now create the Alpha object that controls the speed of the
+ // morphing operation.
+ Alpha morphAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 4000, 1000, 500,
+ 4000, 1000, 500);
+
+ // Finally, create the morphing behavior
+ MorphingBehavior mBeh = new MorphingBehavior(morphAlpha, morph);
+ mBeh.setSchedulingBounds(bounds);
+ objScale.addChild(mBeh);
+
+ return objRoot;
+ }
+
+ public Pyramid2Cube() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public static void main(String[] args) {
+ new MainFrame(new Pyramid2Cube(), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/objload/ObjLoad.java b/src/classes/org/jdesktop/j3d/examples/objload/ObjLoad.java
new file mode 100644
index 0000000..dd57983
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/objload/ObjLoad.java
@@ -0,0 +1,287 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.objload;
+
+import com.sun.j3d.loaders.objectfile.ObjectFile;
+import com.sun.j3d.loaders.ParsingErrorException;
+import com.sun.j3d.loaders.IncorrectFormatException;
+import com.sun.j3d.loaders.Scene;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.io.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+public class ObjLoad extends Applet {
+
+ private boolean spin = false;
+ private boolean noTriangulate = false;
+ private boolean noStripify = false;
+ private double creaseAngle = 60.0;
+ private URL filename = null;
+ private SimpleUniverse u;
+ private BoundingSphere bounds;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.7);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(objTrans);
+
+ int flags = ObjectFile.RESIZE;
+ if (!noTriangulate) flags |= ObjectFile.TRIANGULATE;
+ if (!noStripify) flags |= ObjectFile.STRIPIFY;
+ ObjectFile f = new ObjectFile(flags,
+ (float)(creaseAngle * Math.PI / 180.0));
+ Scene s = null;
+ try {
+ s = f.load(filename);
+ }
+ catch (FileNotFoundException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ catch (ParsingErrorException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ catch (IncorrectFormatException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+
+ objTrans.addChild(s.getSceneGroup());
+
+ bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ if (spin) {
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+ }
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objRoot.addChild(bgNode);
+
+ return objRoot;
+ }
+
+ private void usage()
+ {
+ System.out.println(
+ "Usage: java ObjLoad [-s] [-n] [-t] [-c degrees] <.obj file>");
+ System.out.println(" -s Spin (no user interaction)");
+ System.out.println(" -n No triangulation");
+ System.out.println(" -t No stripification");
+ System.out.println(
+ " -c Set crease angle for normal generation (default is 60 without");
+ System.out.println(
+ " smoothing group info, otherwise 180 within smoothing groups)");
+ System.exit(0);
+ } // End of usage
+
+
+
+ public void init() {
+ if (filename == null) {
+ // Applet
+ try {
+ URL path = getCodeBase();
+ filename = new URL(path.toString() + "./galleon.obj");
+ }
+ catch (MalformedURLException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ PlatformGeometry pg = new PlatformGeometry();
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ pg.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f);
+ Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ pg.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ pg.addChild(light2);
+
+ viewingPlatform.setPlatformGeometry( pg );
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ if (!spin) {
+ OrbitBehavior orbit = new OrbitBehavior(c,
+ OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+ }
+
+ u.addBranchGraph(scene);
+ }
+
+ // Caled if running as a program
+ public ObjLoad(String[] args) {
+ if (args.length != 0) {
+ for (int i = 0 ; i < args.length ; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].equals("-s")) {
+ spin = true;
+ } else if (args[i].equals("-n")) {
+ noTriangulate = true;
+ } else if (args[i].equals("-t")) {
+ noStripify = true;
+ } else if (args[i].equals("-c")) {
+ if (i < args.length - 1) {
+ creaseAngle = (new Double(args[++i])).doubleValue();
+ } else usage();
+ } else {
+ usage();
+ }
+ } else {
+ try {
+ if ((args[i].indexOf("file:") == 0) ||
+ (args[i].indexOf("http") == 0)) {
+ filename = new URL(args[i]);
+ }
+ else if (args[i].charAt(0) != '/') {
+ filename = new URL("file:./" + args[i]);
+ }
+ else {
+ filename = new URL("file:" + args[i]);
+ }
+ }
+ catch (MalformedURLException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ // Running as an applet
+ public ObjLoad() {
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+
+ //
+ // The following allows ObjLoad to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new ObjLoad(args), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java
new file mode 100644
index 0000000..503dc42
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java
@@ -0,0 +1,105 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.offscreen_canvas3d;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.awt.event.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+
+class OffScreenCanvas3D extends Canvas3D {
+
+ Raster drawRaster;
+ boolean printing = false;
+
+ public OffScreenCanvas3D(GraphicsConfiguration gconfig, boolean offscreenflag,
+ Raster drawRaster) {
+
+ super(gconfig, offscreenflag);
+ this.drawRaster = drawRaster;
+ }
+
+ public void print(boolean toWait) {
+
+ if (!toWait)
+ printing = true;
+
+ BufferedImage bImage = new BufferedImage(
+ 200, 200 , BufferedImage.TYPE_INT_ARGB);
+
+ ImageComponent2D buffer = new ImageComponent2D(
+ ImageComponent.FORMAT_RGBA, bImage);
+ buffer.setCapability(ImageComponent2D.ALLOW_IMAGE_READ);
+
+ this.setOffScreenBuffer(buffer);
+ this.renderOffScreenBuffer();
+
+ if (toWait) {
+ this.waitForOffScreenRendering();
+ drawOffScreenBuffer();
+ }
+ }
+
+ public void postSwap() {
+
+ if (printing) {
+ super.postSwap();
+ drawOffScreenBuffer();
+ printing = false;
+ }
+ }
+
+ void drawOffScreenBuffer() {
+
+ BufferedImage bImage = this.getOffScreenBuffer().getImage();
+ ImageComponent2D newImageComponent = new ImageComponent2D(
+ ImageComponent.FORMAT_RGBA, bImage);
+
+ drawRaster.setImage(newImageComponent);
+ }
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form
new file mode 100644
index 0000000..39a0712
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <Properties>
+ <Property name="defaultCloseOperation" type="int" value="3"/>
+ <Property name="title" type="java.lang.String" value="Window Title"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="drawingPanel">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[500, 500]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java
new file mode 100644
index 0000000..f432e46
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java
@@ -0,0 +1,219 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.offscreen_canvas3d;
+
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.geometry.ColorCube;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+
+/**
+ * OffScreenTest programs with no UI.
+ */
+public class OffScreenTest extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+ private Raster drawRaster = null;
+
+ private BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // trans object has composited transformation matrix
+ Transform3D trans = new Transform3D();
+ Transform3D rot = new Transform3D();
+
+ trans.rotX(Math.PI/4.0d);
+ rot.rotY(Math.PI/5.0d);
+ trans.mul(rot);
+ trans.setScale(0.7);
+ trans.setTranslation(new Vector3d(-0.4, 0.3, 0.0));
+
+ TransformGroup objTrans = new TransformGroup(trans);
+ objRoot.addChild(objTrans);
+
+ // Create a simple shape leaf node, add it to the scene graph.
+ // ColorCube is a Convenience Utility class
+ objTrans.addChild(new ColorCube(0.4));
+
+ //Create a raster
+ BufferedImage bImage = new BufferedImage(200, 200 ,
+ BufferedImage.TYPE_INT_ARGB);
+ ImageComponent2D buffer =
+ new ImageComponent2D(ImageComponent.FORMAT_RGBA, bImage);
+ buffer.setCapability(ImageComponent2D.ALLOW_IMAGE_READ);
+
+ drawRaster = new Raster(new Point3f(0.0f, 0.0f, 0.0f),
+ Raster.RASTER_COLOR,
+ 0, 0, 200, 200, buffer, null);
+
+ drawRaster.setCapability(Raster.ALLOW_IMAGE_WRITE);
+ Shape3D shape = new Shape3D(drawRaster);
+ objRoot.addChild(shape);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+
+ private OnScreenCanvas3D createOnScreenCanvasAndUniverse() {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ // Create a Canvas3D using the preferred configuration
+ OnScreenCanvas3D onScrCanvas = new OnScreenCanvas3D(config, false);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(onScrCanvas);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ univ.getViewingPlatform().setNominalViewingTransform();
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return onScrCanvas;
+ }
+
+ private OffScreenCanvas3D createOffScreenCanvas() {
+ // request an offscreen Canvas3D with a single buffer configuration
+ GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
+ template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY);
+ GraphicsConfiguration gc =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getBestConfiguration(template);
+
+ // Create a offscreen Canvas3D using the single buffer configuration.
+ OffScreenCanvas3D offScrCanvas =
+ new OffScreenCanvas3D(gc, true, drawRaster);
+
+ return offScrCanvas;
+ }
+
+ /**
+ * Creates new form OffScreenTest
+ */
+ public OffScreenTest() {
+ // Initialize the GUI components
+ initComponents();
+
+ // Create the content branch and add it to the universe
+ scene = createSceneGraph();
+
+ // Create an OnScreenCanvas3D and SimpleUniverse; add canvas to drawing panel
+ OnScreenCanvas3D onScreenCanvas = createOnScreenCanvasAndUniverse();
+ drawingPanel.add(onScreenCanvas, java.awt.BorderLayout.CENTER);
+
+ // Creante an OffScreenCanvas3D
+ OffScreenCanvas3D offScreenCanvas = createOffScreenCanvas();
+
+ // set the offscreen to match the onscreen
+ Screen3D sOn = onScreenCanvas.getScreen3D();
+ Screen3D sOff = offScreenCanvas.getScreen3D();
+ sOff.setSize(sOn.getSize());
+ sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth());
+ sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight());
+
+ // attach the same view to the offscreen canvas
+ View view = univ.getViewer().getView();
+ view.addCanvas3D(offScreenCanvas);
+
+ // tell onscreen about the offscreen so it knows to
+ // render to the offscreen at postswap
+ onScreenCanvas.setOffScreenCanvas(offScreenCanvas);
+
+ univ.addBranchGraph(scene);
+
+ view.stopView();
+ // Make sure that image are render completely
+ // before grab it in postSwap().
+ onScreenCanvas.setImageReady();
+ view.startView();
+ }
+
+ // ----------------------------------------------------------------
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents() {
+ drawingPanel = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("Window Title");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(500, 500));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new OffScreenTest().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java
new file mode 100644
index 0000000..93c3d5b
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java
@@ -0,0 +1,85 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.offscreen_canvas3d;
+
+import com.sun.j3d.utils.geometry.ColorCube;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.BufferedImage;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+
+class OnScreenCanvas3D extends Canvas3D {
+
+ OffScreenCanvas3D c;
+ boolean print = false;
+ boolean imageReady = false;
+
+ public OnScreenCanvas3D(GraphicsConfiguration gconfig, boolean offscreenflag)
+ {
+ super(gconfig, offscreenflag);
+ }
+
+ public void setOffScreenCanvas(OffScreenCanvas3D c)
+ {
+ this.c = c;
+ }
+
+ public void setImageReady() {
+ imageReady = true;
+ }
+
+ public void postSwap()
+ {
+ if (imageReady && !print) {
+ c.print(false);
+ print = true;
+ }
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form
new file mode 100644
index 0000000..54d6721
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <NonVisualComponents>
+ <Menu class="javax.swing.JMenuBar" name="jMenuBar1">
+ <SubComponents>
+ <Menu class="javax.swing.JMenu" name="fileMenu">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="File"/>
+ </Properties>
+ <SubComponents>
+ <MenuItem class="javax.swing.JMenuItem" name="exitMenuItem">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Exit"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exitMenuItemActionPerformed"/>
+ </Events>
+ </MenuItem>
+ </SubComponents>
+ </Menu>
+ </SubComponents>
+ </Menu>
+ </NonVisualComponents>
+ <Properties>
+ <Property name="defaultCloseOperation" type="int" value="3"/>
+ <Property name="title" type="java.lang.String" value="Window Title"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="menuBar" type="java.lang.String" value="jMenuBar1"/>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="guiPanel">
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="North"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JButton" name="myButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Print"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="myButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="4" insetsRight="4" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JPanel" name="drawingPanel">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[500, 500]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java
new file mode 100644
index 0000000..89d6557
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java
@@ -0,0 +1,262 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.offscreen_canvas3d;
+
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.geometry.ColorCube;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.GraphicsConfiguration;
+import javax.swing.JPopupMenu;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+
+/**
+ * PrintFromButton programs with simple UI.
+ */
+public class PrintFromButton extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+ private Raster drawRaster = null;
+ private OffScreenCanvas3D offScreenCanvas = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // trans object has composited transformation matrix
+ Transform3D trans = new Transform3D();
+ Transform3D rot = new Transform3D();
+
+ trans.rotX(Math.PI/4.0d);
+ rot.rotY(Math.PI/5.0d);
+ trans.mul(rot);
+ trans.setScale(0.7);
+ trans.setTranslation(new Vector3d(-0.4, 0.3, 0.0));
+
+ TransformGroup objTrans = new TransformGroup(trans);
+ objRoot.addChild(objTrans);
+
+ // Create a simple shape leaf node, add it to the scene graph.
+ // ColorCube is a Convenience Utility class
+ objTrans.addChild(new ColorCube(0.4));
+
+ //Create a raster
+ BufferedImage bImage = new BufferedImage(200, 200 ,
+ BufferedImage.TYPE_INT_ARGB);
+ ImageComponent2D buffer =
+ new ImageComponent2D(ImageComponent.FORMAT_RGBA, bImage);
+ buffer.setCapability(ImageComponent2D.ALLOW_IMAGE_READ);
+
+ drawRaster = new Raster(new Point3f(0.0f, 0.0f, 0.0f),
+ Raster.RASTER_COLOR,
+ 0, 0, 200, 200, buffer, null);
+
+ drawRaster.setCapability(Raster.ALLOW_IMAGE_WRITE);
+ Shape3D shape = new Shape3D(drawRaster);
+ objRoot.addChild(shape);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ private OnScreenCanvas3D createOnScreenCanvasAndUniverse() {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ // Create a Canvas3D using the preferred configuration
+ OnScreenCanvas3D onScrCanvas = new OnScreenCanvas3D(config, false);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(onScrCanvas);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ univ.getViewingPlatform().setNominalViewingTransform();
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return onScrCanvas;
+ }
+
+ private OffScreenCanvas3D createOffScreenCanvas() {
+ // request an offscreen Canvas3D with a single buffer configuration
+ GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
+ template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY);
+ GraphicsConfiguration gc =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getBestConfiguration(template);
+
+ // Create a offscreen Canvas3D using the single buffer configuration.
+ OffScreenCanvas3D offScrCanvas =
+ new OffScreenCanvas3D(gc, true, drawRaster);
+
+ return offScrCanvas;
+ }
+
+ /**
+ * Creates new form PrintFromButton
+ */
+ public PrintFromButton() {
+ // Initialize the GUI components
+ JPopupMenu.setDefaultLightWeightPopupEnabled(false);
+ initComponents();
+
+ // Create the content branch and add it to the universe
+ scene = createSceneGraph();
+
+ // Create an OnScreenCanvas3D and SimpleUniverse; add canvas to drawing panel
+ OnScreenCanvas3D onScreenCanvas = createOnScreenCanvasAndUniverse();
+ drawingPanel.add(onScreenCanvas, java.awt.BorderLayout.CENTER);
+
+ // Creante an OffScreenCanvas3D
+ offScreenCanvas = createOffScreenCanvas();
+
+ // set the offscreen to match the onscreen
+ Screen3D sOn = onScreenCanvas.getScreen3D();
+ Screen3D sOff = offScreenCanvas.getScreen3D();
+ sOff.setSize(sOn.getSize());
+ sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth());
+ sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight());
+
+ // attach the same view to the offscreen canvas
+ View view = univ.getViewer().getView();
+ view.addCanvas3D(offScreenCanvas);
+
+ univ.addBranchGraph(scene);
+ }
+
+ // ----------------------------------------------------------------
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ guiPanel = new javax.swing.JPanel();
+ myButton = new javax.swing.JButton();
+ drawingPanel = new javax.swing.JPanel();
+ jMenuBar1 = new javax.swing.JMenuBar();
+ fileMenu = new javax.swing.JMenu();
+ exitMenuItem = new javax.swing.JMenuItem();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("Window Title");
+ guiPanel.setLayout(new java.awt.GridBagLayout());
+
+ myButton.setText("Print");
+ myButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ myButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
+ guiPanel.add(myButton, gridBagConstraints);
+
+ getContentPane().add(guiPanel, java.awt.BorderLayout.NORTH);
+
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(500, 500));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ fileMenu.setText("File");
+ exitMenuItem.setText("Exit");
+ exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ exitMenuItemActionPerformed(evt);
+ }
+ });
+
+ fileMenu.add(exitMenuItem);
+
+ jMenuBar1.add(fileMenu);
+
+ setJMenuBar(jMenuBar1);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void myButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_myButtonActionPerformed
+ offScreenCanvas.print(false);
+ }//GEN-LAST:event_myButtonActionPerformed
+
+ private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
+ System.exit(0);
+ }//GEN-LAST:event_exitMenuItemActionPerformed
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new PrintFromButton().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+ private javax.swing.JMenuItem exitMenuItem;
+ private javax.swing.JMenu fileMenu;
+ private javax.swing.JPanel guiPanel;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JButton myButton;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java b/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java
new file mode 100644
index 0000000..0d12bd3
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java
@@ -0,0 +1,196 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.oriented_shape3d;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import com.sun.j3d.utils.behaviors.mouse.*;
+
+/**
+ * MouseRotateY is a Java3D behavior object that lets users control the
+ * rotation of an object via a mouse.
+ * <p>
+ * To use this utility, first create a transform group that this
+ * rotate behavior will operate on. Then,
+ *<blockquote><pre>
+ *
+ * MouseRotateY behavior = new MouseRotateY();
+ * behavior.setTransformGroup(objTrans);
+ * objTrans.addChild(behavior);
+ * behavior.setSchedulingBounds(bounds);
+ *
+ *</pre></blockquote>
+ * The above code will add the rotate behavior to the transform
+ * group. The user can rotate any object attached to the objTrans.
+ */
+
+public class MouseRotateY extends MouseBehavior {
+ double y_angle;
+ double y_factor;
+
+ /**
+ * Creates a rotate behavior given the transform group.
+ * @param transformGroup The transformGroup to operate on.
+ */
+ public MouseRotateY(TransformGroup transformGroup) {
+ super(transformGroup);
+ }
+
+ /**
+ * Creates a default mouse rotate behavior.
+ **/
+ public MouseRotateY() {
+ super(0);
+ }
+
+ /**
+ * Creates a rotate behavior.
+ * Note that this behavior still needs a transform
+ * group to work on (use setTransformGroup(tg)) and
+ * the transform group must add this behavior.
+ * @param flags interesting flags (wakeup conditions).
+ */
+ public MouseRotateY(int flags) {
+ super(flags);
+ }
+
+ public void initialize() {
+ super.initialize();
+ y_angle = 0;
+ y_factor = .03;
+ if ((flags & INVERT_INPUT) == INVERT_INPUT) {
+ invert = true;
+ y_factor *= -1;
+ }
+ }
+
+ public double getYFactor() {
+ return y_factor;
+ }
+
+ public void setFactor( double factor) {
+ y_factor = factor;
+
+ }
+
+
+ public void processStimulus (Enumeration criteria) {
+ WakeupCriterion wakeup;
+ AWTEvent[] event;
+ int id;
+ int dx;
+
+ while (criteria.hasMoreElements()) {
+ wakeup = (WakeupCriterion) criteria.nextElement();
+ if (wakeup instanceof WakeupOnAWTEvent) {
+ event = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
+ for (int i=0; i<event.length; i++) {
+ processMouseEvent((MouseEvent) event[i]);
+
+ if (((buttonPress)&&((flags & MANUAL_WAKEUP) == 0)) ||
+ ((wakeUp)&&((flags & MANUAL_WAKEUP) != 0))){
+
+ id = event[i].getID();
+ if ((id == MouseEvent.MOUSE_DRAGGED) &&
+ !((MouseEvent)event[i]).isMetaDown() &&
+ !((MouseEvent)event[i]).isAltDown()){
+
+ x = ((MouseEvent)event[i]).getX();
+
+ dx = x - x_last;
+
+ if (!reset){
+ y_angle = dx * y_factor;
+
+ transformY.rotY(y_angle);
+
+ transformGroup.getTransform(currXform);
+
+ //Vector3d translation = new Vector3d();
+ //Matrix3f rotation = new Matrix3f();
+ Matrix4d mat = new Matrix4d();
+
+ // Remember old matrix
+ currXform.get(mat);
+
+ // Translate to origin
+ currXform.setTranslation(new Vector3d(0.0,0.0,0.0));
+ if (invert) {
+ currXform.mul(currXform, transformX);
+ currXform.mul(currXform, transformY);
+ } else {
+ currXform.mul(transformX, currXform);
+ currXform.mul(transformY, currXform);
+ }
+
+ // Set old translation back
+ Vector3d translation = new
+ Vector3d(mat.m03, mat.m13, mat.m23);
+ currXform.setTranslation(translation);
+
+ // Update xform
+ transformGroup.setTransform(currXform);
+ }
+ else {
+ reset = false;
+ }
+
+ x_last = x;
+ }
+ else if (id == MouseEvent.MOUSE_PRESSED) {
+ x_last = ((MouseEvent)event[i]).getX();
+ }
+ }
+ }
+ }
+ }
+
+ wakeupOn (mouseCriterion);
+
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java b/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java
new file mode 100644
index 0000000..60333bb
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java
@@ -0,0 +1,297 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.oriented_shape3d;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.event.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.geometry.Cone;
+import com.sun.j3d.utils.geometry.Cylinder;
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.io.*;
+import java.awt.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+
+public class OrientedPtTest extends Applet {
+
+ // setup font stuff
+ private String fontName = "TestFont";
+ private String textString = "OrientedShape3D";
+ float sl = textString.length();
+
+ // paths to texture image files
+ private java.net.URL earthImage = null;
+ private java.net.URL stoneImage = null;
+
+ private SimpleUniverse u;
+
+ public BranchGroup createSceneGraph() {
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ TransformGroup objScale = new TransformGroup();
+ Transform3D textMat = new Transform3D();
+ // Assuming uniform size chars, set scale to fit string in view
+ textMat.setScale(1.2/sl);
+ objScale.setTransform(textMat);
+
+
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objRoot.addChild(objTrans);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ Appearance apText = new Appearance();
+ Material m = new Material();
+ m.setLightingEnable(true);
+ apText.setMaterial(m);
+
+
+ Appearance apEarth= new Appearance();
+ Material mm = new Material();
+ mm.setLightingEnable(true);
+ apEarth.setMaterial(mm);
+
+ Appearance apStone = new Appearance();
+ apStone.setMaterial(mm);
+
+// create 3D text
+ Font3D f3d = new Font3D(new Font(fontName, Font.PLAIN, 2),
+ new FontExtrusion());
+ Point3f textPt = new Point3f( -sl/2.0f, 3.0f, 0.0f);
+ Text3D txt = new Text3D(f3d, textString, textPt);
+ OrientedShape3D textShape = new OrientedShape3D();
+ textShape.setGeometry(txt);
+ textShape.setAppearance(apText);
+
+ textShape.setAlignmentMode(OrientedShape3D.ROTATE_ABOUT_POINT);
+ // text is centered around 0, 3, 0. Make it rotate around 0,5,0
+ Point3f rotationPt = new Point3f(0.0f, 5.0f, 0.0f);
+ textShape.setRotationPoint(rotationPt);
+ objScale.addChild( textShape );
+
+ // also add a small Sphere at the rotation point to
+ // show that we are rotating around the right point
+ Sphere sphere = new Sphere(0.2f);
+ TransformGroup sphereGroup = new TransformGroup();
+ Transform3D sphereXform = new Transform3D();
+ sphereXform.set(new Vector3f(rotationPt));
+ sphereGroup.setTransform(sphereXform);
+ sphereGroup.addChild(sphere);
+ objScale.addChild(sphereGroup);
+
+
+ // Create a simple shape leaf node, add it to the scene graph.
+
+ Transform3D cubeMat = new Transform3D();
+ TransformGroup cubeTrans = new TransformGroup(cubeMat);
+ cubeMat.set(new Vector3d(0.9, 0.0, -1.0));
+ cubeTrans.setTransform(cubeMat);
+ cubeTrans.addChild(new ColorCube(0.3));
+ objTrans.addChild(cubeTrans);
+
+ TextureLoader stoneTex = new TextureLoader(stoneImage, new String("RGB"), this);
+ if (stoneTex != null) apStone.setTexture(stoneTex.getTexture());
+
+ TextureAttributes texAttr = new TextureAttributes();
+ texAttr.setTextureMode(TextureAttributes.REPLACE);
+ apStone.setTextureAttributes(texAttr);
+
+ Transform3D coneMat = new Transform3D();
+ TransformGroup coneTrans = new TransformGroup(coneMat);
+ coneMat.set(new Vector3d(0.0, 0.0, 0.0));
+ coneTrans.setTransform(coneMat);
+ coneTrans.addChild(new Cone(.2f, 0.8f,Cone.GENERATE_NORMALS |
+ Cone.GENERATE_TEXTURE_COORDS, apStone));
+ objTrans.addChild(coneTrans);
+
+ TextureLoader earthTex = new TextureLoader(earthImage, new String("RGB"), this);
+ if (earthTex != null) apEarth.setTexture(earthTex.getTexture());
+ apEarth.setTextureAttributes(texAttr);
+
+ Transform3D cylinderMat = new Transform3D();
+ TransformGroup cylinderTrans = new TransformGroup(cylinderMat);
+ cylinderMat.set(new Vector3d(-0.9, 0.5, -1.0));
+ cylinderTrans.setTransform(cylinderMat);
+ cylinderTrans.addChild(new Cylinder(.35f, 2.0f,Cylinder.GENERATE_NORMALS |
+ Cylinder.GENERATE_TEXTURE_COORDS, apEarth));
+ objTrans.addChild(cylinderTrans);
+
+ objTrans.addChild(objScale);
+
+
+
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objRoot.addChild(bgNode);
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ objRoot.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ objRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ objRoot.addChild(light2);
+
+ apText.setMaterial(mm);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public OrientedPtTest() {
+ }
+
+ public OrientedPtTest(java.net.URL earthURL, java.net.URL stoneURL) {
+ earthImage = earthURL;
+ stoneImage = stoneURL;
+ }
+
+ public void init() {
+ // the paths to the image files for an applet
+ if (earthImage == null) {
+ try {
+ earthImage = new java.net.URL(getCodeBase().toString() +
+ "../images/earth.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ if (stoneImage == null) {
+ try {
+ stoneImage = new java.net.URL(getCodeBase().toString() +
+ "../images/stone.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ setLayout(new BorderLayout());
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ // add orbit behavior to the viewing platform
+ OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows OrientedPtTest to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ java.net.URL earthURL = null;
+ java.net.URL stoneURL = null;
+ try {
+ // the paths to the image files for an application
+ earthURL = new java.net.URL("file:../images/earth.jpg");
+ stoneURL = new java.net.URL("file:../images/stone.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+
+ new MainFrame(new OrientedPtTest(earthURL, stoneURL), 400, 400);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java b/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java
new file mode 100644
index 0000000..191c375
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java
@@ -0,0 +1,305 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.oriented_shape3d;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import com.sun.j3d.utils.behaviors.mouse.*;
+
+public class OrientedTest extends Applet {
+
+ // setup font stuff
+ private String fontName = "TestFont";
+ private String textString = "OrientedShape3D";
+ float sl = textString.length();
+
+ // paths to texture image files
+ private java.net.URL earthImage = null;
+ private java.net.URL stoneImage = null;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ TransformGroup objScale = new TransformGroup();
+ Transform3D textMat = new Transform3D();
+ // Assuming uniform size chars, set scale to fit string in view
+ textMat.setScale(1.2/sl);
+ objScale.setTransform(textMat);
+
+
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objRoot.addChild(objTrans);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ Appearance apText = new Appearance();
+ Material m = new Material();
+ m.setLightingEnable(true);
+ apText.setMaterial(m);
+
+
+ Appearance apEarth= new Appearance();
+ Material mm = new Material();
+ mm.setLightingEnable(true);
+ apEarth.setMaterial(mm);
+
+ Appearance apStone = new Appearance();
+ apStone.setMaterial(mm);
+
+// create 3D text
+ Font3D f3d = new Font3D(new Font(fontName, Font.PLAIN, 2),
+ new FontExtrusion());
+ Text3D txt = new Text3D(f3d, textString,
+ new Point3f( -sl/2.0f, 3.0f, 0.0f));
+ OrientedShape3D textShape = new OrientedShape3D();
+ textShape.setGeometry(txt);
+ textShape.setAppearance(apText);
+ textShape.setAlignmentAxis( 0.0f, 1.0f, 0.0f);
+ objScale.addChild( textShape );
+
+
+ // Create a simple shape leaf node, add it to the scene graph.
+
+ Transform3D cubeMat = new Transform3D();
+ TransformGroup cubeTrans = new TransformGroup(cubeMat);
+ cubeMat.set(new Vector3d(0.9, 0.0, -1.0));
+ cubeTrans.setTransform(cubeMat);
+ cubeTrans.addChild(new ColorCube(0.3));
+ objTrans.addChild(cubeTrans);
+
+ TextureLoader stoneTex = new TextureLoader(stoneImage, new String("RGB"), this);
+ if (stoneTex != null) apStone.setTexture(stoneTex.getTexture());
+
+ TextureAttributes texAttr = new TextureAttributes();
+ texAttr.setTextureMode(TextureAttributes.MODULATE);
+ apStone.setTextureAttributes(texAttr);
+
+
+ Transform3D coneMat = new Transform3D();
+ TransformGroup coneTrans = new TransformGroup(coneMat);
+ coneMat.set(new Vector3d(0.0, 0.0, 0.0));
+ coneTrans.setTransform(coneMat);
+ coneTrans.addChild(new Cone(.2f, 0.8f,Cone.GENERATE_NORMALS |
+ Cone.GENERATE_TEXTURE_COORDS, apStone));
+ objTrans.addChild(coneTrans);
+
+ TextureLoader earthTex = new TextureLoader(earthImage, new String("RGB"), this);
+ if (earthTex != null) apEarth.setTexture(earthTex.getTexture());
+
+ apEarth.setTextureAttributes(texAttr);
+
+ Transform3D cylinderMat = new Transform3D();
+ TransformGroup cylinderTrans = new TransformGroup(cylinderMat);
+ cylinderMat.set(new Vector3d(-0.9, 0.5, -1.0));
+ cylinderTrans.setTransform(cylinderMat);
+ cylinderTrans.addChild(new Cylinder(.35f, 2.0f,Cylinder.GENERATE_NORMALS |
+ Cylinder.GENERATE_TEXTURE_COORDS, apEarth));
+ objTrans.addChild(cylinderTrans);
+
+ objTrans.addChild(objScale);
+
+
+
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objRoot.addChild(bgNode);
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ objRoot.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ objRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ objRoot.addChild(light2);
+
+ apText.setMaterial(mm);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public OrientedTest() {
+ }
+
+ public OrientedTest(java.net.URL earthURL, java.net.URL stoneURL) {
+ earthImage = earthURL;
+ stoneImage = stoneURL;
+ }
+
+ public void init() {
+ // the paths to the image files for an applet
+ if (earthImage == null) {
+ try {
+ earthImage = new java.net.URL(getCodeBase().toString() +
+ "../images/earth.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ if (stoneImage == null) {
+ try {
+ stoneImage = new java.net.URL(getCodeBase().toString() +
+ "../images/stone.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c, 4);
+
+ // add mouse behaviors to ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ // there is a special rotate behavior, so can't use the utility
+ // method
+ MouseRotateY rotate = new MouseRotateY(MouseRotateY.INVERT_INPUT);
+ rotate.setTransformGroup(viewingPlatform.getMultiTransformGroup().
+ getTransformGroup(0));
+ BranchGroup rotateBG = new BranchGroup();
+ rotateBG.addChild(rotate);
+ viewingPlatform.addChild(rotateBG);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotate.setSchedulingBounds(bounds);
+
+ MouseZoom zoom =
+ new MouseZoom(c, MouseZoom.INVERT_INPUT);
+ zoom.setTransformGroup(viewingPlatform.getMultiTransformGroup().
+ getTransformGroup(1));
+ zoom.setSchedulingBounds(bounds);
+ BranchGroup zoomBG = new BranchGroup();
+ zoomBG.addChild(zoom);
+ viewingPlatform.addChild(zoomBG);
+
+ MouseTranslate translate =
+ new MouseTranslate(c, MouseTranslate.INVERT_INPUT);
+ translate.setTransformGroup(viewingPlatform.getMultiTransformGroup().
+ getTransformGroup(2));
+ translate.setSchedulingBounds(bounds);
+ BranchGroup translateBG = new BranchGroup();
+ translateBG.addChild(translate);
+ viewingPlatform.addChild(translateBG);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows OrientedTest to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ java.net.URL earthURL = null;
+ java.net.URL stoneURL = null;
+ try {
+ // the paths to the image files for an application
+ earthURL = new java.net.URL("file:../images/earth.jpg");
+ stoneURL = new java.net.URL("file:../images/stone.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+
+ new MainFrame(new OrientedTest(earthURL, stoneURL), 400, 400);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/package_info/PackageInfo.java b/src/classes/org/jdesktop/j3d/examples/package_info/PackageInfo.java
new file mode 100644
index 0000000..2cc6cad
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/package_info/PackageInfo.java
@@ -0,0 +1,95 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.package_info;
+
+public class PackageInfo {
+ public PackageInfo() {
+ ClassLoader classLoader = getClass().getClassLoader();
+
+ pkgInfo(classLoader, "javax.vecmath", "Point3d");
+ pkgInfo(classLoader, "javax.media.j3d", "SceneGraphObject");
+ pkgInfo(classLoader, "com.sun.j3d.utils.universe", "SimpleUniverse");
+ //pkgInfo(classLoader, "com.sun.j3d.loaders.vrml97", "VrmlLoader");
+ }
+
+ static void pkgInfo(ClassLoader classLoader,
+ String pkgName,
+ String className) {
+
+ try {
+ classLoader.loadClass(pkgName + "." + className);
+
+ Package p = Package.getPackage(pkgName);
+ if (p == null) {
+ System.out.println("WARNING: Package.getPackage(" +
+ pkgName +
+ ") is null");
+ }
+ else {
+ System.out.println(p);
+ System.out.println("Specification Title = " +
+ p.getSpecificationTitle());
+ System.out.println("Specification Vendor = " +
+ p.getSpecificationVendor());
+ System.out.println("Specification Version = " +
+ p.getSpecificationVersion());
+
+ System.out.println("Implementation Vendor = " +
+ p.getImplementationVendor());
+ System.out.println("Implementation Version = " +
+ p.getImplementationVersion());
+ }
+ }
+ catch (ClassNotFoundException e) {
+ System.out.println("Unable to load " + pkgName);
+ }
+
+ System.out.println();
+ }
+
+ public static void main(String[] args) {
+ new PackageInfo();
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/package_info/QueryProperties.java b/src/classes/org/jdesktop/j3d/examples/package_info/QueryProperties.java
new file mode 100644
index 0000000..fb34965
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/package_info/QueryProperties.java
@@ -0,0 +1,150 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.package_info;
+
+import java.util.*;
+import javax.media.j3d.*;
+import java.awt.GraphicsEnvironment;
+import java.awt.GraphicsConfiguration;
+import com.sun.j3d.utils.universe.*;
+
+public class QueryProperties {
+ public static void printProps(Map map, String[] propList) {
+ // Create an alphabetical list of keys
+ List keyList = new ArrayList(map.keySet());
+ Collections.sort(keyList);
+ Iterator it;
+
+ // Collection used to remember the properties we've already
+ // printed, so we don't print them twice
+ HashSet hs = new HashSet();
+
+ // Print out the values for the caller-specified properties
+ String key;
+ for (int i = 0; i < propList.length; i++) {
+ int len = propList[i].length();
+ int idxWild = propList[i].indexOf('*');
+ if (idxWild < 0) {
+ key = propList[i];
+ if (!hs.contains(key)) {
+ System.out.println(key + " = " + map.get(key));
+ hs.add(key);
+ }
+ }
+ else if (idxWild == len-1) {
+ String pattern = propList[i].substring(0, len-1);
+ it = keyList.iterator();
+ while (it.hasNext()) {
+ key = (String)it.next();
+ if (key.startsWith(pattern) && !hs.contains(key)) {
+ System.out.println(key + " = " + map.get(key));
+ hs.add(key);
+ }
+ }
+ }
+ else {
+ System.out.println(propList[i] +
+ " = ERROR: KEY WITH EMBEDDED WILD CARD IGNORED");
+ }
+ }
+
+ // Print out the values for those properties not already printed
+ it = keyList.iterator();
+ while (it.hasNext()) {
+ key = (String)it.next();
+ if (!hs.contains(key)) {
+ System.out.println(key + " = " + map.get(key));
+ }
+ }
+
+ }
+
+ public static void main(String[] args) {
+ VirtualUniverse vu = new VirtualUniverse();
+ Map vuMap = vu.getProperties();
+ final String[] vuPropList = {
+ "j3d.version",
+ "j3d.vendor",
+ "j3d.specification.version",
+ "j3d.specification.vendor",
+ "j3d.*"
+ // Just print all other properties in alphabetical order
+ };
+
+ printProps(vuMap, vuPropList);
+ System.out.println();
+
+ GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
+
+ /* We need to set this to force choosing a pixel format
+ that support the canvas.
+ */
+ template.setStereo(template.PREFERRED);
+ template.setSceneAntialiasing(template.PREFERRED);
+
+ GraphicsConfiguration config =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getBestConfiguration(template);
+
+ Map c3dMap = new Canvas3D(config).queryProperties();
+ final String[] c3dPropList = {
+ "native.*",
+ "doubleBufferAvailable",
+ "stereoAvailable",
+ "sceneAntialiasing*",
+ "compressedGeometry.majorVersionNumber",
+ "compressedGeometry.minorVersionNumber",
+ "compressedGeometry.*",
+ "textureUnitStateMax",
+ "textureWidthMax",
+ "textureHeightMax",
+ // Just print all other properties in alphabetical order
+ };
+
+ printProps(c3dMap, c3dPropList);
+
+ System.exit(0);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/BoltCG.java b/src/classes/org/jdesktop/j3d/examples/picking/BoltCG.java
new file mode 100644
index 0000000..5fcb9fd
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/BoltCG.java
@@ -0,0 +1,359 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class BoltCG extends CompressedGeometry {
+
+ BoltCG() {
+ super(cgHeader, cgData) ;
+ }
+
+ private static final byte cgData[] = {
+ 25, 0, -120, 16, -124, 64, 33, -35,
+ 0, 67, 60, 48, -121, 90, 1, 3,
+ 116, -62, 25, 105, -60, 60, -32, 8,
+ 5, -58, 16, -9, -114, 32, -1, -104,
+ 67, 16, 0, -117, -128, 97, 40, 62,
+ -62, -128, -122, 5, 67, 48, 10, -76,
+ -32, 21, 1, 6, 40, 10, -128, 86,
+ -123, 24, -96, 76, 65, 74, 88, 2,
+ -117, -80, -59, 21, 113, -118, -40, -28,
+ 21, 110, 6, 40, 27, 64, 81, 23,
+ -124, -7, 47, 54, 13, -3, -4, 69,
+ 40, 25, -69, -99, -123, 64, 8, 48,
+ 3, 64, 16, 23, 16, 97, -39, 8,
+ -20, -125, 0, 36, 2, 1, -123, 2,
+ 8, -120, 48, 27, 122, 91, 65, -67,
+ 108, 18, 26, 13, -12, -35, 95, -48,
+ 107, 63, -5, 91, -46, 12, 84, -44,
+ -53, -120, 54, -45, -98, 115, 64, -69,
+ 92, 126, -55, 1, 6, -80, 34, -49,
+ -24, 53, -30, 61, -19, 9, 6, -76,
+ 10, -115, -24, 53, 87, -54, -2, -127,
+ 113, 68, -15, -33, 16, 97, -9, 113,
+ -54, -30, 12, 75, 34, -48, -48, 107,
+ 86, -32, -10, -125, 97, -42, 19, -78,
+ 12, 0, -48, 4, 4, 68, 8, 12,
+ -67, -69, 32, -64, 9, 0, 0, 92,
+ 65, -121, 116, 42, 10, 13, 98, -52,
+ -97, 16, 34, 104, 114, 75, 66, 12,
+ -45, 11, -82, 32, -34, -74, -127, -15,
+ 6, 74, 51, 70, -81, 32, -42, 27,
+ 105, 13, 6, -97, 13, 111, -24, 22,
+ -12, 22, -19, -95, 6, -49, -85, -48,
+ 16, 107, 2, 44, -8, -125, 6, 73,
+ -123, -97, 16, 37, 40, 68, -22, -30,
+ 12, 58, 97, 80, -112, 104, -16, -104,
+ -72, -125, 122, -38, 22, -12, 25, -114,
+ -39, 124, 64, -111, -115, -112, -49, -24,
+ 53, -34, 85, -23, 5, 6, -82, -26,
+ 15, 104, 54, 1, -31, 62, 32, 68,
+ -17, 100, -58, 84, 27, 33, -54, -66,
+ -125, 55, -2, -89, 32, -119, 122, -73,
+ -25, -36, 105, -128, 8, 53, -128, 2,
+ 76, -71, 9, -56, -128, 30, 112, -59,
+ -48, 96, -37, 0, 0, 0, 9, -112,
+ 28, -117, 100, 64, 127, 58, 113, -58,
+ 13, 96, 0, -109, 46, 70, 50, 80,
+ 103, -88, 56, -86, 13, 96, 0, -109,
+ 46, 67, 114, -112, 95, -74, 49, 84,
+ 49, -74, -72, 15, 96, 2, 80, 6,
+ 55, 80, 0, -36, 82, 0, 40, 3,
+ 108, 1, -58, -95, -63, -84, 0, 18,
+ 101, -56, -74, 87, 10, 56, 39, 31,
+ -32, -43, -32, 9, 50, -28, 87, 46,
+ -125, 28, -61, -117, -48, 107, 0, 4,
+ -103, 114, 19, -105, -65, -98, 117, -60,
+ 32, -63, -84, 0, 18, 101, -116, -74,
+ 45, 1, -15, 1, -57, 0, -29, -116,
+ 26, -64, 1, 38, 92, -116, 101, 111,
+ 79, 124, 113, 83, -6, -68, 8, 37,
+ -36, -83, -4, -93, -4, 109, 46, 55,
+ 6, -81, 0, 73, -105, 33, -71, 63,
+ -57, -40, -36, 82, 28, 26, -64, 1,
+ 38, 92, -117, 100, -113, 71, 71, 113,
+ -2, 13, 96, 0, -109, 46, 69, 114,
+ 47, -41, -99, -72, -67, 6, -80, 0,
+ 73, -107, -63, 72, -64, -113, -83, 99,
+ 72, 53, 97, -6, 65, 57, -67, 60,
+ -38, -26, -63, -78, 105, 11, 112, 85,
+ 110, 101, -95, 58, -128, 16, 107, -125,
+ 90, -60, 3, 0, 0, 1, 0, 32,
+ 64, 67, -32, -54, -41, -103, 113, 6,
+ -55, -92, 45, -63, 85, -71, -106, -34,
+ -22, 0, 55, -79, -36, -28, 62, -95,
+ -68, 97, -73, -41, -70, -122, -13, 117,
+ -50, 94, -22, 32, 80, 21, 77, -39,
+ 6, 0, 48, 6, 2, 10, 13, 61,
+ 106, -104, 80, 32, -68, -125, 64, -75,
+ 100, 17, 91, -78, 90, -67, -42, 24,
+ 55, 27, -39, 61, 0, -56, 63, -40,
+ -71, -95, -124, 49, 74, 37, 3, 7,
+ -83, 118, -18, 13, -79, 30, -96, -126,
+ 80, 77, 53, 19, -32, -47, -121, -103,
+ 104, -122, 82, 89, -19, 56, 92, 45,
+ -96, -73, 42, -128, 16, 109, -120, -11,
+ 4, 18, -126, 105, -88, 126, 70, -127,
+ -56, -24, 48, -43, -36, 20, -25, -48,
+ -60, -115, -4, -98, -42, -31, -84, 8,
+ -35, -13, 59, -96, -36, 11, 1, 64,
+ 69, 65, -126, 80, -85, 10, 4, 22,
+ -48, 97, 109, -42, -114, 71, 112, -106,
+ -58, -51, 6, 104, 48, 82, 8, -19,
+ -74, -36, -81, -100, -56, -122, 85, 34,
+ -111, -37, 125, -83, 103, 65, -89, 125,
+ -30, -15, 36, -20, -5, 81, -63, 68,
+ 27, -17, -89, -83, 3, -63, -89, 33,
+ -24, 66, 0, 7, 50, 45, 2, -56,
+ 17, 6, -99, -9, -117, -60, -109, -77,
+ -19, 122, 5, 14, 96, 110, 114, 71,
+ -92, 117, 39, 107, 93, -50, 105, 49,
+ 110, -75, 80, 46, -125, -68, -18, -125,
+ 80, 60, 10, 1, -111, 6, -76, 10,
+ 48, -96, 65, 105, 6, -120, 27, 8,
+ 68, -77, -109, -59, 90, -64, 16, 106,
+ -61, -12, -26, 17, 26, 10, 54, -53,
+ 40, -88, 1, 6, -14, 124, 52, 32,
+ -39, 13, -117, 66, 13, 63, -111, -80,
+ -96, 65, 117, 6, 103, -11, -120, 104,
+ 54, -49, 116, 92, 65, -102, -84, -125,
+ 50, 12, 87, -109, 67, 64, -124, 106,
+ -22, -22, 12, 28, -24, -48, -48, 109,
+ 94, -22, -48, -125, 10, -96, 75, -120,
+ 17, 39, -119, 104, 65, -92, -110, 68,
+ 36, 27, 99, -87, -73, -96, -56, -42,
+ -85, 18, 12, 8, 3, -22, 0, 28,
+ 1, 120, 34, -112, -6, -81, 52, -64,
+ 4, 24, -88, 0, 0, 14, 0, -104,
+ 39, 32, 44, 23, -98, -125, 6, 44,
+ 0, 0, 3, -128, 38, 22, -56, 95,
+ 13, -25, 24, 49, 80, 0, 0, 28,
+ 1, 48, -58, -28, -38, -113, 42, -125,
+ 21, 0, 0, 1, -80, 19, 70, -24,
+ 73, -46, -13, 80, -32, -59, 64, 0,
+ 0, 108, 7, -94, -37, -127, -1, 30,
+ 127, -125, 21, 0, 0, 1, -64, 30,
+ -118, -18, -124, -124, 121, 122, 12, 84,
+ 0, 0, 7, 0, 78, 19, -81, -32,
+ 99, -56, 65, -125, 22, 0, 0, 1,
+ -64, 30, 11, 110, 64, 117, 0, 0,
+ 2, -106, 48, 106, 2, 56, -102, 99,
+ 126, 15, 53, 37, 65, -81, -8, -30,
+ 104, -36, -75, -8, -98, 82, 28, 24,
+ -88, 0, 0, 13, -128, -104, 91, 93,
+ -20, -41, -97, -32, -59, 64, 0, 0,
+ 112, 7, -94, -69, 31, 56, -98, 94,
+ -125, 21, 0, 0, 1, -64, 24, 77,
+ -96, -39, -12, 65, -125, 41, 86, -79,
+ 58, 14, -56, 87, 102, -112, 105, -50,
+ 18, -42, 11, 91, 10, -54, -9, 6,
+ 61, -1, -87, 3, 51, 55, -14, 86,
+ 108, 80, 111, -5, -18, -110, 55, 34,
+ 112, -43, 114, -123, 6, 1, 63, 9,
+ 32, -11, 21, 28, 87, 36, 4, 32,
+ -56, 83, -3, 36, -82, -1, -60, -86,
+ -31, -63, -88, -40, 98, 73, -99, -72,
+ 71, 27, 59, 6, 3, 38, -110, 12,
+ 111, -92, 4, -39, -8, 49, -111, 74,
+ -112, 51, 28, -18, -90, -64, 37, 6,
+ 80, -54, -38, -51, 106, -93, 73, -80,
+ 5, 8, 50, 119, 84, -116, 47, 110,
+ 123, -10, -60, 45, 6, 45, 104, 81,
+ -116, 106, 15, 126, -40, -40, 48, 101,
+ 42, -30, 109, 90, -16, 69, 123, -81,
+ -47, 6, 112, 0, 0, 9, 1, 4,
+ 78, 1, 17, -114, -67, 6, 12, -32,
+ 0, 0, 18, 2, 9, 108, -111, -28,
+ 29, 113, -125, 56, 0, 0, 4, -128,
+ -124, 99, 119, 92, 87, 85, 65, -100,
+ 0, 0, 2, 64, 106, 53, -112, 31,
+ 101, -80, 30, 13, -35, -80, 85, -86,
+ -95, -63, -109, -1, 117, -46, -38, 46,
+ -94, -70, 127, 6, -112, 0, 0, 119,
+ 1, 124, -82, 39, 15, 46, -113, 65,
+ -92, 0, 0, 29, -128, 127, 19, -67,
+ -4, -112, -82, -127, 6, 13, 40, 0,
+ 0, -18, 2, -15, 108, -81, -40, 29,
+ 49, -125, 72, 0, 0, 59, 0, -70,
+ 99, 9, -61, -106, -91, 65, -112, 31,
+ 102, -44, 27, 62, -118, 116, 65, -92,
+ 0, 0, 29, -64, 117, 65, -100, 0,
+ 0, 2, 64, 122, 27, -111, -127, -35,
+ -75, 33, -63, -80, 8, -92, 34, -40,
+ -52, 86, -70, -1, 6, 108, 0, 0,
+ 10, 1, 4, -82, 122, 114, -114, -81,
+ 65, -100, 0, 0, 2, 64, 115, 26,
+ -113, -107, -98, -115, -46, -95, -63, -71,
+ 0, 0, 28, -128, 87, 65, -123, -57,
+ -69, -22, 12, 4, 9, -32, 118, 65,
+ -128, 24, 7, -128, -96, -127, 27, -128,
+ 101, -12, 27, 36, 13, -93, -96, -50,
+ -29, 89, -31, 6, -114, 0, 0, 29,
+ -96, 48, -96, 65, -7, 6, -4, 72,
+ 30, -79, 32, -56, 32, 59, -32, 60,
+ 96, 23, -48, 110, -124, 50, -80, -127,
+ 116, -126, -89, 100, 25, -128, 0, 120,
+ 15, 72, 51, 119, -74, 52, 32, -38,
+ -8, -94, -70, 5, 65, -123, 30, 16,
+ 104, -96, 0, 1, -36, 3, 42, 13,
+ -1, 127, 124, 26, -122, -64, 5, -22,
+ -4, 74, 12, 0, 68, -102, -48, 99,
+ 117, 1, 73, 6, -72, -55, -17, -120,
+ 54, 115, -83, -3, 73, 6, -46, 15,
+ -85, -88, 50, 112, -91, 104, 65, -110,
+ 43, 22, -12, 27, 27, 83, 104, 65,
+ -114, -126, -105, -64, -119, -33, 105, -120,
+ -71, 76, 0, 65, -81, -99, -54, 82,
+ 13, 3, 78, 81, 80, 107, -25, 76,
+ -122, -125, 0, -60, 23, -28, 10, -17,
+ -97, 42, -24, -125, 112, 0, 0, 56,
+ -128, -76, -125, 32, -43, -89, -92, 27,
+ -65, 50, -99, -112, 96, 1, 0, -32,
+ 40, -96, 72, 49, -107, 57, 6, -34,
+ -109, 104, 40, 51, 12, 68, 67, 64,
+ -128, 98, 11, -78, 12, -64, 16, 24,
+ 7, -108, 25, -64, 0, 0, 9, -128,
+ -16, 109, 72, 0, 0, 14, -48, 30,
+ -20, 56, 55, -23, 7, 43, -96, -54,
+ -29, -35, 97, 6, -88, 69, 13, 8,
+ 49, 69, -46, -6, -127, 14, 68, -125,
+ -34, 80, 103, 0, 0, 0, 36, 2,
+ 58, 12, 110, 53, -44, 80, 110, -112,
+ 112, -54, -125, 127, -33, -40, 80, 32,
+ -68, -125, 59, -18, -74, 36, 25, 0,
+ 0, 0, 7, -66, 3, -14, 13, -1,
+ -12, 31, 104, 64, -118, 46, -105, 100,
+ 24, 1, 32, 104, 14, -120, 55, 32,
+ 0, 3, -112, 15, -29, 85, 84, -127,
+ 5, -120, 9, 65, -112, 0, 0, 0,
+ 123, -32, 63, 32, -38, -57, 127, 55,
+ -44, 24, -97, 40, 18, -4, -125, 105,
+ 56, -15, 95, 80, 96, -68, 16, -93,
+ 122, 5, 110, -88, 40, 32, -64, 20,
+ 113, -11, 6, 11, -59, 8, -69, 32,
+ -64, 12, 0, -64, 111, 64, -83, -43,
+ 7, 100, 24, -128, -96, 88, 12, 104,
+ 53, -4, 0, 0, 0, -124, 7, -64,
+ -118, -33, -106, -102, -13, -84, 0, 65,
+ -100, 0, 0, 0, -104, 9, 72, 50,
+ 13, 56, 126, 65, -70, -4, -6, -49,
+ -88, 50, 112, -39, -59, -115, 6, -83,
+ 1, -13, 1, -53, 0, -8, -125, 37,
+ 13, 34, -41, 16, 107, -25, 116, -122,
+ -125, 0, -60, 7, -16, -118, 102, 102,
+ -36, -66, -118, 0, 65, -67, -1, -30,
+ 10, 12, -99, 74, 94, -48, 110, -31,
+ 108, 104, 65, -102, -87, 103, -60, 8,
+ 34, -100, 36, -2, -125, 124, -84, -5,
+ -97, 16, 98, 43, -46, 27, 34, 12,
+ 127, -101, 127, 64, -80, -47, -16, -19,
+ 8, 53, -33, 88, -8, -125, 20, 109,
+ 19, 95, -48, 111, -111, -1, -117, 66,
+ 13, -57, 92, 63, -96, 93, -104, -99,
+ 119, -60, 24, 84, -16, 82, -8, -125,
+ 3, 80, 2, -38, 16, 103, -116, 101,
+ -19, 2, -18, 110, -26, 68, 24, -117,
+ -98, -56, -125, 5, -64, -35, -112, 96,
+ 4, 0, 32, 63, -102, 89, 15, 119,
+ -122, 112, 12, 32, -38, -68, 70, -110,
+ 91, -114, -68, 111, 2, 16, 96, -65,
+ -23, -123, 2, 13, 7, 118, -36, 104,
+ -127, 46, -26, -117, -92, -19, 36, 102,
+ 0, -128, -64, 61, -61, 84, 87, -73,
+ 74, 32, -24, 50, 11, 10, 111, 57,
+ -79, -36, -28, 10, 93, 24, 4, 22,
+ 106, -32, -42, 17, -42, -29, -104, -37,
+ 74, 105, -73, -9, -48, 112, -35, -82,
+ 107, 119, 73, 10, -33, 78, -4, -79,
+ -97, 96, -54, -14, 54, -128, 58, 97,
+ 8, 111, 4, 3, -50, -37, -53, 64,
+ -124, 0, 14, -103, 65, -41, -127, 8,
+ 53, 6, -14, 65, 65, -97, -48, 115,
+ 113, -51, -74, 42, 50, 82, 57, 40,
+ -86, -53, -100, -41, -66, -74, 106, -125,
+ 82, 116, -39, -48, 38, 51, 107, 121,
+ 44, 88, -28, 34, 96, 4, -78, 4,
+ 75, 118, -64, 16, 96, 4, -127, -96,
+ 45, -110, 88, 14, -31, 3, 0, 65,
+ -65, -128, 10, 25, 44, -61, 81, -40,
+ -16, 3, -85, -100, 0, 20, 6, -12,
+ 3, 49, -63, -107, 14, 15, 71, -16,
+ 99, 19, -81, -37, -102, -15, -37, 32,
+ -21, -7, 6, -91, -81, 91, -119, -4,
+ 88, -77, -20, 26, -49, -96, -54, 23,
+ 112, -72, -41, -35, 64, 8, 53, 11,
+ 14, 102, 65, -123, -35, -52, -94, 55,
+ 24, -7, -45, -72, -75, -123, 0, 0,
+ 22, -64, 111, -16, 2, 13, 97, -46,
+ 48, -96, 65, 0, 86, 40, 32, -120,
+ 21, -124, -115, 46, 54, 29, -69, 11,
+ 88, 0, -96, 96, 11, -32, 60, 20,
+ -94, 25, 99, 53, 97, -125, 8, 91,
+ -48, 2, 101, 113, -54, -128, -20, 0,
+ 10, -85, -70, -117, 50, 32, 1, 6,
+ 75, 84, 46, -99, -38, -53, -51, 9,
+ -59, -59, 52, 25, 121, 16, 0, 119,
+ 27, -114, -108, 39, 21, 4, -111, -26,
+ 116, 64, 2, 13, 121, -104, 105, 63,
+ -115, 58, -42, 122, -125, 106, -15, 25,
+ -112, 99, 35, -32, 8, 5, -96, 0
+ } ;
+
+ private static final CompressedGeometryHeader cgHeader ;
+
+ static {
+ cgHeader = new CompressedGeometryHeader() ;
+ cgHeader.majorVersionNumber = 1 ;
+ cgHeader.minorVersionNumber = 0 ;
+ cgHeader.minorMinorVersionNumber = 1 ;
+ cgHeader.bufferType = CompressedGeometryHeader.TRIANGLE_BUFFER ;
+ cgHeader.bufferDataPresent = CompressedGeometryHeader.NORMAL_IN_BUFFER ;
+ cgHeader.start = 0 ;
+ cgHeader.size = cgData.length ;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/ColorCube.java b/src/classes/org/jdesktop/j3d/examples/picking/ColorCube.java
new file mode 100644
index 0000000..02e6807
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/ColorCube.java
@@ -0,0 +1,123 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class ColorCube extends QuadArray {
+ private static final float[] verts = {
+ // front face
+ 1.0f, -1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f,
+ -1.0f, -1.0f, 1.0f,
+ // back face
+ -1.0f, -1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ // right face
+ 1.0f, -1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 1.0f,
+ // left face
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, -1.0f,
+ -1.0f, -1.0f, -1.0f,
+ // top face
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, 1.0f,
+ // bottom face
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, 1.0f,
+ };
+
+ private static final float[] colors = {
+ // front face (red)
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ // back face (green)
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ // right face (blue)
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ // left face (yellow)
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ // top face (magenta)
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ // bottom face (cyan)
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ };
+
+ ColorCube() {
+ super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
+
+ setCoordinates(0, verts);
+ setColors(0, colors);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java b/src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java
new file mode 100644
index 0000000..094c0b0
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java
@@ -0,0 +1,123 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class ColorPyramidDown extends QuadArray {
+ private static final float[] verts = {
+ // front face
+ 0.0f, -1.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f,
+ 0.0f, -1.0f, 0.0f,
+ // back face
+ 0.0f, -1.0f, 0.0f,
+ -1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f,
+ 0.0f, -1.0f, 0.0f,
+ // right face
+ 0.0f, -1.0f, 0.0f,
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 0.0f, -1.0f, 0.0f,
+ // left face
+ 0.0f, -1.0f, 0.0f,
+ -1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, -1.0f,
+ 0.0f, -1.0f, 0.0f,
+ // top face
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, 1.0f,
+ // bottom face
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ };
+
+ private static final float[] colors = {
+ // front face (green)
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ // back face (red)
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ // right face (yellow)
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ // left face (magenta)
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ // top face (blue)
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ // bottom face (cyan)
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ };
+
+ ColorPyramidDown() {
+ super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
+
+ setCoordinates(0, verts);
+ setColors(0, colors);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java b/src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java
new file mode 100644
index 0000000..737baf2
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java
@@ -0,0 +1,125 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class ColorPyramidUp extends QuadArray {
+ private static final float[] verts = {
+ // front face
+ 1.0f, -1.0f, 1.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ -1.0f, -1.0f, 1.0f,
+ // back face
+ -1.0f, -1.0f, -1.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 1.0f, -1.0f, -1.0f,
+ // right face
+ 1.0f, -1.0f, -1.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 1.0f, -1.0f, 1.0f,
+ // left face
+ -1.0f, -1.0f, 1.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ -1.0f, -1.0f, -1.0f,
+ // top face
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ // bottom face
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, 1.0f,
+ };
+
+ private static final float[] colors = {
+
+ // front face (cyan)
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ 0.0f, 1.0f, 1.0f,
+ // back face (magenta)
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ 1.0f, 0.0f, 1.0f,
+ // right face (yellow)
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+ // left face (blue)
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f,
+ // top face (green)
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ // bottom face (red)
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f,
+
+ };
+
+ ColorPyramidUp() {
+ super(24, QuadArray.COORDINATES | QuadArray.COLOR_3);
+
+ setCoordinates(0, verts);
+ setColors(0, colors);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/Cube.java b/src/classes/org/jdesktop/j3d/examples/picking/Cube.java
new file mode 100644
index 0000000..e87d7c4
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/Cube.java
@@ -0,0 +1,110 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Cube extends Shape3D {
+ private static final float[] verts = {
+ // front face
+ 1.0f, -1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f,
+ -1.0f, -1.0f, 1.0f,
+ // back face
+ -1.0f, -1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ // right face
+ 1.0f, -1.0f, -1.0f,
+ 1.0f, 1.0f, -1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 1.0f,
+ // left face
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, 1.0f, 1.0f,
+ -1.0f, 1.0f, -1.0f,
+ -1.0f, -1.0f, -1.0f,
+ // top face
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, 1.0f,
+ // bottom face
+ -1.0f, -1.0f, 1.0f,
+ -1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, 1.0f,
+ };
+
+ private static final Vector3f[] normals = {
+ new Vector3f( 0.0f, 0.0f, 1.0f), // front face
+ new Vector3f( 0.0f, 0.0f, -1.0f), // back face
+ new Vector3f( 1.0f, 0.0f, 0.0f), // right face
+ new Vector3f(-1.0f, 0.0f, 0.0f), // left face
+ new Vector3f( 0.0f, 1.0f, 0.0f), // top face
+ new Vector3f( 0.0f, -1.0f, 0.0f), // bottom face
+ };
+
+ public Cube() {
+ super();
+
+ int i;
+
+ QuadArray cube = new QuadArray(24, QuadArray.COORDINATES |
+ QuadArray.NORMALS);
+
+ cube.setCoordinates(0, verts);
+ for (i = 0; i < 24; i++) {
+ cube.setNormal(i, normals[i/4]);
+ }
+
+ cube.setCapability(Geometry.ALLOW_INTERSECT);
+ setGeometry(cube);
+ setAppearance(new Appearance());
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/CubeIQA.java b/src/classes/org/jdesktop/j3d/examples/picking/CubeIQA.java
new file mode 100644
index 0000000..dca3bf4
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/CubeIQA.java
@@ -0,0 +1,138 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class CubeIQA extends IndexedQuadArray {
+ CubeIQA() {
+ super(8, GeometryArray.COORDINATES | GeometryArray.COLOR_3, 24);
+
+
+ Point3f verts[] = new Point3f[8];
+ Color3f colors[] = new Color3f[8];
+
+ verts[0] = new Point3f(1.0f, 1.0f, 1.0f);
+ verts[1] = new Point3f(-1.0f, 1.0f, 1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f, 1.0f);
+ verts[3] = new Point3f( 1.0f,-1.0f, 1.0f);
+ verts[4] = new Point3f( 1.0f, 1.0f,-1.0f);
+ verts[5] = new Point3f( -1.0f, 1.0f,-1.0f);
+ verts[6] = new Point3f( -1.0f,-1.0f,-1.0f);
+ verts[7] = new Point3f( 1.0f,-1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+ colors[4] = new Color3f(1.0f, 0.0f, 1.0f);
+ colors[5] = new Color3f(0.0f, 1.0f, 1.0f);
+ colors[6] = new Color3f(0.0f, 1.0f, 1.0f);
+ colors[7] = new Color3f(0.0f, 1.0f, 1.0f);
+
+ int pntsIndex[] = new int[24];
+ int clrsIndex[] = new int[24];
+
+ pntsIndex[0] = 0;
+ clrsIndex[0] = 0;
+ pntsIndex[1] = 3;
+ clrsIndex[1] = 0;
+ pntsIndex[2] = 7;
+ clrsIndex[2] = 0;
+ pntsIndex[3] = 4;
+ clrsIndex[3] = 0;
+
+ pntsIndex[4] = 1;
+ clrsIndex[4] = 1;
+ pntsIndex[5] = 5;
+ clrsIndex[5] = 1;
+ pntsIndex[6] = 6;
+ clrsIndex[6] = 1;
+ pntsIndex[7] = 2;
+ clrsIndex[7] = 1;
+
+ pntsIndex[8] = 0;
+ clrsIndex[8] = 2;
+ pntsIndex[9] = 4;
+ clrsIndex[9] = 2;
+ pntsIndex[10] = 5;
+ clrsIndex[10] = 2;
+ pntsIndex[11] = 1;
+ clrsIndex[11] = 2;
+
+ pntsIndex[12] = 3;
+ clrsIndex[12] = 3;
+ pntsIndex[13] = 2;
+ clrsIndex[13] = 3;
+ pntsIndex[14] = 6;
+ clrsIndex[14] = 3;
+ pntsIndex[15] = 7;
+ clrsIndex[15] = 3;
+
+ pntsIndex[16] = 0;
+ clrsIndex[16] = 4;
+ pntsIndex[17] = 1;
+ clrsIndex[17] = 4;
+ pntsIndex[18] = 2;
+ clrsIndex[18] = 4;
+ pntsIndex[19] = 3;
+ clrsIndex[19] = 4;
+
+ pntsIndex[20] = 7;
+ clrsIndex[20] = 5;
+ pntsIndex[21] = 6;
+ clrsIndex[21] = 5;
+ pntsIndex[22] = 5;
+ clrsIndex[22] = 5;
+ pntsIndex[23] = 4;
+ clrsIndex[23] = 5;
+
+ setCoordinates(0, verts);
+ setCoordinateIndices(0, pntsIndex);
+ setColors(0, colors);
+ setColorIndices(0, clrsIndex);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/CubeQA.java b/src/classes/org/jdesktop/j3d/examples/picking/CubeQA.java
new file mode 100644
index 0000000..9760578
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/CubeQA.java
@@ -0,0 +1,135 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class CubeQA extends QuadArray {
+ CubeQA() {
+ super(24, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
+
+
+ Point3f verts[] = new Point3f[8];
+ Color3f colors[] = new Color3f[6];
+
+ verts[0] = new Point3f(1.0f, 1.0f, 1.0f);
+ verts[1] = new Point3f(-1.0f, 1.0f, 1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f, 1.0f);
+ verts[3] = new Point3f( 1.0f,-1.0f, 1.0f);
+ verts[4] = new Point3f( 1.0f, 1.0f,-1.0f);
+ verts[5] = new Point3f( -1.0f, 1.0f,-1.0f);
+ verts[6] = new Point3f( -1.0f,-1.0f,-1.0f);
+ verts[7] = new Point3f( 1.0f,-1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+ colors[4] = new Color3f(1.0f, 0.0f, 1.0f);
+ colors[5] = new Color3f(0.0f, 1.0f, 1.0f);
+
+ Point3f pnts[] = new Point3f[24];
+ Color3f clrs[] = new Color3f[24];
+
+ pnts[0] = verts[0];
+ clrs[0] = colors[0];
+ pnts[1] = verts[3];
+ clrs[1] = colors[0];
+ pnts[2] = verts[7];
+ clrs[2] = colors[0];
+ pnts[3] = verts[4];
+ clrs[3] = colors[0];
+
+ pnts[4] = verts[1];
+ clrs[4] = colors[1];
+ pnts[5] = verts[5];
+ clrs[5] = colors[1];
+ pnts[6] = verts[6];
+ clrs[6] = colors[1];
+ pnts[7] = verts[2];
+ clrs[7] = colors[1];
+
+ pnts[8] = verts[0];
+ clrs[8] = colors[2];
+ pnts[9] = verts[4];
+ clrs[9] = colors[2];
+ pnts[10] = verts[5];
+ clrs[10] = colors[2];
+ pnts[11] = verts[1];
+ clrs[11] = colors[2];
+
+ pnts[12] = verts[3];
+ clrs[12] = colors[3];
+ pnts[13] = verts[2];
+ clrs[13] = colors[3];
+ pnts[14] = verts[6];
+ clrs[14] = colors[3];
+ pnts[15] = verts[7];
+ clrs[15] = colors[3];
+
+ pnts[16] = verts[0];
+ clrs[16] = colors[4];
+ pnts[17] = verts[1];
+ clrs[17] = colors[4];
+ pnts[18] = verts[2];
+ clrs[18] = colors[4];
+ pnts[19] = verts[3];
+ clrs[19] = colors[4];
+
+ pnts[20] = verts[7];
+ clrs[20] = colors[5];
+ pnts[21] = verts[6];
+ clrs[21] = colors[5];
+ pnts[22] = verts[5];
+ clrs[22] = colors[5];
+ pnts[23] = verts[4];
+ clrs[23] = colors[5];
+
+
+ setCoordinates(0, pnts);
+ setColors(0, clrs);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/GullCG.java b/src/classes/org/jdesktop/j3d/examples/picking/GullCG.java
new file mode 100644
index 0000000..b208b3a
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/GullCG.java
@@ -0,0 +1,578 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class GullCG extends CompressedGeometry {
+
+ GullCG() {
+ super(cgHeader, cgData) ;
+ }
+
+ private static final byte cgData[] = {
+ 25, 0, -120, 16, -58, -52, 33, -35,
+ -128, 67, -36, 0, -127, -72, 97, 14,
+ 64, 2, 29, 104, 4, 2, -45, 8,
+ 125, -89, 16, 51, -116, 33, -1, -104,
+ 71, -64, 48, -106, 31, 1, 32, -52,
+ 2, -127, 6, 5, 5, 32, 10, -78,
+ -128, 20, 14, 6, 40, 74, -128, 81,
+ -43, 24, -94, 44, 1, 86, -104, 98,
+ -96, 49, 5, 34, 112, 10, -68, -29,
+ 21, -115, -56, 40, 8, -64, 81, -74,
+ -128, -90, 13, 49, 71, 30, 2, -81,
+ -68, -30, -62, 122, 56, 37, -107, 60,
+ -109, 120, 0, 0, 26, -32, 18, 85,
+ -128, 14, -16, 71, -13, 66, -33, 103,
+ 127, -81, 78, -61, -106, -112, 0, 1,
+ -32, 13, -86, -96, 4, -103, -36, 59,
+ -23, 25, 39, 18, 11, 122, -80, 1,
+ -34, -22, -112, -109, -80, -71, -7, -39,
+ -40, 0, -127, 0, 0, 0, 0, 43,
+ 97, -102, 118, 16, 83, -32, -121, -87,
+ -32, -86, -4, 32, 121, 8, 33, -48,
+ -100, -39, 64, 0, 0, 50, 0, -47,
+ -9, -97, -118, 53, 75, -122, 89, -54,
+ -10, 8, 0, 69, -98, 0, 0, 54,
+ 3, -67, 0, 29, -17, 2, 64, 0,
+ 5, 126, -93, -56, -31, 15, 74, -95,
+ -128, 5, -64, 0, 3, -46, 8, 0,
+ 36, 0, 0, 58, 93, -92, 0, 0,
+ 30, 0, 87, 4, 0, 23, 4, 68,
+ 36, 64, 30, -17, -25, -121, -40, 22,
+ 13, 48, 78, -43, 73, -64, -10, 48,
+ 51, -25, -1, -82, -65, 3, 55, -71,
+ 41, 124, -50, -118, -64, 4, -102, 112,
+ 0, 1, -20, 5, 98, 59, -58, -95,
+ -87, 42, -9, -112, -99, -107, -91, -11,
+ 127, 5, 36, -46, -112, 121, 9, -39,
+ -17, -1, -41, 0, 0, 0, 112, 4,
+ -121, -19, -124, -16, -44, 66, -40, 36,
+ 116, -83, -96, -128, 7, -37, 100, -37,
+ 121, 11, 123, -81, -106, 43, 82, 14,
+ -85, -8, 41, -95, 67, 81, 18, 125,
+ 15, 39, -114, -88, 63, -10, 0, -11,
+ 5, 4, 73, -38, 13, 80, -64, 7,
+ 64, 56, 14, -56, 108, 3, -64, 96,
+ 5, -33, 81, 24, 11, -115, 26, -95,
+ -104, 95, -69, -95, -112, 15, 0, -128,
+ 40, 30, 67, -27, 1, 107, -55, 102,
+ -39, 97, 67, 103, 66, 79, 67, 37,
+ -60, 62, -95, -88, -32, 105, 72, 106,
+ -113, -59, -108, 54, -64, 43, 50, 9,
+ 86, 30, 45, 72, 101, 31, -51, -120,
+ 106, -8, 75, -24, 98, 111, -106, -12,
+ 54, 104, 54, 47, 87, -115, -61, -106,
+ 64, -47, 13, -80, 10, -116, -122, 39,
+ -3, 118, -7, 0, 0, 0, 0, 42,
+ -13, -118, 27, 96, 9, 27, -20, 71,
+ -8, -96, -50, 61, 111, 87, 102, -83,
+ -93, -54, 47, -37, 51, -113, 27, 122,
+ 98, -52, -91, -75, 1, 53, -96, 8,
+ 97, -120, 54, -44, 55, -1, -10, 105,
+ -108, -84, -4, -101, -64, 67, 41, -4,
+ 105, 67, 117, -60, 92, 67, 115, -4,
+ -65, 124, -125, 90, 64, 118, -85, 97,
+ 67, 39, 126, 96, 67, 78, 80, 65,
+ -15, 12, -57, 61, 94, 67, 50, 3,
+ -93, 33, -107, -2, -44, 16, 91, -34,
+ -115, -88, 109, 24, 75, -120, 109, -113,
+ -108, 20, 49, 52, 59, 122, 25, 51,
+ -29, 23, -85, -39, 33, -50, -28, 104,
+ -122, -16, 2, 0, -128, 90, 67, 20,
+ 1, -93, 124, -122, 31, 91, 113, -59,
+ 13, -55, -7, 121, 12, -57, 10, -10,
+ -122, 120, 0, 1, -8, 8, -56, 33,
+ -49, -59, 94, -78, -45, -85, 6, -33,
+ 105, -55, -121, -77, 99, -113, 91, 105,
+ -2, 77, -37, 70, -118, -2, 52, 102,
+ -122, -45, -120, -66, -122, 25, -7, 65,
+ 65, 19, 67, -69, 33, -92, 1, 0,
+ 0, 23, 16, -37, 31, 40, 113, -90,
+ 120, 118, -84, -48, -55, -17, -37, 16,
+ -59, 62, -88, 28, -126, 21, 70, 1,
+ -108, 3, 80, 1, -96, 45, 107, -115,
+ 124, 58, -60, 102, -128, 0, 7, 64,
+ 27, -60, 125, -107, 127, 42, -40, -83,
+ 57, -15, -71, 1, -32, -50, -60, 42,
+ 123, 106, 60, -16, -32, -66, 85, 26,
+ -14, -31, 82, -20, -49, -128, -120, 94,
+ -64, 0, -25, 50, 85, 26, -52, -80,
+ 23, -21, 7, -120, 1, 118, 53, -55,
+ 75, -83, -96, 2, 24, -16, 0, 0,
+ 0, 4, 18, -77, 92, -101, -64, 8,
+ 84, 72, -22, -33, 85, -126, -42, -69,
+ -41, -79, -49, -69, 126, -128, 5, 0,
+ -1, -128, 125, 54, 0, -53, 47, 110,
+ 91, -59, 64, 13, 119, 115, -59, 63,
+ 93, -28, -6, -23, -61, -128, 1, 40,
+ 0, 0, 80, 75, 64, -18, -33, -123,
+ -2, -117, -74, -116, 26, -106, -80, 6,
+ 91, -70, 21, -23, -44, 0, -121, 12,
+ 7, 64, 0, 5, 38, -73, 118, -79,
+ -114, 104, 118, 0, -5, 87, 2, 85,
+ -46, 94, 115, -112, -117, 72, 124, 100,
+ -32, 106, 106, 81, -98, -121, -100, 116,
+ 76, -121, -23, -112, 40, 43, 40, -92,
+ 57, -96, 4, 121, 47, -29, -65, 81,
+ -26, 2, -128, 16, 6, 62, -85, 86,
+ -67, -8, 74, -35, -77, -62, -5, -81,
+ -106, 56, 0, 0, 31, 1, -91, -48,
+ 0, 67, 27, -62, 100, 43, 80, 68,
+ 61, -48, 1, 24, 0, 45, 1, -16,
+ 7, 18, 1, -23, -88, -84, 127, -6,
+ 11, 37, -98, 14, 57, 107, -61, -52,
+ -114, -128, 1, 91, -92, -95, -82, -128,
+ 16, -64, 1, 108, 0, -128, 55, 111,
+ -101, 96, -80, 61, -90, -94, 122, 49,
+ -21, 14, -2, -73, 99, 115, 81, 11,
+ 90, -118, 74, -99, 30, -9, -9, 67,
+ -57, 80, 42, 79, -14, 3, -86, -91,
+ -94, 51, -1, 83, 64, -118, 50, 53,
+ -59, 74, -89, 126, -23, 32, 13, 57,
+ 40, -123, 76, 97, -41, 91, -115, -23,
+ 107, -83, -37, 81, 67, 27, -73, -113,
+ 58, 22, -80, 4, 88, 64, 109, -10,
+ -64, 14, -80, -19, -43, 15, 62, -80,
+ -116, -14, -121, -11, 110, -25, 38, -109,
+ 3, 55, -103, 85, -65, -79, -117, -37,
+ 66, -102, 97, -70, -123, 43, 104, -128,
+ 21, 100, 40, 71, -55, -125, 104, 33,
+ -43, 82, 84, -102, 7, -3, -32, -114,
+ 20, -37, -27, -4, -107, 116, 67, 3,
+ -7, -91, -9, -99, -25, -44, -71, -57,
+ 4, 5, -75, 74, 0, 1, 107, -120,
+ -19, -92, 21, -66, 100, 8, -124, -6,
+ -79, 18, -44, -27, 12, 12, -112, -32,
+ -108, -68, 99, 123, -89, -39, 98, -53,
+ 51, -10, -128, 10, 42, -48, -9, -108,
+ -34, -100, -7, -52, -123, -39, 100, -46,
+ 85, 45, 16, 0, 12, 97, -58, -25,
+ 32, 111, -32, 0, -48, 0, -48, 10,
+ -73, 86, -18, 104, 114, -102, -80, 32,
+ 0, 88, 0, 64, 7, -25, -127, 66,
+ -6, -75, 74, 73, 78, -51, -125, 4,
+ -103, -88, 1, 78, -62, 54, 84, 90,
+ -14, 32, 35, -18, -40, -67, -44, 106,
+ -102, -128, 2, 107, -24, -124, -64, 66,
+ -51, 15, 100, -87, 44, 0, 70, 125,
+ -120, 95, 33, 50, 123, 70, 83, 0,
+ -115, 122, 22, -102, 35, 92, -112, 94,
+ -87, -121, -66, -64, -105, -65, -15, 17,
+ -22, 122, -80, 33, 94, -5, 5, 75,
+ -35, 114, 65, 99, 99, 94, 28, -52,
+ -3, -77, 42, -16, -24, -87, 84, 12,
+ -76, 76, 90, 110, -120, 0, 86, -36,
+ -95, 85, 0, -122, -62, -125, 97, 67,
+ 13, 0, -127, -78, -19, 63, -3, -46,
+ 80, 0, -84, 0, 10, -128, 46, 3,
+ 40, 4, 55, 114, -8, -38, 16, -59,
+ -12, 84, -90, -35, -83, 111, 64, 21,
+ -128, 3, 96, 30, 3, -112, 12, -111,
+ -120, 13, -24, 14, -32, 5, 29, 16,
+ 1, 12, 123, -6, -60, 86, 82, 25,
+ 59, -56, 11, -74, -16, 4, 0, -104,
+ -91, 0, 16, -53, 59, 29, 101, 43,
+ 119, -41, -23, -100, 6, 74, 81, 56,
+ 10, -6, 32, 1, 91, -27, -31, -124,
+ 5, -40, -22, -90, 46, -78, -128, 5,
+ 99, -64, 0, 0, 0, 19, -128, 33,
+ -106, 5, -44, -26, -57, -97, -113, -64,
+ 20, -93, 72, 2, 55, 48, 8, 111,
+ 80, 31, -32, 31, -16, 12, -30, -26,
+ -88, 9, -69, -128, 8, 98, 3, 64,
+ 120, 5, -67, 118, -12, 59, -118, -122,
+ -115, 122, -6, -122, -125, -95, -77, -95,
+ -105, 73, -28, -6, -122, -86, -127, 51,
+ -95, -105, 125, -22, -6, -122, -38, -31,
+ -65, 84, -86, -14, 95, 71, -97, 67,
+ 111, -66, -81, -47, -124, 92, 22, 1,
+ -43, 16, 1, 13, 97, -18, -63, -82,
+ -46, -120, 106, -110, -122, -17, 120, 97,
+ -87, 82, 67, -99, 75, -48, -33, 95,
+ 79, 2, -32, -32, -104, 13, 41, 0,
+ 8, 103, 79, -105, -115, 112, 112, 70,
+ 3, 21, 84, 51, -101, -53, 18, 8,
+ 14, -62, -83, 72, 100, 72, 72, -24,
+ 102, 71, -73, -117, 17, 30, -65, -32,
+ -40, 36, 4, 46, -51, 76, 44, 96,
+ -44, 0, -57, 102, 54, -31, -2, 80,
+ 0, -71, 98, -72, 80, 46, 82, -64,
+ 8, 96, -80, 0, 32, 0, 16, 8,
+ 55, 106, -98, -121, -19, 64, 11, -108,
+ 36, 103, 8, -88, 8, 0, 46, -116,
+ -101, 104, -128, 50, -54, 112, 93, 73,
+ 64, 0, 115, -128, 0, 3, -32, 14,
+ -100, 25, 96, 0, -66, 0, 0, 22,
+ 49, -64, 12, -76, -124, 35, -95, 56,
+ 1, -10, 0, 11, -32, 122, 1, 98,
+ 20, 114, -38, 16, -18, -124, -32, 7,
+ -40, 0, 47, -128, 0, 5, 104, 97,
+ -53, 8, 127, -70, 35, -128, 29, -32,
+ 0, -66, 0, 0, 20, 7, -17, 104,
+ 124, -70, 47, -34, 0, 11, -32, 0,
+ 1, 93, 124, -78, -121, -29, -93, 56,
+ 0, 22, 0, 11, -32, 0, 1, 82,
+ -58, 122, -38, 31, 110, -101, 125, -128,
+ 2, -8, 0, 0, 86, -26, 28, -74,
+ -121, -29, -92, 56, 1, -106, 0, 11,
+ -32, 0, 1, -2, -104, 0, 35, 53,
+ -127, 65, -82, 34, 38, -51, -74, -34,
+ 0, -71, 123, 66, 111, -63, -24, 16,
+ 1, 12, 0, 17, 0, 0, 21, 5,
+ -48, -125, 109, 48, 7, -118, -125, 83,
+ -68, 10, 115, -112, 1, 0, -128, 18,
+ -47, -89, 61, 121, -86, 77, 58, 16,
+ 109, 92, 65, 86, 127, -82, -100, 31,
+ 96, 0, 64, 0, 0, 30, -7, 68,
+ -116, 32, 0, 3, -32, 28, 72, 13,
+ -110, -125, 43, 0, 17, 107, -64, 23,
+ -92, 0, 46, -64, 1, -96, 13, 1,
+ 91, -112, 1, 12, 5, -2, -66, -122,
+ -110, -104, 81, 19, 30, -2, 60, 2,
+ 18, 96, 48, -112, 20, 51, 16, 38,
+ -51, 126, 67, 56, 33, -82, -78, -87,
+ -117, -10, 10, -52, -86, -18, -97, 120,
+ 62, -47, 67, -9, -86, 81, -17, 0,
+ 8, 0, 24, 5, -127, -5, -38, 0,
+ 47, 67, -9, -128, 4, 0, 0, 2,
+ -80, -1, 97, 7, -9, -82, 81, -53,
+ 0, 8, 0, 0, 5, 4, 112, 3,
+ -19, -96, -14, -11, -56, 57, 96, 1,
+ 0, 0, 0, -82, -116, 0, 125, -108,
+ 31, 30, -71, 71, -68, 0, 32, 0,
+ 0, 21, 7, -53, 104, 61, -67, 35,
+ 0, 5, 96, 1, 0, 0, 0, -84,
+ 3, 45, -96, -8, -11, 12, 0, 21,
+ -128, 4, 0, 0, 3, -8, 15, -77,
+ -64, -108, 16, -30, 14, 61, 105, -40,
+ -81, 27, 124, -75, 64, 40, 6, -11,
+ -54, 32, -32, 1, 0, 0, 0, -111,
+ -63, -106, -116, -125, 115, 5, 0, 33,
+ 76, 0, 1, -64, 61, -96, 25, 26,
+ -116, 24, 37, 66, -113, -55, 42, 77,
+ 19, -35, -4, -73, -111, -110, -14, 12,
+ -23, 12, 0, 101, -91, 0, 0, 1,
+ 0, 104, 70, 0, 43, -39, -99, -46,
+ 78, 45, -5, 58, -30, 2, -127, 27,
+ 44, -22, 80, -118, 53, -24, 58, -3,
+ -17, -76, -90, 95, 18, 55, -16, -39,
+ -4, -121, -55, -25, -11, -38, 85, 68,
+ 60, -76, 15, -5, 124, 40, 0, 86,
+ -14, 12, -2, 3, 124, -16, 63, 0,
+ -69, -91, 102, 2, -128, 16, 6, 48,
+ 31, 43, 94, -4, 50, 42, 14, 90,
+ -126, -95, 107, -18, -96, 0, -102, 71,
+ -11, -68, 16, -37, 11, -59, 122, -2,
+ 64, 1, -64, 59, 1, -38, 24, 80,
+ -48, 5, 64, 0, 15, -46, 104, -82,
+ -57, -19, -4, -115, 115, 112, 92, 20,
+ -28, -3, -127, 64, 125, -64, 127, -64,
+ 56, -125, -113, 74, 118, 43, 78, -35,
+ 107, 47, -18, 91, -121, -111, 0, 0,
+ 0, 126, -128, 63, -23, 31, 102, -65,
+ 32, 53, -30, -104, 102, 86, -16, -16,
+ 8, 86, 2, -20, 31, 24, -11, -56,
+ 1, 78, 0, 16, -127, -104, 10, 18,
+ 102, -51, 8, 122, 0, 86, 0, 19,
+ 1, -120, 10, -32, 34, -55, 65, 111,
+ 64, 16, 119, -128, 5, -128, 98, 3,
+ -82, -103, 100, -64, 0, 7, -80, 31,
+ -111, -128, 11, -108, 89, 16, 106, -107,
+ -56, 1, 118, -75, -10, 121, -92, 0,
+ -69, 121, 5, 32, -79, 43, -104, 2,
+ -20, 123, -2, -51, 72, 1, 118, -6,
+ 40, -5, -105, 48, 2, 24, 56, 0,
+ 4, 0, 4, 2, -15, 90, 90, 93,
+ -4, 1, -117, 86, -87, -89, 67, 0,
+ 86, -98, -94, 121, 1, -66, -34, 0,
+ -64, 18, 10, 86, -40, 21, 115, 0,
+ 70, -28, 1, -22, 1, -14, 0, -126,
+ 33, 12, -87, 38, -3, -30, -104, -28,
+ 124, 89, -63, -58, 77, -76, -79, -89,
+ 98, 8, -64, 7, 0, 56, 11, -62,
+ 59, -45, 18, 46, -62, -51, -128, 14,
+ 0, 96, 25, -128, -33, 93, 64, 45,
+ -35, -101, 120, 31, 0, -96, 58, -128,
+ -122, -120, 7, 0, 0, 1, -39, 12,
+ 0, 124, 2, 0, -80, 70, -36, -127,
+ 119, 16, -122, -16, 62, 0, -128, 126,
+ -19, 54, 70, 121, 108, 26, 17, -117,
+ 107, -52, -30, 35, -36, 19, 93, -128,
+ 28, 102, -39, -122, -61, 118, 1, 12,
+ 0, 28, 10, -128, -13, 114, -33, 14,
+ 66, -109, 7, 48, 2, 24, -24, 3,
+ -52, -92, 110, 123, 124, -96, 8, 67,
+ 40, 8, -87, -111, -117, -71, -98, -124,
+ 73, -128, 3, 96, 30, 2, 105, 8,
+ 32, 64, -74, 41, 48, -6, -67, -105,
+ -56, 43, 106, -53, -75, 0, 67, 113,
+ 2, 121, -89, 114, 4, -128, 57, -60,
+ 80, -50, 56, -107, 16, -46, -64, 45,
+ 72, 96, 88, 107, 8, 105, -64, 55,
+ -31, -112, 108, -89, -76, -59, 0, 107,
+ -124, 42, 26, -53, -21, -116, 92, 14,
+ -100, -107, -109, -62, 94, 64, 33, -75,
+ -128, -121, -12, -102, -122, 17, -119, 101,
+ 67, 88, 27, -27, 41, 13, -76, 22,
+ -20, -126, 0, 0, 0, 0, 71, 67,
+ 113, -66, 51, -95, -92, -122, 12, -94,
+ -126, 33, -13, 103, 35, 46, -1, -47,
+ 40, 68, -101, 48, 41, -100, -119, -79,
+ 47, 60, 83, 64, 67, 101, -122, 51,
+ -103, -119, 107, -62, -102, 1, 12, 8,
+ 22, -2, 42, -73, 77, 6, 91, 32,
+ 2, 49, -73, -89, -63, 8, 98, -45,
+ -21, -16, 10, 50, 41, -87, 74, -76,
+ 53, 91, 75, -43, -40, 0, 42, 1,
+ -96, 36, -46, 0, 111, -85, 57, 94,
+ 93, 119, -104, 116, 17, -104, -65, 84,
+ 97, 100, -102, 37, 15, -68, 126, 73,
+ 47, -111, 115, -53, -46, -72, 0, 102,
+ -60, -123, 119, 1, -54, 64, 4, 2,
+ 0, 118, 71, 92, 0, 12, 12, -128,
+ -34, -55, -65, 74, -85, -111, 78, -125,
+ -3, 127, -100, -111, -80, -128, 10, -108,
+ -56, 16, 1, -109, -24, 21, -44, -115,
+ -9, -32, -16, 35, 37, 14, -22, -69,
+ -106, -15, 64, 3, 45, -22, 33, 86,
+ -64, 32, -41, 32, 117, 52, 62, -27,
+ -101, -118, -74, -125, -66, 56, -13, 93,
+ 113, -56, 21, 79, -76, -128, 0, -103,
+ 122, 126, -48, 20, 93, -90, 47, 42,
+ -40, 8, 17, -83, -94, -33, 8, 93,
+ -113, 10, 79, 62, -128, 23, 109, -25,
+ -8, 1, 33, 90, 0, 33, -118, 5,
+ -44, -54, -64, 127, -113, 64, 16, -64,
+ 2, 80, 15, 1, -5, -27, -38, -16,
+ -83, 41, -118, 15, -37, -57, -79, -94,
+ -51, 50, -59, -47, 20, -59, 64, 15,
+ -75, 107, -53, -91, -96, -9, -128, 1,
+ 48, 0, 0, 80, 94, -19, 92, -10,
+ -127, -20, 0, 14, 82, 125, 83, -24,
+ -121, 56, -124, 61, -67, -88, -73, 64,
+ 120, 0, 0, 84, 0, -61, -19, 99,
+ 32, -33, -26, -76, -26, -17, -51, -122,
+ 38, -111, -84, -36, 12, 93, -77, -66,
+ -85, -86, 0, 107, -68, 6, -36, 92,
+ -74, 30, 102, 71, 64, 3, 93, 78,
+ -80, -75, -7, 5, 93, -6, -57, -74,
+ -79, 79, -109, 78, 22, 117, 108, -111,
+ 122, 52, 96, -49, 38, -117, -125, 123,
+ 10, 114, 121, 85, 96, -48, 0, -96,
+ 31, 16, 13, 39, -42, 113, 50, -109,
+ -9, 90, 59, 93, 15, -8, -79, 116,
+ -14, 77, -128, 29, 104, -19, -42, -97,
+ -94, -62, 6, -33, 44, 0, -5, 108,
+ -3, 91, -19, 7, -83, -27, 81, 49,
+ 24, -12, -109, 123, -51, 60, 39, 111,
+ -50, 23, -78, 53, -10, 14, -80, -93,
+ 122, -87, 33, -78, -30, 59, -95, -96,
+ 10, -128, 0, 30, 61, 92, -112, -53,
+ -25, 104, -76, 24, -79, 9, 37, 32,
+ 22, 4, -57, 1, 109, 65, 7, 26,
+ -98, 59, 106, -101, 103, -64, -116, -52,
+ 11, 29, 23, 106, 107, 106, -51, -15,
+ 120, -5, -20, 1, 54, -16, -47, -77,
+ 0, 38, -81, -54, 18, -8, 32, -122,
+ 69, 70, 117, 23, 44, 0, 0, 30,
+ 0, -68, 0, 109, -128, -45, -37, 80,
+ 48, 5, 118, -25, -85, 50, 110, 108,
+ -111, 51, -47, 23, 16, -96, 45, 99,
+ -51, -110, -12, 96, -63, -42, 20, 120,
+ 89, 86, 41, 120, 32, 5, 41, -5,
+ 0, 13, -99, 104, -100, -128, 10, -80,
+ 16, 0, 104, 15, -104, 5, 106, -85,
+ 125, 9, 57, -1, 91, -16, 0, 44,
+ 7, -32, 3, -10, 55, 40, -1, 80,
+ 65, -126, -64, 66, -20, -37, 66, -59,
+ 95, 64, 4, 55, -20, 26, 13, -37,
+ -126, 125, -106, -48, 1, 13, -48, -65,
+ -90, -126, -79, -123, 21, 32, 8, 108,
+ 95, -91, -111, 115, 44, -101, -112, 1,
+ 82, 16, 0, 103, 1, -51, 0, -112,
+ -14, 103, -112, -122, 98, 46, -43, -71,
+ 41, 126, -76, 0, -71, 79, 2, 127,
+ 108, -2, -128, 23, 109, 93, -111, -74,
+ 90, 0, 33, -96, 63, -94, -107, -86,
+ 70, 92, -64, 21, -67, 64, 0, -128,
+ 127, -64, 51, 0, 23, 126, -40, 69,
+ 68, 0, -101, 71, -5, -84, -127, -82,
+ 104, -123, 85, 80, -55, -81, 47, -88,
+ 109, -46, 27, -11, 74, -83, 49, -35,
+ 116, 113, 112, 0, 86, 0, -72, 15,
+ 32, 4, -37, 124, 11, 126, -116, -32,
+ 11, -113, 126, 40, -92, 0, 33, -110,
+ -2, 87, 53, -51, 64, -81, -51, 74,
+ -36, 121, -4, 102, -15, 117, -19, 4,
+ 93, -32, 4, 49, 0, 96, 60, 3,
+ -23, 26, 19, -124, -92, 33, 13, -94,
+ -16, -6, -122, -83, -127, 54, 33, -118,
+ -99, -79, 32, -107, 112, 30, -8, -122,
+ -125, -66, -77, -95, -91, 122, 16, -114,
+ -122, 92, 123, 113, 65, 69, 125, 125,
+ 67, 66, 48, -43, 80, -53, 78, -49,
+ 29, 37, 10, 121, -59, 36, -61, -114,
+ -109, -28, 103, -92, 0, 46, -57, -115,
+ 72, 127, -12, 0, -55, 101, -48, -119,
+ -117, 22, -64, 1, 25, -110, 21, -60,
+ 66, 26, 43, -21, -59, -55, -62, -58,
+ -21, 46, -96, -128, 25, 101, 0, 0,
+ 1, -64, 31, 9, 64, 1, -75, -73,
+ -55, 82, 0, -89, 94, 13, -76, -56,
+ 74, -1, 83, 115, 72, -21, -104, 43,
+ 56, -75, -32, -10, 74, -11, -66, 126,
+ 11, 72, 113, -40, 29, -51, -12, -127,
+ 6, -85, -116, -85, 78, 30, -65, -44,
+ -111, -1, -95, -111, 62, -33, 68, -55,
+ -29, -91, 112, -93, 37, 1, 72, -111,
+ -114, 0, 125, -96, -32, -38, 9, 70,
+ 76, -102, 5, -28, -116, -109, -53, -58,
+ -7, -37, -7, 0, 10, 114, 100, -105,
+ -47, -53, 59, 46, -37, -23, 64, 2,
+ -73, 112, 103, -16, 4, 102, -18, 104,
+ 21, -40, 70, -70, 0, 88, 0, 1,
+ -113, -123, 88, -89, -55, -112, -84, -45,
+ -107, -82, 28, -128, 40, 105, 24, 55,
+ 61, -73, -40, 15, -72, 0, 8, 4,
+ 47, -27, 88, -18, -3, 74, 50, 104,
+ -111, 31, -27, -4, -115, 115, 111, -92,
+ 22, -12, -10, -128, 3, -128, 10, 3,
+ 78, -56, 97, 127, 104, 8, 105, 24,
+ 53, -2, -43, 119, -21, -12, -13, 104,
+ -95, 71, -19, -4, 13, -13, -57, -20,
+ 16, -16, -36, -84, 95, 88, 52, -5,
+ 8, 1, 78, 97, -68, -67, 120, -40,
+ 0, 66, 1, -96, 40, 64, 2, -20,
+ -2, -57, -88, 2, -84, 0, 38, 0,
+ -16, 21, -2, 60, -102, -38, -12, -115,
+ 88, 0, 88, 1, -32, 43, 95, 57,
+ -9, -115, 32, -3, 113, -28, -45, 31,
+ -62, 57, 7, -5, -30, -105, 106, 102,
+ 59, -44, 32, 7, 56, 0, 52, 6,
+ 96, 61, 3, 54, -24, 0, 1, -56,
+ 11, 0, 92, -70, 40, 85, 113, 0,
+ 16, -42, -79, 73, -73, 106, 66, 21,
+ 104, 64, 11, -79, -20, 11, 14, 32,
+ 1, 88, 119, -60, 14, 96, 16, -34,
+ 64, 0, 32, 63, -32, 23, -48, -35,
+ 82, -20, -92, 110, -102, -15, 52, 8,
+ 67, 24, 17, 83, 35, 2, 58, -84,
+ -120, -41, 50, -55, -65, 123, 39, -42,
+ 6, -71, 71, 19, 1, 126, 60, 2,
+ 4, 98, 87, 124, 19, 60, -112, -41,
+ 111, 63, -96, 9, -119, -109, 47, 24,
+ 113, -108, -126, 55, 2, -66, 88, -60,
+ 120, -127, -24, 18, -64, 78, 40, 99,
+ 32, -21, 56, -5, -66, 100, -80, 19,
+ -116, -37, 77, -75, -18, -64, 33, -128,
+ 3, -128, -80, 25, -4, 71, -122, 61,
+ 103, 39, 20, 54, -81, -54, -99, -112,
+ -64, 7, 0, -56, 11, -63, 106, -71,
+ -25, 100, -103, 51, 0, 28, 3, 64,
+ 51, 0, -33, 90, -44, 89, -39, -101,
+ 8, 31, 3, 96, 44, 0, -122, 101,
+ 9, 114, 67, 0, 0, -1, -64, -1,
+ 0, 88, 35, 82, 67, -71, 8, 43,
+ 0, 64, -1, -64, -1, -128, 126, 1,
+ -110, 101, 95, -6, -37, 113, 0, 9,
+ -79, 19, -26, 112, 41, -51, -83, 18,
+ 113, -108, 52, -113, -25, -44, 54, 33,
+ 13, -59, 13, 5, -11, 97, 12, -58,
+ 8, -50, -122, 90, -17, -102, -46, 26,
+ -82, 9, -80, -116, 83, -23, -56, 69,
+ 73, 84, 0, -28, 7, -12, 3, 47,
+ 17, -68, 43, -26, -62, 32, 92, 25,
+ -15, -43, 24, 1, 13, -98, -18, -64,
+ -122, -51, 120, 98, -102, 24, 71, -35,
+ -127, 5, 90, 48, -42, -92, 49, -36,
+ 36, 116, 52, -29, -21, -11, 72, -59,
+ 21, -22, 106, -14, -73, -16, 36, 16,
+ 19, 105, 110, -105, -16, 41, 71, 54,
+ 80, -38, 109, 73, -110, -63, 21, 72,
+ 35, 38, 59, 49, 8, -109, 24, 88,
+ 29, 72, -125, 50, 91, -93, 16, 9,
+ -77, -53, 126, 20, -64, 33, 2, 58,
+ -90, 8, -109, 102, 61, 41, -112, 70,
+ 65, -9, 75, 17, 38, 22, -12, 83,
+ 35, 125, -4, -14, -62, -95, -106, -103,
+ -66, -82, 70, -60, -16, 115, 17, 30,
+ -4, 0, 11, 1, -8, 0, -126, -120,
+ 75, 65, -47, -42, -58, 126, -55, -128,
+ 0, 15, 96, 52, 115, 14, -37, 79,
+ -70, 71, 10, 60, -102, 74, 34, 124,
+ -25, 10, 5, 112, -24, -46, -68, 105,
+ 23, -34, -3, 4, 95, -20, 69, -37,
+ 50, -98, 8, 17, -113, 97, 20, 72,
+ 33, -107, 88, -45, -56, -49, -80, -85,
+ -30, 36, 85, -77, 9, 68, 33, -94,
+ -67, -97, 72, -52, 35, -108, -95, 23,
+ 96, 40, 22, 40, 64, 12, 87, -122,
+ -9, 27, -23, 2, 8, -73, -6, -26,
+ -112, 22, 4, -44, 116, 85, 2, -116,
+ -109, -24, -101, -34, 56, 1, -74, 16,
+ 0, 1, -16, 14, 61, 89, 56, 51,
+ -21, -107, -101, -72, -17, 64, 46, -64,
+ 2, -80, 13, 1, -37, 16, 1, 4,
+ 0, 0, 0, 0, -63, 118, 101, -103,
+ 91, -60, 32, 4, -40, 52, 58, 119,
+ 64, 32, 0, -52, 0, 0, 0, -120
+ } ;
+
+ private static final CompressedGeometryHeader cgHeader ;
+
+ static {
+ cgHeader = new CompressedGeometryHeader() ;
+ cgHeader.majorVersionNumber = 1 ;
+ cgHeader.minorVersionNumber = 0 ;
+ cgHeader.minorMinorVersionNumber = 1 ;
+ cgHeader.bufferType = CompressedGeometryHeader.TRIANGLE_BUFFER ;
+ cgHeader.bufferDataPresent = CompressedGeometryHeader.NORMAL_IN_BUFFER ;
+ cgHeader.start = 0 ;
+ cgHeader.size = cgData.length ;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java b/src/classes/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java
new file mode 100644
index 0000000..5245b80
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java
@@ -0,0 +1,180 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class IcosahedronITSA extends IndexedTriangleStripArray {
+
+ private static final int[] sVertCnt = {
+ 3, 11, 5, 4, 5, 4
+ };
+
+ IcosahedronITSA() {
+ super(12, GeometryArray.COORDINATES | GeometryArray.COLOR_3, 32, sVertCnt);
+
+ Point3f verts[] = new Point3f[12];
+ Color3f colors[] = new Color3f[12];
+
+ verts[0] = new Point3f(0.0f, 1.4f, 0.8652f);
+ verts[1] = new Point3f(0.0f, 1.4f, -0.8652f);
+ verts[2] = new Point3f(1.4f, 0.8652f, 0.0f);
+ verts[3] = new Point3f(1.4f, -0.8652f, 0.0f);
+ verts[4] = new Point3f(0.0f, -1.4f, -0.8652f);
+ verts[5] = new Point3f(0.0f, -1.4f, 0.8652f);
+ verts[6] = new Point3f(0.8652f, 0.0f, 1.4f);
+ verts[7] = new Point3f(-0.8652f, 0.0f, 1.4f);
+ verts[8] = new Point3f(0.8652f, 0.0f, -1.4f);
+ verts[9] = new Point3f(-0.8652f, 0.0f, -1.4f);
+ verts[10] = new Point3f(-1.4f, 0.8652f, 0.0f);
+ verts[11] = new Point3f(-1.4f, -0.8652f, 0.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+ colors[4] = new Color3f(0.0f, 1.0f, 1.0f);
+ colors[5] = new Color3f(1.0f, 0.0f, 1.0f);
+ colors[6] = new Color3f(0.0f, 0.5f, 0.0f);
+ colors[7] = new Color3f(0.0f, 0.0f, 0.5f);
+ colors[8] = new Color3f(0.5f, 0.5f, 0.0f);
+ colors[9] = new Color3f(0.0f, 0.5f, 0.5f);
+ colors[10] = new Color3f(0.5f, 0.0f, 0.5f);
+ colors[11] = new Color3f(0.5f, 0.5f, 0.5f);
+
+ int pntsIndex[] = new int[32];
+ int clrsIndex[] = new int[32];
+
+ pntsIndex[0] = 4;
+ clrsIndex[0] = 4;
+ pntsIndex[1] = 5;
+ clrsIndex[1] = 5;
+ pntsIndex[2] = 11;
+ clrsIndex[2] = 11;
+
+ pntsIndex[3] = 11;
+ clrsIndex[3] = 11;
+ pntsIndex[4] = 5;
+ clrsIndex[4] = 5;
+ pntsIndex[5] = 7;
+ clrsIndex[5] = 7;
+
+ pntsIndex[6] = 6;
+ clrsIndex[6] = 6;
+
+ pntsIndex[7] = 0;
+ clrsIndex[7] = 0;
+
+ pntsIndex[8] = 2;
+ clrsIndex[8] = 2;
+
+ pntsIndex[9] = 1;
+ clrsIndex[9] = 1;
+
+ pntsIndex[10] = 8;
+ clrsIndex[10] = 8;
+
+ pntsIndex[11] = 9;
+ clrsIndex[11] = 9;
+
+ pntsIndex[12] = 4;
+ clrsIndex[12] = 4;
+
+ pntsIndex[13] = 11;
+ clrsIndex[13] = 11;
+
+ pntsIndex[14] = 2;
+ clrsIndex[14] = 2;
+ pntsIndex[15] = 6;
+ clrsIndex[15] = 6;
+ pntsIndex[16] = 3;
+ clrsIndex[16] = 3;
+
+ pntsIndex[17] = 5;
+ clrsIndex[17] = 5;
+
+ pntsIndex[18] = 4;
+ clrsIndex[18] = 4;
+
+ pntsIndex[19] = 4;
+ clrsIndex[19] = 4;
+ pntsIndex[20] = 8;
+ clrsIndex[20] = 8;
+ pntsIndex[21] = 3;
+ clrsIndex[21] = 3;
+
+ pntsIndex[22] = 2;
+ clrsIndex[22] = 2;
+
+ pntsIndex[23] = 0;
+ clrsIndex[23] = 0;
+ pntsIndex[24] = 1;
+ clrsIndex[24] = 1;
+ pntsIndex[25] = 10;
+ clrsIndex[25] = 10;
+
+ pntsIndex[26] = 9;
+ clrsIndex[26] = 9;
+
+ pntsIndex[27] = 11;
+ clrsIndex[27] = 11;
+
+ pntsIndex[28] = 0;
+ clrsIndex[28] = 0;
+ pntsIndex[29] = 10;
+ clrsIndex[29] = 10;
+ pntsIndex[30] = 7;
+ clrsIndex[30] = 7;
+
+ pntsIndex[31] = 11;
+ clrsIndex[31] = 11;
+
+ setCoordinates(0, verts);
+ setCoordinateIndices(0, pntsIndex);
+ setColors(0, colors);
+ setColorIndices(0, clrsIndex);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java b/src/classes/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java
new file mode 100644
index 0000000..a9587c6
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java
@@ -0,0 +1,177 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class IcosahedronTSA extends TriangleStripArray {
+ private static final int[] sVertCnt = {
+ 3, 11, 5, 4, 5, 4
+ };
+
+ IcosahedronTSA() {
+ super(32, GeometryArray.COORDINATES | GeometryArray.COLOR_3, sVertCnt);
+
+ Point3f verts[] = new Point3f[12];
+ Color3f colors[] = new Color3f[12];
+
+ verts[0] = new Point3f(0.0f, 1.4f, 0.8652f);
+ verts[1] = new Point3f(0.0f, 1.4f, -0.8652f);
+ verts[2] = new Point3f(1.4f, 0.8652f, 0.0f);
+ verts[3] = new Point3f(1.4f, -0.8652f, 0.0f);
+ verts[4] = new Point3f(0.0f, -1.4f, -0.8652f);
+ verts[5] = new Point3f(0.0f, -1.4f, 0.8652f);
+ verts[6] = new Point3f(0.8652f, 0.0f, 1.4f);
+ verts[7] = new Point3f(-0.8652f, 0.0f, 1.4f);
+ verts[8] = new Point3f(0.8652f, 0.0f, -1.4f);
+ verts[9] = new Point3f(-0.8652f, 0.0f, -1.4f);
+ verts[10] = new Point3f(-1.4f, 0.8652f, 0.0f);
+ verts[11] = new Point3f(-1.4f, -0.8652f, 0.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+ colors[4] = new Color3f(0.0f, 1.0f, 1.0f);
+ colors[5] = new Color3f(1.0f, 0.0f, 1.0f);
+ colors[6] = new Color3f(0.0f, 0.5f, 0.0f);
+ colors[7] = new Color3f(0.0f, 0.0f, 0.5f);
+ colors[8] = new Color3f(0.5f, 0.5f, 0.0f);
+ colors[9] = new Color3f(0.0f, 0.5f, 0.5f);
+ colors[10] = new Color3f(0.5f, 0.0f, 0.5f);
+ colors[11] = new Color3f(0.5f, 0.5f, 0.5f);
+
+ Point3f pnts[] = new Point3f[32];
+ Color3f clrs[] = new Color3f[32];
+
+ pnts[0] = verts[4];
+ clrs[0] = colors[4];
+ pnts[1] = verts[5];
+ clrs[1] = colors[5];
+ pnts[2] = verts[11];
+ clrs[2] = colors[11];
+
+ pnts[3] = verts[11];
+ clrs[3] = colors[11];
+ pnts[4] = verts[5];
+ clrs[4] = colors[5];
+ pnts[5] = verts[7];
+ clrs[5] = colors[7];
+
+ pnts[6] = verts[6];
+ clrs[6] = colors[6];
+
+ pnts[7] = verts[0];
+ clrs[7] = colors[0];
+
+ pnts[8] = verts[2];
+ clrs[8] = colors[2];
+
+ pnts[9] = verts[1];
+ clrs[9] = colors[1];
+
+ pnts[10] = verts[8];
+ clrs[10] = colors[8];
+
+ pnts[11] = verts[9];
+ clrs[11] = colors[9];
+
+ pnts[12] = verts[4];
+ clrs[12] = colors[4];
+
+ pnts[13] = verts[11];
+ clrs[13] = colors[11];
+
+ pnts[14] = verts[2];
+ clrs[14] = colors[2];
+ pnts[15] = verts[6];
+ clrs[15] = colors[6];
+ pnts[16] = verts[3];
+ clrs[16] = colors[3];
+
+ pnts[17] = verts[5];
+ clrs[17] = colors[5];
+
+ pnts[18] = verts[4];
+ clrs[18] = colors[4];
+
+ pnts[19] = verts[4];
+ clrs[19] = colors[4];
+ pnts[20] = verts[8];
+ clrs[20] = colors[8];
+ pnts[21] = verts[3];
+ clrs[21] = colors[3];
+
+ pnts[22] = verts[2];
+ clrs[22] = colors[2];
+
+ pnts[23] = verts[0];
+ clrs[23] = colors[0];
+ pnts[24] = verts[1];
+ clrs[24] = colors[1];
+ pnts[25] = verts[10];
+ clrs[25] = colors[10];
+
+ pnts[26] = verts[9];
+ clrs[26] = colors[9];
+
+ pnts[27] = verts[11];
+ clrs[27] = colors[11];
+
+ pnts[28] = verts[0];
+ clrs[28] = colors[0];
+ pnts[29] = verts[10];
+ clrs[29] = colors[10];
+ pnts[30] = verts[7];
+ clrs[30] = colors[7];
+
+ pnts[31] = verts[11];
+ clrs[31] = colors[11];
+
+ setCoordinates(0, pnts);
+ setColors(0, clrs);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java b/src/classes/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java
new file mode 100644
index 0000000..09c7d36
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java
@@ -0,0 +1,253 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import com.sun.j3d.utils.pickfast.*;
+import com.sun.j3d.utils.geometry.*;
+
+/**
+ * Class: IntersectInfoBehavior
+ *
+ * Description: Used to respond to mouse pick and drag events
+ * in the 3D window. Displays information about the pick.
+ *
+ * Version: 1.0
+ *
+ */
+public class IntersectInfoBehavior extends Behavior {
+
+ float size;
+ PickCanvas pickCanvas;
+ PickInfo[] pickInfoArr;
+ Appearance oldlook, redlookwf, redlook, greenlook, bluelook;
+ Node oldNode = null;
+ GeometryArray oldGeom = null;
+ Color3f redColor = new Color3f (1.0f, 0.0f, 0.0f);
+ TransformGroup[] sphTrans = new TransformGroup [6];
+ Sphere[] sph = new Sphere [6];
+ Transform3D spht3 = new Transform3D();
+
+ public IntersectInfoBehavior(Canvas3D canvas3D, BranchGroup branchGroup,
+ float size) {
+ pickCanvas = new PickCanvas(canvas3D, branchGroup);
+ pickCanvas.setTolerance(5.0f);
+ pickCanvas.setMode(PickInfo.PICK_GEOMETRY);
+ pickCanvas.setFlags(PickInfo.LOCAL_TO_VWORLD | PickInfo.CLOSEST_GEOM_INFO);
+ this.size = size;
+ // Create an Appearance.
+ redlook = new Appearance();
+ Color3f objColor = new Color3f(0.5f, 0.0f, 0.0f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ redlook.setMaterial(new Material(objColor, black, objColor, white, 50.0f));
+ redlook.setCapability (Appearance.ALLOW_MATERIAL_WRITE);
+
+ redlookwf = new Appearance ();
+ redlookwf.setMaterial(new Material(objColor, black, objColor, white, 50.0f));
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(pa.POLYGON_LINE);
+ pa.setCullFace(pa.CULL_NONE);
+ redlookwf.setPolygonAttributes(pa);
+
+ oldlook = new Appearance();
+ objColor = new Color3f(1.0f, 1.0f, 1.0f);
+ oldlook.setMaterial(new Material(objColor, black, objColor, white, 50.0f));
+
+ greenlook = new Appearance();
+ objColor = new Color3f(0.0f, 0.8f, 0.0f);
+ greenlook.setMaterial(new Material(objColor, black, objColor, white, 50.0f));
+ bluelook = new Appearance();
+ objColor = new Color3f(0.0f, 0.0f, 0.8f);
+ bluelook.setMaterial(new Material(objColor, black, objColor, white, 50.0f));
+ for (int i=0;i<6;i++) {
+ switch (i) {
+ case 0:
+ sph[i] = new Sphere(size*1.15f, redlook);
+ break;
+ case 1:
+ sph[i] = new Sphere(size*1.1f, greenlook);
+ break;
+ default:
+ sph[i] = new Sphere(size, bluelook);
+ break;
+ }
+ sph[i].setPickable (false);
+ sphTrans[i] = new TransformGroup ();
+ sphTrans[i].setCapability (TransformGroup.ALLOW_TRANSFORM_READ);
+ sphTrans[i].setCapability (TransformGroup.ALLOW_TRANSFORM_WRITE);
+
+ // Add sphere, transform
+ branchGroup.addChild (sphTrans[i]);
+ sphTrans[i].addChild (sph[i]);
+ }
+ }
+
+ public void initialize() {
+ wakeupOn (new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED));
+ }
+
+ public void processStimulus (Enumeration criteria) {
+ WakeupCriterion wakeup;
+ AWTEvent[] event;
+ int eventId;
+
+ while (criteria.hasMoreElements()) {
+ wakeup = (WakeupCriterion) criteria.nextElement();
+ if (wakeup instanceof WakeupOnAWTEvent) {
+ event = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
+ for (int i=0; i<event.length; i++) {
+ eventId = event[i].getID();
+ if (eventId == MouseEvent.MOUSE_PRESSED) {
+ int x = ((MouseEvent)event[i]).getX();
+ int y = ((MouseEvent)event[i]).getY();
+ pickCanvas.setShapeLocation(x, y);
+
+ pickInfoArr = pickCanvas.pickAllSorted();
+ // Use this to do picking benchmarks
+ /*
+ long start = System.currentTimeMillis();
+ for (int l=0;l<2;l++) {
+ if (l == 0) System.out.print ("BOUNDS: ");
+ if (l == 1) System.out.print ("GEOMETRY: ");
+
+ for (int k=0;k<1000;k++) {
+ if (l == 0) {
+ pickCanvas.setMode(PickTool.BOUNDS);
+ pickResult = pickCanvas.pickAllSorted();
+ }
+ if (l == 1) {
+ pickCanvas.setMode(PickTool.GEOMETRY);
+ pickResult = pickCanvas.pickAllSorted();
+ }
+ }
+ long delta = System.currentTimeMillis() - start;
+ System.out.println ("\t"+delta+" ms / 1000 picks");
+ }
+ */
+ if (pickInfoArr != null) {
+
+ // Get closest intersection results
+ Transform3D l2vw = pickInfoArr[0].getLocalToVWorld();
+ PickInfo.IntersectionInfo[] iInfoArr = pickInfoArr[0].getIntersectionInfos();
+ PickIntersection pi = new PickIntersection(l2vw, iInfoArr[0]);
+
+ // Safe to assume the return geometry is of GeometryArray type.
+ GeometryArray curGeomArray = (GeometryArray) iInfoArr[0].getGeometry();
+
+ // Position sphere at intersection point
+ Vector3d v = new Vector3d();
+ Point3d intPt = pi.getPointCoordinatesVW();
+ v.set(intPt);
+ spht3.setTranslation (v);
+ sphTrans[0].setTransform (spht3);
+
+ // Position sphere at closest vertex
+ Point3d closestVert = pi.getClosestVertexCoordinatesVW();
+ v.set(closestVert);
+ spht3.setTranslation (v);
+ sphTrans[1].setTransform (spht3);
+
+ Point3d []ptw = pi.getPrimitiveCoordinatesVW();
+ Point3d []pt = pi.getPrimitiveCoordinates();
+ int []coordidx = pi.getPrimitiveCoordinateIndices();
+ Point3d ptcoord = new Point3d();
+ for (int k=0;k<pt.length;k++) {
+ v.set(ptw[k]);
+ spht3.setTranslation (v);
+ sphTrans[k+2].setTransform (spht3);
+ }
+
+ // Get interpolated color (if available)
+ Color4f iColor4 = null;
+ Color3f iColor = null;
+ Vector3f iNormal = null;
+
+ if (curGeomArray != null) {
+ int vf = curGeomArray.getVertexFormat();
+
+ if (((vf &
+ (GeometryArray.COLOR_3 |
+ GeometryArray.COLOR_4)) != 0) &&
+ (null != (iColor4 =
+ pi.getPointColor()))) {
+ iColor =
+ new Color3f(iColor4.x, iColor4.y, iColor4.z);
+
+ // Change the point's color
+ redlook.setMaterial(new Material(iColor, new Color3f (0.0f, 0.0f, 0.0f), iColor, new Color3f(1.0f, 1.0f, 1.0f), 50.0f));
+ }
+ if (((vf & GeometryArray.NORMALS) != 0) &&
+ (null != (iNormal =
+ pi.getPointNormal()))) {
+ System.out.println ("Interpolated normal: "+iNormal);
+ }
+ }
+
+ System.out.println ("=============");
+ System.out.println ("Coordinates of intersection pt:"+intPt);
+ System.out.println ("Coordinates of vertices: ");
+ for (int k=0;k<pt.length;k++) {
+ System.out.println (k + ":" + ptw[k].x + " " + ptw[k].y + " " + ptw[k].z);
+ }
+ System.out.println ("Closest vertex: "+closestVert);
+ if (iColor != null) {
+ System.out.println ("Interpolated color: "+iColor);
+ }
+ if (iNormal != null) {
+ System.out.println ("Interpolated normal: "+iNormal);
+ }
+ }
+ }
+ }
+ }
+ }
+ wakeupOn (new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED));
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/IntersectTest.java b/src/classes/org/jdesktop/j3d/examples/picking/IntersectTest.java
new file mode 100644
index 0000000..6ff062a
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/IntersectTest.java
@@ -0,0 +1,235 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.event.*;
+import java.awt.GraphicsConfiguration;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import com.sun.j3d.utils.behaviors.keyboard.*;
+
+public class IntersectTest extends Applet {
+
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 1000.0);
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph () {
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ objRoot.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
+ Color3f light2Color = new Color3f(0.3f, 0.3f, 0.4f);
+ Vector3f light2Direction = new Vector3f(-6.0f, -2.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ objRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ objRoot.addChild(light2);
+
+ Transform3D t3 = new Transform3D ();
+
+ // Shapes
+ for (int x=0;x<3;x++) {
+ for (int y=0;y<3;y++) {
+ for (int z=0;z<3;z++) {
+ t3.setTranslation (new Vector3d(-4+x*4.0, -4+y*4.0, -20-z*4.0));
+ TransformGroup objTrans = new TransformGroup(t3);
+
+ objRoot.addChild(objTrans);
+
+ // Create a simple shape leaf node, add it to the scene graph.
+ GeometryArray geom = null;
+
+ if (((x+y+z) % 2) == 0) {
+ geom = new RandomColorCube();
+ }
+ else {
+ geom = new RandomColorTetrahedron();
+ }
+
+ Shape3D shape = new Shape3D(geom);
+
+ objTrans.addChild(shape);
+ }
+ }
+ }
+
+ // Lines
+ Point3f[] verts = {
+ new Point3f (-2.0f, 0.0f, 0.0f),new Point3f(2.0f, 0.0f, 0.0f)
+ };
+ Color3f grey = new Color3f (0.7f, 0.7f, 0.7f);
+ Color3f[] colors = {
+ grey, grey
+ };
+
+ for (int y=0;y<5;y++) {
+ for (int z=0;z<5;z++) {
+ t3.setTranslation (new Vector3d(7.0, -4+y*2.0, -20.0-z*2.0));
+ TransformGroup objTrans = new TransformGroup(t3);
+
+ objRoot.addChild(objTrans);
+
+ LineArray la = new LineArray (verts.length,
+ LineArray.COORDINATES |
+ LineArray.COLOR_3);
+ la.setCoordinates (0, verts);
+ la.setColors (0, colors);
+
+
+ Shape3D shape = new Shape3D();
+ shape.setGeometry (la);
+
+
+ objTrans.addChild(shape);
+ }
+ }
+
+ // Points
+ for (double x=-2.0;x<=2.0;x+=1.0) {
+ for (double y=-2.0;y<=2.0;y+=1.0) {
+ for (double z=-2.0;z<=2.0;z+=1.0) {
+ t3.setTranslation (new Vector3d(-10.0+2.0*x, 0.0+2.0*y,-20.0+2.0*z));
+ TransformGroup objTrans = new TransformGroup(t3);
+
+ objRoot.addChild(objTrans);
+
+ PointArray pa = new PointArray (1,
+ PointArray.COORDINATES |
+ PointArray.COLOR_3);
+
+ pa.setCoordinate (0, new Point3d (0.0, 0.0, 0.0));
+ pa.setColor (0, grey);
+
+ Shape3D shape = new Shape3D();
+ shape.setGeometry (pa);
+
+
+ objTrans.addChild(shape);
+ }
+ }
+ }
+
+ return objRoot;
+ }
+
+ public IntersectTest () {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // Add picking behavior
+ IntersectInfoBehavior behavior =
+ new IntersectInfoBehavior (c, scene,0.05f);
+ behavior.setSchedulingBounds (bounds);
+ scene.addChild (behavior);
+
+ TransformGroup vpTrans =
+ u.getViewingPlatform().getViewPlatformTransform();
+
+ KeyNavigatorBehavior keybehavior = new KeyNavigatorBehavior (vpTrans);
+ keybehavior.setSchedulingBounds (bounds);
+ scene.addChild (keybehavior);
+ scene.setCapability (Group.ALLOW_CHILDREN_EXTEND);
+ scene.compile();
+ u.addBranchGraph(scene);
+
+ View view = u.getViewer().getView();
+ view.setBackClipDistance (100000);
+
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows IntersectTest to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ String s = "\n\nIntersectTest:\n-----------\n";
+ s += "Pick with the mouse over the primitives\n";
+ s += "- A sphere will be placed to indicate the picked point.\n";
+ s += "If color information is available, the sphere will change color to reflect\n";
+ s += "the interpolated color.\n";
+ s += "- Other spheres will be placed to show the vertices of the selected polygon\n";
+ s += "- Information will be displayed about the picking operation\n\n\n";
+
+ System.out.println (s);
+
+ new MainFrame(new IntersectTest(), 640, 640);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/MorphingBehavior.java b/src/classes/org/jdesktop/j3d/examples/picking/MorphingBehavior.java
new file mode 100644
index 0000000..dfce69f
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/MorphingBehavior.java
@@ -0,0 +1,99 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import java.util.Enumeration;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+// User-defined morphing behavior class
+public class MorphingBehavior extends Behavior {
+
+ Alpha alpha;
+ Morph morph;
+ double weights[];
+
+ WakeupOnElapsedFrames w = new WakeupOnElapsedFrames(0);
+
+ // Override Behavior's initialize method to setup wakeup criteria
+ public void initialize() {
+ alpha.setStartTime(System.currentTimeMillis());
+
+ // Establish initial wakeup criteria
+ wakeupOn(w);
+ }
+
+ // Override Behavior's stimulus method to handle the event
+ public void processStimulus(Enumeration criteria) {
+
+ // NOTE: This assumes 3 objects. It should be generalized to
+ // "n" objects.
+
+ double val = alpha.value();
+ if (val < 0.5) {
+ double a = val * 2.0;
+ weights[0] = 1.0 - a;
+ weights[1] = a;
+ weights[2] = 0.0;
+ }
+ else {
+ double a = (val - 0.5) * 2.0;
+ weights[0] = 0.0;
+ weights[1] = 1.0f - a;
+ weights[2] = a;
+ }
+
+ morph.setWeights(weights);
+
+ // Set wakeup criteria for next time
+ wakeupOn(w);
+ }
+
+ public MorphingBehavior(Alpha a, Morph m) {
+ alpha = a;
+ morph = m;
+ weights = morph.getWeights();
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/OctahedronITFA.java b/src/classes/org/jdesktop/j3d/examples/picking/OctahedronITFA.java
new file mode 100644
index 0000000..d97f8fe
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/OctahedronITFA.java
@@ -0,0 +1,115 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class OctahedronITFA extends IndexedTriangleFanArray {
+ private static final int[] sVertCnt = {
+ 6, 6
+ };
+
+ OctahedronITFA() {
+ super(6, GeometryArray.COORDINATES | GeometryArray.COLOR_3, 12, sVertCnt);
+
+ Point3f verts[] = new Point3f[6];
+ Color3f colors[] = new Color3f[6];
+
+ verts[0] = new Point3f(0.0f,0.0f,-1.5f);
+ verts[1] = new Point3f(0.0f,0.0f,1.5f);
+ verts[2] = new Point3f(0.0f,-1.5f,0.0f);
+ verts[3] = new Point3f(0.0f,1.5f,0.0f);
+ verts[4] = new Point3f(1.5f,0.0f,0.0f);
+ verts[5] = new Point3f(-1.5f,0.0f,0.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+ colors[4] = new Color3f(1.0f, 0.0f, 1.0f);
+ colors[5] = new Color3f(0.0f, 1.0f, 1.0f);
+
+ int pntsIndex[] = new int[12];
+ int clrsIndex[] = new int[12];
+
+ pntsIndex[0] = 4;
+ clrsIndex[0] = 4;
+ pntsIndex[1] = 2;
+ clrsIndex[1] = 2;
+ pntsIndex[2] = 0;
+ clrsIndex[2] = 0;
+
+ pntsIndex[3] = 3;
+ clrsIndex[3] = 3;
+
+ pntsIndex[4] = 1;
+ clrsIndex[4] = 1;
+
+ pntsIndex[5] = 2;
+ clrsIndex[5] = 2;
+
+ pntsIndex[6] = 5;
+ clrsIndex[6] = 5;
+ pntsIndex[7] = 1;
+ clrsIndex[7] = 1;
+ pntsIndex[8] = 3;
+ clrsIndex[8] = 3;
+
+ pntsIndex[9] = 0;
+ clrsIndex[9] = 0;
+
+ pntsIndex[10] = 2;
+ clrsIndex[10] = 2;
+
+ pntsIndex[11] = 1;
+ clrsIndex[11] = 1;
+
+ setCoordinates(0, verts);
+ setCoordinateIndices(0, pntsIndex);
+ setColors(0, colors);
+ setColorIndices(0, clrsIndex);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/OctahedronTFA.java b/src/classes/org/jdesktop/j3d/examples/picking/OctahedronTFA.java
new file mode 100644
index 0000000..794cc70
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/OctahedronTFA.java
@@ -0,0 +1,114 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class OctahedronTFA extends TriangleFanArray {
+ private static final int[] sVertCnt = {
+ 6, 6
+ };
+
+ OctahedronTFA() {
+ super(12, GeometryArray.COORDINATES | GeometryArray.COLOR_3, sVertCnt);
+
+ Point3f verts[] = new Point3f[6];
+ Color3f colors[] = new Color3f[6];
+
+ verts[0] = new Point3f(0.0f,0.0f,-1.5f);
+ verts[1] = new Point3f(0.0f,0.0f,1.5f);
+ verts[2] = new Point3f(0.0f,-1.5f,0.0f);
+ verts[3] = new Point3f(0.0f,1.5f,0.0f);
+ verts[4] = new Point3f(1.5f,0.0f,0.0f);
+ verts[5] = new Point3f(-1.5f,0.0f,0.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+ colors[4] = new Color3f(1.0f, 0.0f, 1.0f);
+ colors[5] = new Color3f(0.0f, 1.0f, 1.0f);
+
+
+ Point3f pnts[] = new Point3f[12];
+ Color3f clrs[] = new Color3f[12];
+
+ pnts[0] = verts[4];
+ clrs[0] = colors[4];
+ pnts[1] = verts[2];
+ clrs[1] = colors[2];
+ pnts[2] = verts[0];
+ clrs[2] = colors[0];
+
+ pnts[3] = verts[3];
+ clrs[3] = colors[3];
+
+ pnts[4] = verts[1];
+ clrs[4] = colors[1];
+
+ pnts[5] = verts[2];
+ clrs[5] = colors[2];
+
+ pnts[6] = verts[5];
+ clrs[6] = colors[5];
+ pnts[7] = verts[1];
+ clrs[7] = colors[1];
+ pnts[8] = verts[3];
+ clrs[8] = colors[3];
+
+ pnts[9] = verts[0];
+ clrs[9] = colors[0];
+
+ pnts[10] = verts[2];
+ clrs[10] = colors[2];
+
+ pnts[11] = verts[1];
+ clrs[11] = colors[1];
+
+ setCoordinates(0, pnts);
+ setColors(0, clrs);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java b/src/classes/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java
new file mode 100644
index 0000000..bd7ab6a
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java
@@ -0,0 +1,102 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import com.sun.j3d.utils.picking.PickTool;
+import com.sun.j3d.utils.picking.PickResult;
+import com.sun.j3d.utils.picking.behaviors.PickMouseBehavior;
+import java.util.*;
+import java.awt.*;
+import java.awt.Event;
+import java.awt.AWTEvent;
+import java.awt.event.MouseEvent;
+import javax.vecmath.*;
+
+public class PickHighlightBehavior extends PickMouseBehavior {
+ Appearance savedAppearance = null;
+ Shape3D oldShape = null;
+ Appearance highlightAppearance;
+
+ public PickHighlightBehavior(Canvas3D canvas, BranchGroup root,
+ Bounds bounds) {
+ super(canvas, root, bounds);
+ this.setSchedulingBounds(bounds);
+ root.addChild(this);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f highlightColor = new Color3f(0.0f, 1.0f, 0.0f);
+ Material highlightMaterial = new Material(highlightColor, black,
+ highlightColor, white,
+ 80.0f);
+ highlightAppearance = new Appearance();
+ highlightAppearance.setMaterial(new Material(highlightColor, black,
+ highlightColor, white,
+ 80.0f));
+
+ pickCanvas.setMode(PickTool.BOUNDS);
+ }
+
+ public void updateScene(int xpos, int ypos) {
+ PickResult pickResult = null;
+ Shape3D shape = null;
+
+ pickCanvas.setShapeLocation(xpos, ypos);
+
+ pickResult = pickCanvas.pickClosest();
+ if (pickResult != null) {
+ shape = (Shape3D) pickResult.getNode(PickResult.SHAPE3D);
+ }
+
+ if (oldShape != null){
+ oldShape.setAppearance(savedAppearance);
+ }
+ if (shape != null) {
+ savedAppearance = shape.getAppearance();
+ oldShape = shape;
+ shape.setAppearance(highlightAppearance);
+ }
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/PickTest.java b/src/classes/org/jdesktop/j3d/examples/picking/PickTest.java
new file mode 100644
index 0000000..0857197
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/PickTest.java
@@ -0,0 +1,416 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import com.sun.j3d.utils.pickfast.behaviors.*;
+import com.sun.j3d.utils.pickfast.*;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.event.*;
+import java.awt.Component;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.Point;
+import javax.swing.*;
+import javax.swing.border.BevelBorder;
+
+/**
+ * PickTest shows how to use the Picking utilities on various GeometryArray
+ * subclasses and Morph object.
+ * Type of Geometry : CompressedGeometry ( GullCG.java )
+ * IndexedQuadArray ( CubeIQA.java )
+ * TriangleArray ( TetrahedronTA.java )
+ * IndexedTriangleArray ( TetrahedronITA.java )
+ * TriangleFanArray ( OctahedronTFA.java )
+ * IndexedTriangleFanArray ( OctahedronITA.java )
+ * TriangleStripArray ( IcosahedronTFA.java )
+ * IndexedTriangleStripArray ( IcosahedronITA.java )
+ * PointArray( TetrahedronPA.java )
+ * LineArray( TetrahedronLA.java )
+ * IndexLineArray( TetrahedronILA.java )
+ * LineStripArray( TetrahedronLSA.java )
+ * IndexLineStripArray( TetrahedronILSA.java )
+ *
+ * Morph Object uses : QuadArray ( ColorCube.java, ColorPyramidDown.java,
+ * and ColorPyramidUp.java ).
+ */
+
+public class PickTest extends Applet implements ActionListener {
+
+ private View view = null;
+ private QuadArray geomMorph[] = new QuadArray[3];
+ private Morph morph;
+
+ private PickRotateBehavior behavior1;
+ private PickZoomBehavior behavior2;
+ private PickTranslateBehavior behavior3;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(Canvas3D canvas)
+ {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(1.0);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bunch of objects with a behavior and add them
+ // into the scene graph.
+
+ int row, col;
+ int numRows = 4, numCols = 4;
+
+ for (int i = 0; i < numRows; i++) {
+ double ypos = (double)(i - numRows/2) * 0.45 + 0.25;
+ for (int j = 0; j < numCols; j++) {
+ double xpos = (double)(j - numCols/2) * 0.45 + 0.25;
+ objScale.addChild(createObject(i * numCols + j, 0.1, xpos, ypos));
+ }
+ }
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Add a light.
+ Color3f lColor = new Color3f(1.0f, 1.0f, 1.0f) ;
+ Vector3f lDir = new Vector3f(0.0f, 0.0f, -1.0f) ;
+
+ DirectionalLight lgt = new DirectionalLight(lColor, lDir) ;
+ lgt.setInfluencingBounds(bounds) ;
+ objRoot.addChild(lgt) ;
+
+
+ // Now create the Alpha object that controls the speed of the
+ // morphing operation.
+ Alpha morphAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 4000, 1000, 500,
+ 4000, 1000, 500);
+
+ // Finally, create the morphing behavior
+ MorphingBehavior mBeh = new MorphingBehavior(morphAlpha, morph);
+ mBeh.setSchedulingBounds(bounds);
+ objRoot.addChild(mBeh);
+
+ behavior1 = new PickRotateBehavior(objRoot, canvas, bounds);
+ objRoot.addChild(behavior1);
+
+ behavior2 = new PickZoomBehavior(objRoot, canvas, bounds);
+ objRoot.addChild(behavior2);
+
+ behavior3 = new PickTranslateBehavior(objRoot, canvas, bounds);
+ objRoot.addChild(behavior3);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+
+ private Group createObject(int index, double scale, double xpos, double ypos){
+
+ Shape3D shape = null;
+ Geometry geom = null;
+
+ // Create a transform group node to scale and position the object.
+ Transform3D t = new Transform3D();
+ t.set(scale, new Vector3d(xpos, ypos, 0.0));
+ TransformGroup objTrans = new TransformGroup(t);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objTrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+
+ // Create a second transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime.
+ TransformGroup spinTg = new TransformGroup();
+ spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ spinTg.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+
+ Appearance appearance = new Appearance();
+
+ switch(index) {
+ case 0:
+ geom = new GullCG();
+ break;
+ case 1:
+ geom = new TetrahedronTA();
+ break;
+ case 2:
+ geom = new OctahedronTFA();
+ break;
+ case 3:
+ geom = new IcosahedronTSA();
+ break;
+ case 4:
+ geom = new CubeIQA();
+ break;
+ case 5:
+ geom = new TetrahedronITA();
+ break;
+ case 6:
+ geom = new OctahedronITFA();
+ break;
+ case 7:
+ geom = new IcosahedronITSA();
+ break;
+ case 8:
+ geomMorph[0] = new ColorPyramidUp();
+ geomMorph[1] = new ColorCube();
+ geomMorph[2] = new ColorPyramidDown();
+ break;
+ case 9:
+ geom = new TetrahedronLA();
+ break;
+ case 10:
+ geom = new TetrahedronILA();
+ break;
+ case 11:
+ geom = new TetrahedronLSA();
+ break;
+ case 12:
+ geom = new TetrahedronILSA();
+ break;
+ case 13:
+ geom = new TetrahedronPA();
+ break;
+ case 14:
+ geom = new TetrahedronIPA();
+ break;
+ // TODO: other geo types, Text3D?
+ case 15:
+ geom = new TetrahedronTA();
+ break;
+ }
+
+ Material m = new Material() ;
+
+ if(index == 8) {
+ m.setLightingEnable(false) ;
+ appearance.setMaterial(m) ;
+ morph = new Morph((GeometryArray[]) geomMorph, appearance);
+ morph.setCapability(Morph.ALLOW_WEIGHTS_READ);
+ morph.setCapability(Morph.ALLOW_WEIGHTS_WRITE);
+ spinTg.addChild(morph);
+ } else {
+ // Geometry picking require this to be set.
+ if (index == 0)
+ m.setLightingEnable(true) ;
+ else
+ m.setLightingEnable(false) ;
+ appearance.setMaterial(m) ;
+
+ if ((index == 13) || (index == 14)) {
+ PointAttributes pa = new PointAttributes();
+ pa.setPointSize(4.0f);
+ appearance.setPointAttributes(pa);
+ }
+
+ shape = new Shape3D(geom,appearance);
+ shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+ shape.setCapability(Shape3D.ENABLE_PICK_REPORTING);
+ spinTg.addChild(shape);
+ }
+
+ // add it to the scene graph.
+ objTrans.addChild(spinTg);
+
+ return objTrans;
+ }
+
+ private void setPickMode(int mode) {
+ behavior1.setMode(mode);
+ behavior2.setMode(mode);
+ behavior3.setMode(mode);
+ }
+
+ private void setPickTolerance(float tolerance) {
+ behavior1.setTolerance(tolerance);
+ behavior2.setTolerance(tolerance);
+ behavior3.setTolerance(tolerance);
+ }
+
+ private void setViewMode(int mode) {
+ view.setProjectionPolicy(mode);
+ }
+
+ // GUI stuff
+
+ String pickModeString = new String("Pick Mode");
+ String boundsString = new String("BOUNDS");
+ String geometryString = new String("GEOMETRY");
+ String toleranceString = new String("Pick Tolerance");
+ String tolerance0String = new String("0");
+ String tolerance2String = new String("2");
+ String tolerance4String = new String("4");
+ String tolerance8String = new String("8");
+ String viewModeString = new String("View Mode");
+ String perspectiveString = new String("Perspective");
+ String parallelString = new String("Parallel");
+
+ private void addRadioButton(JPanel panel, ButtonGroup bg, String ownerName,
+ String buttonName, boolean selected) {
+ JRadioButton item;
+ item = new JRadioButton(buttonName);
+ item.setName(ownerName);
+ item.addActionListener(this);
+ if (selected) {
+ item.setSelected(true);
+ }
+ panel.add(item);
+ bg.add(item);
+ }
+
+ private void setupGUI(JPanel panel) {
+ ButtonGroup bg;
+
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+ panel.setBorder(new BevelBorder(BevelBorder.RAISED));
+
+ panel.add(new JLabel(pickModeString));
+ bg = new ButtonGroup();
+ addRadioButton(panel, bg, pickModeString, boundsString, true);
+ addRadioButton(panel, bg, pickModeString, geometryString, false);
+
+ panel.add(new JLabel(toleranceString));
+ bg = new ButtonGroup();
+ addRadioButton(panel, bg, toleranceString, tolerance0String,false);
+ addRadioButton(panel, bg, toleranceString, tolerance2String,true);
+ addRadioButton(panel, bg, toleranceString, tolerance4String,false);
+ addRadioButton(panel, bg, toleranceString, tolerance8String,false);
+
+ panel.add(new JLabel(viewModeString));
+ bg = new ButtonGroup();
+ addRadioButton(panel, bg, viewModeString, perspectiveString, true);
+ addRadioButton(panel, bg, viewModeString, parallelString, false);
+
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ String name = ((Component)e.getSource()).getName();
+ String value = e.getActionCommand();
+ //System.out.println("action: name = " + name + " value = " + value);
+ if (name == pickModeString) {
+ if (value == boundsString) {
+ setPickMode(PickInfo.PICK_BOUNDS);
+ } else if (value == geometryString) {
+ setPickMode(PickInfo.PICK_GEOMETRY);
+ } else {
+ System.out.println("Unknown pick mode: " + value);
+ }
+ } else if (name == toleranceString) {
+ if (value == tolerance0String) {
+ setPickTolerance(0.0f);
+ } else if (value == tolerance2String) {
+ setPickTolerance(2.0f);
+ } else if (value == tolerance4String) {
+ setPickTolerance(4.0f);
+ } else if (value == tolerance8String) {
+ setPickTolerance(8.0f);
+ } else {
+ System.out.println("Unknown tolerance: " + value);
+ }
+ } else if (name == viewModeString) {
+ if (value == perspectiveString) {
+ setViewMode(View.PERSPECTIVE_PROJECTION);
+ } else if (value == parallelString) {
+ setViewMode(View.PARALLEL_PROJECTION);
+ }
+ } else {
+ System.out.println("Unknown action name: " + name);
+ }
+ }
+
+ public PickTest (){
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
+ add("Center", c);
+
+ JPanel guiPanel = new JPanel();
+ setupGUI(guiPanel);
+ add(guiPanel, BorderLayout.EAST);
+
+ // Create a scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph(c);
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+ view = u.getViewer().getView();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+ public static void main(String argv[])
+ {
+
+ BranchGroup group;
+
+ new MainFrame(new PickTest(), 750, 550);
+ }
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/PickText3DBounds.java b/src/classes/org/jdesktop/j3d/examples/picking/PickText3DBounds.java
new file mode 100644
index 0000000..52442ec
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/PickText3DBounds.java
@@ -0,0 +1,234 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import com.sun.j3d.utils.picking.PickTool;
+import com.sun.j3d.utils.picking.behaviors.*;
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+import java.awt.*;
+import java.lang.String;
+
+public class PickText3DBounds extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(Canvas3D canvas) {
+ Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f);
+ Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+
+ Transform3D t;
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ Material m = new Material(objColor, eColor, objColor, sColor, 100.0f);
+ Appearance a = new Appearance();
+ m.setLightingEnable(true);
+ a.setMaterial(m);
+ Font3D f3d = new Font3D(new Font("TestFont", Font.PLAIN, 1),
+ new FontExtrusion());
+ Text3D txt = new Text3D(f3d, new String("TEXT3D"),
+ new Point3f(-2.0f, 0.0f, 0.0f));
+ // txt.setCapability(Geometry.ALLOW_INTERSECT);
+ Shape3D s3D = new Shape3D();
+ s3D.setGeometry(txt);
+ s3D.setAppearance(a);
+
+ // Create a transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime.
+ TransformGroup spinTg = new TransformGroup();
+ spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ spinTg.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+
+ spinTg.addChild(s3D);
+ objScale.addChild(spinTg);
+
+ // Create the transform group node for the each light and initialize
+ // it to the identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add them to the root
+ // of the subgraph.
+
+ // Create transformations for the positional lights
+ t = new Transform3D();
+ Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0);
+ t.set(lPos1);
+ TransformGroup l1Trans = new TransformGroup(t);
+ l1Trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ l1Trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ l1Trans.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ objScale.addChild(l1Trans);
+
+ t = new Transform3D();
+ Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0);
+ t.set(lPos2);
+ TransformGroup l2Trans = new TransformGroup(t);
+ l2Trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ l2Trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ l2Trans.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+
+ objScale.addChild(l2Trans);
+
+ // Create Geometry for point lights
+ ColoringAttributes caL1 = new ColoringAttributes();
+ ColoringAttributes caL2 = new ColoringAttributes();
+ caL1.setColor(lColor1);
+ caL2.setColor(lColor2);
+ Appearance appL1 = new Appearance();
+ Appearance appL2 = new Appearance();
+ appL1.setColoringAttributes(caL1);
+ appL2.setColoringAttributes(caL2);
+ l1Trans.addChild(new Sphere(0.05f,
+ Sphere.GENERATE_NORMALS, 15, appL1));
+ l2Trans.addChild(new Sphere(0.05f,
+ Sphere.GENERATE_NORMALS, 15, appL2));
+
+ // Create lights
+ AmbientLight aLgt = new AmbientLight(alColor);
+
+ Light lgt1;
+ Light lgt2;
+
+ Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f atten = new Point3f(1.0f, 0.0f, 0.0f);
+ lgt1 = new PointLight(lColor1, lPoint, atten);
+ lgt2 = new PointLight(lColor2, lPoint, atten);
+
+ // Set the influencing bounds
+ aLgt.setInfluencingBounds(bounds);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+
+ // Add the lights into the scene graph
+ objScale.addChild(aLgt);
+ l1Trans.addChild(lgt1);
+ l2Trans.addChild(lgt2);
+
+
+ PickRotateBehavior behavior1 =
+ new PickRotateBehavior(objRoot, canvas, bounds);
+ behavior1.setMode(PickTool.BOUNDS);
+ objRoot.addChild(behavior1);
+
+ PickZoomBehavior behavior2 =
+ new PickZoomBehavior(objRoot, canvas, bounds);
+ behavior2.setMode(PickTool.BOUNDS);
+ objRoot.addChild(behavior2);
+
+ PickTranslateBehavior behavior3 =
+ new PickTranslateBehavior(objRoot, canvas, bounds);
+ behavior3.setMode(PickTool.BOUNDS);
+ objRoot.addChild(behavior3);
+
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public PickText3DBounds() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ u = new SimpleUniverse(c);
+ BranchGroup scene = createSceneGraph(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows Text3DMotion to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new PickText3DBounds(), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java b/src/classes/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java
new file mode 100644
index 0000000..40c2736
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java
@@ -0,0 +1,252 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import com.sun.j3d.utils.picking.PickTool;
+import com.sun.j3d.utils.picking.behaviors.*;
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+import java.awt.*;
+import java.lang.String;
+
+public class PickText3DGeometry extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(Canvas3D canvas) {
+ Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f);
+ Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+
+ Transform3D t;
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ Material m = new Material(objColor, eColor, objColor, sColor, 100.0f);
+ Appearance a = new Appearance();
+ m.setLightingEnable(true);
+ a.setMaterial(m);
+ Font3D f3d = new Font3D(new Font("TestFont", Font.PLAIN, 1),
+ new FontExtrusion());
+
+ Text3D text3D = new Text3D(f3d, new String("TEXT3D"),
+ new Point3f(-2.0f, 0.7f, 0.0f));
+ text3D.setCapability(Geometry.ALLOW_INTERSECT);
+ Shape3D s3D1 = new Shape3D();
+ s3D1.setGeometry(text3D);
+ s3D1.setAppearance(a);
+
+ // Create a transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime.
+ TransformGroup spinTg1 = new TransformGroup();
+ spinTg1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ spinTg1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ spinTg1.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+
+ spinTg1.addChild(s3D1);
+ objScale.addChild(spinTg1);
+
+ Text3D pick = new Text3D(f3d, new String("Pick me"),
+ new Point3f(-2.0f, -0.7f, 0.0f));
+ pick.setCapability(Geometry.ALLOW_INTERSECT);
+ Shape3D s3D2 = new Shape3D();
+ s3D2.setGeometry(pick);
+ s3D2.setAppearance(a);
+
+ // Create a transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime.
+ TransformGroup spinTg2 = new TransformGroup();
+ spinTg2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ spinTg2.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ spinTg2.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+
+ spinTg2.addChild(s3D2);
+ objScale.addChild(spinTg2);
+
+ // Create the transform group node for the each light and initialize
+ // it to the identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add them to the root
+ // of the subgraph.
+
+ // Create transformations for the positional lights
+ t = new Transform3D();
+ Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0);
+ t.set(lPos1);
+ TransformGroup l1Trans = new TransformGroup(t);
+ l1Trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ l1Trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ l1Trans.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ objScale.addChild(l1Trans);
+
+ t = new Transform3D();
+ Vector3d lPos2 = new Vector3d(0.5, 1.2, 2.0);
+ t.set(lPos2);
+ TransformGroup l2Trans = new TransformGroup(t);
+ l2Trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ l2Trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ l2Trans.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ objScale.addChild(l2Trans);
+
+ // Create Geometry for point lights
+ ColoringAttributes caL1 = new ColoringAttributes();
+ ColoringAttributes caL2 = new ColoringAttributes();
+ caL1.setColor(lColor1);
+ caL2.setColor(lColor2);
+ Appearance appL1 = new Appearance();
+ Appearance appL2 = new Appearance();
+ appL1.setColoringAttributes(caL1);
+ appL2.setColoringAttributes(caL2);
+ l1Trans.addChild(new Sphere(0.05f,
+ Sphere.GENERATE_NORMALS | Sphere.ENABLE_GEOMETRY_PICKING, 15, appL1));
+ l2Trans.addChild(new Sphere(0.05f,
+ Sphere.GENERATE_NORMALS | Sphere.ENABLE_GEOMETRY_PICKING, 15, appL2));
+
+ // Create lights
+ AmbientLight aLgt = new AmbientLight(alColor);
+
+ Light lgt1;
+ Light lgt2;
+
+ Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f atten = new Point3f(1.0f, 0.0f, 0.0f);
+ lgt1 = new PointLight(lColor1, lPoint, atten);
+ lgt2 = new PointLight(lColor2, lPoint, atten);
+
+ // Set the influencing bounds
+ aLgt.setInfluencingBounds(bounds);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+
+ // Add the lights into the scene graph
+ objScale.addChild(aLgt);
+ l1Trans.addChild(lgt1);
+ l2Trans.addChild(lgt2);
+
+ PickRotateBehavior behavior1 =
+ new PickRotateBehavior(objRoot, canvas, bounds);
+ behavior1.setMode(PickTool.GEOMETRY);
+ behavior1.setTolerance(0.0f);
+ objRoot.addChild(behavior1);
+
+ PickZoomBehavior behavior2 =
+ new PickZoomBehavior(objRoot, canvas, bounds);
+ behavior2.setMode(PickTool.GEOMETRY);
+ behavior2.setTolerance(0.0f);
+ objRoot.addChild(behavior2);
+
+ PickTranslateBehavior behavior3 =
+ new PickTranslateBehavior(objRoot, canvas, bounds);
+ behavior3.setMode(PickTool.GEOMETRY);
+ behavior3.setTolerance(0.0f);
+ objRoot.addChild(behavior3);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public PickText3DGeometry() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ u = new SimpleUniverse(c);
+ BranchGroup scene = createSceneGraph(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows Text3DMotion to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new PickText3DGeometry(), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/RandomColorCube.java b/src/classes/org/jdesktop/j3d/examples/picking/RandomColorCube.java
new file mode 100644
index 0000000..cd47a2a
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/RandomColorCube.java
@@ -0,0 +1,131 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class RandomColorCube extends QuadArray {
+ RandomColorCube() {
+ super(24, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
+
+ Point3f verts[] = new Point3f[8];
+ Color3f colors[] = new Color3f[3];
+
+ verts[0] = new Point3f(0.5f, 0.5f, 0.5f);
+ verts[1] = new Point3f(-0.5f, 0.5f, 0.5f);
+ verts[2] = new Point3f(-0.5f,-0.5f, 0.5f);
+ verts[3] = new Point3f( 0.5f,-0.5f, 0.5f);
+ verts[4] = new Point3f( 0.5f, 0.5f,-0.5f);
+ verts[5] = new Point3f( -0.5f, 0.5f,-0.5f);
+ verts[6] = new Point3f( -0.5f,-0.5f,-0.5f);
+ verts[7] = new Point3f( 0.5f,-0.5f,-0.5f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+
+ Point3f pnts[] = new Point3f[24];
+ Color3f clrs[] = new Color3f[24];
+
+ pnts[0] = verts[0];
+ clrs[0] = colors[(int)(Math.random()*3.0)];
+ pnts[1] = verts[3];
+ clrs[1] = colors[(int)(Math.random()*3.0)];
+ pnts[2] = verts[7];
+ clrs[2] = colors[(int)(Math.random()*3.0)];
+ pnts[3] = verts[4];
+ clrs[3] = colors[(int)(Math.random()*3.0)];
+
+ pnts[4] = verts[1];
+ clrs[4] = colors[(int)(Math.random()*3.0)];
+ pnts[5] = verts[5];
+ clrs[5] = colors[(int)(Math.random()*3.0)];
+ pnts[6] = verts[6];
+ clrs[6] = colors[(int)(Math.random()*3.0)];
+ pnts[7] = verts[2];
+ clrs[7] = colors[(int)(Math.random()*3.0)];
+
+ pnts[8] = verts[0];
+ clrs[8] = colors[(int)(Math.random()*3.0)];
+ pnts[9] = verts[4];
+ clrs[9] = colors[(int)(Math.random()*3.0)];
+ pnts[10] = verts[5];
+ clrs[10] = colors[(int)(Math.random()*3.0)];
+ pnts[11] = verts[1];
+ clrs[11] = colors[(int)(Math.random()*3.0)];
+
+ pnts[12] = verts[3];
+ clrs[12] = colors[(int)(Math.random()*3.0)];
+ pnts[13] = verts[2];
+ clrs[13] = colors[(int)(Math.random()*3.0)];
+ pnts[14] = verts[6];
+ clrs[14] = colors[(int)(Math.random()*3.0)];
+ pnts[15] = verts[7];
+ clrs[15] = colors[(int)(Math.random()*3.0)];
+
+ pnts[16] = verts[0];
+ clrs[16] = colors[(int)(Math.random()*3.0)];
+ pnts[17] = verts[1];
+ clrs[17] = colors[(int)(Math.random()*3.0)];
+ pnts[18] = verts[2];
+ clrs[18] = colors[(int)(Math.random()*3.0)];
+ pnts[19] = verts[3];
+ clrs[19] = colors[(int)(Math.random()*3.0)];
+
+ pnts[20] = verts[7];
+ clrs[20] = colors[(int)(Math.random()*3.0)];
+ pnts[21] = verts[6];
+ clrs[21] = colors[(int)(Math.random()*3.0)];
+ pnts[22] = verts[5];
+ clrs[22] = colors[(int)(Math.random()*3.0)];
+ pnts[23] = verts[4];
+ clrs[23] = colors[(int)(Math.random()*3.0)];
+
+
+ setCoordinates(0, pnts);
+ setColors(0, clrs);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java b/src/classes/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java
new file mode 100644
index 0000000..7ff0ff9
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java
@@ -0,0 +1,101 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class RandomColorTetrahedron extends TriangleArray {
+
+ RandomColorTetrahedron() {
+ super(12, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(0.5f,0.5f,0.5f);
+ verts[1] = new Point3f(0.5f,-0.5f,-0.5f);
+ verts[2] = new Point3f(-0.5f,-0.5f,0.5f);
+ verts[3] = new Point3f(-0.5f,0.5f,-0.5f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+
+ Point3f pnts[] = new Point3f[12];
+ Color3f clrs[] = new Color3f[12];
+
+ pnts[0] = verts[2];
+ clrs[0] = colors[(int)(Math.random() * 3.0)];
+ pnts[1] = verts[1];
+ clrs[1] = colors[(int)(Math.random() * 3.0)];
+ pnts[2] = verts[0];
+ clrs[2] = colors[(int)(Math.random() * 3.0)];
+
+ pnts[3] = verts[3];
+ clrs[3] = colors[(int)(Math.random() * 3.0)];
+ pnts[4] = verts[2];
+ clrs[4] = colors[(int)(Math.random() * 3.0)];
+ pnts[5] = verts[0];
+ clrs[5] = colors[(int)(Math.random() * 3.0)];
+
+ pnts[6] = verts[1];
+ clrs[6] = colors[(int)(Math.random() * 3.0)];
+ pnts[7] = verts[2];
+ clrs[7] = colors[(int)(Math.random() * 3.0)];
+ pnts[8] = verts[3];
+ clrs[8] = colors[(int)(Math.random() * 3.0)];
+
+ pnts[9] = verts[1];
+ clrs[9] = colors[(int)(Math.random() * 3.0)];
+ pnts[10] = verts[3];
+ clrs[10] = colors[(int)(Math.random() * 3.0)];
+ pnts[11] = verts[0];
+ clrs[11] = colors[(int)(Math.random() * 3.0)];
+
+ setCoordinates(0, pnts);
+ setColors(0, clrs);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/Tetrahedron.java b/src/classes/org/jdesktop/j3d/examples/picking/Tetrahedron.java
new file mode 100644
index 0000000..aca7653
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/Tetrahedron.java
@@ -0,0 +1,112 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Tetrahedron extends Shape3D {
+ private static final float sqrt3 = (float) Math.sqrt(3.0);
+ private static final float sqrt3_3 = sqrt3 / 3.0f;
+ private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;
+
+ private static final float ycenter = 0.5f * sqrt24_3;
+ private static final float zcenter = -sqrt3_3;
+
+ private static final Point3f p1 = new Point3f(-1.0f, -ycenter, -zcenter);
+ private static final Point3f p2 = new Point3f(1.0f, -ycenter, -zcenter);
+ private static final Point3f p3 =
+ new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
+ private static final Point3f p4 =
+ new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);
+
+ private static final Point3f[] verts = {
+ p1, p2, p4, // front face
+ p1, p4, p3, // left, back face
+ p2, p3, p4, // right, back face
+ p1, p3, p2, // bottom face
+ };
+
+ private TexCoord2f texCoord[] = {
+ new TexCoord2f(0.0f, 0.0f),
+ new TexCoord2f(1.0f, 0.0f),
+ new TexCoord2f(0.5f, sqrt3 / 2.0f),
+ };
+
+ public Tetrahedron() {
+ int i;
+
+ TriangleArray tetra = new TriangleArray(12, TriangleArray.COORDINATES |
+ TriangleArray.NORMALS | TriangleArray.TEXTURE_COORDINATE_2);
+
+ tetra.setCoordinates(0, verts);
+ for (i = 0; i < 12; i++) {
+ tetra.setTextureCoordinate(0, i, texCoord[i%3]);
+ }
+
+ int face;
+ Vector3f normal = new Vector3f();
+ Vector3f v1 = new Vector3f();
+ Vector3f v2 = new Vector3f();
+ Point3f [] pts = new Point3f[3];
+ for (i = 0; i < 3; i++) pts[i] = new Point3f();
+
+ for (face = 0; face < 4; face++) {
+ tetra.getCoordinates(face*3, pts);
+ v1.sub(pts[1], pts[0]);
+ v2.sub(pts[2], pts[0]);
+ normal.cross(v1, v2);
+ normal.normalize();
+ for (i = 0; i < 3; i++) {
+ tetra.setNormal((face * 3 + i), normal);
+ }
+ }
+
+ tetra.setCapability(Geometry.ALLOW_INTERSECT);
+
+ this.setGeometry(tetra);
+ this.setAppearance(new Appearance());
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILA.java b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILA.java
new file mode 100644
index 0000000..55ab409
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILA.java
@@ -0,0 +1,106 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class TetrahedronILA extends IndexedLineArray {
+
+ TetrahedronILA() {
+ super(4, GeometryArray.COORDINATES | GeometryArray.COLOR_3, 12);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(1.0f,1.0f,1.0f);
+ verts[1] = new Point3f(1.0f,-1.0f,-1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f,1.0f);
+ verts[3] = new Point3f(-1.0f,1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+
+ int[] pntsIndex = new int[12];
+ int[] clrsIndex = new int[12];
+
+ pntsIndex[0] = 0;
+ clrsIndex[0] = 0;
+ pntsIndex[1] = 1;
+ clrsIndex[1] = 1;
+
+ pntsIndex[2] = 1;
+ clrsIndex[2] = 1;
+ pntsIndex[3] = 2;
+ clrsIndex[3] = 2;
+
+ pntsIndex[4] = 2;
+ clrsIndex[4] = 2;
+ pntsIndex[5] = 0;
+ clrsIndex[5] = 0;
+
+ pntsIndex[6] = 1;
+ clrsIndex[6] = 1;
+ pntsIndex[7] = 3;
+ clrsIndex[7] = 3;
+
+ pntsIndex[8] = 2;
+ clrsIndex[8] = 2;
+ pntsIndex[9] = 3;
+ clrsIndex[9] = 3;
+
+ pntsIndex[10] = 0;
+ clrsIndex[10] = 0;
+ pntsIndex[11] = 3;
+ clrsIndex[11] = 3;
+
+ setCoordinates(0, verts);
+ setCoordinateIndices(0, pntsIndex);
+ setColors(0, colors);
+ setColorIndices(0, clrsIndex);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java
new file mode 100644
index 0000000..3f6530a
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java
@@ -0,0 +1,97 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class TetrahedronILSA extends IndexedLineStripArray {
+
+ private static final int[] lineLengths = {
+ 4, 4
+ };
+ TetrahedronILSA() {
+ super(4, GeometryArray.COORDINATES | GeometryArray.COLOR_3, 8, lineLengths);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(1.0f,1.0f,1.0f);
+ verts[1] = new Point3f(1.0f,-1.0f,-1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f,1.0f);
+ verts[3] = new Point3f(-1.0f,1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+
+ int pntsIndex[] = new int[8];
+ int clrsIndex[] = new int[8];
+
+ pntsIndex[0] = 0;
+ clrsIndex[0] = 0;
+ pntsIndex[1] = 1;
+ clrsIndex[1] = 1;
+ pntsIndex[2] = 3;
+ clrsIndex[2] = 3;
+ pntsIndex[3] = 2;
+ clrsIndex[3] = 2;
+
+ pntsIndex[4] = 1;
+ clrsIndex[4] = 1;
+ pntsIndex[5] = 2;
+ clrsIndex[5] = 2;
+ pntsIndex[6] = 0;
+ clrsIndex[6] = 0;
+ pntsIndex[7] = 3;
+ clrsIndex[7] = 3;
+
+ setCoordinates(0, verts);
+ setCoordinateIndices(0, pntsIndex);
+ setColors(0, colors);
+ setColorIndices(0, clrsIndex);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java
new file mode 100644
index 0000000..26d1eaa
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java
@@ -0,0 +1,81 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class TetrahedronIPA extends IndexedPointArray {
+
+ TetrahedronIPA() {
+ super(4, GeometryArray.COORDINATES | GeometryArray.COLOR_3, 4);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(1.0f,1.0f,1.0f);
+ verts[1] = new Point3f(1.0f,-1.0f,-1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f,1.0f);
+ verts[3] = new Point3f(-1.0f,1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+
+ int pntsIndex[] = new int[4];
+ int clrsIndex[] = new int[4];
+
+ pntsIndex[0] = clrsIndex[0] = 0;
+ pntsIndex[1] = clrsIndex[1] = 1;
+ pntsIndex[2] = clrsIndex[2] = 2;
+ pntsIndex[3] = clrsIndex[3] = 3;
+
+ setCoordinates(0, verts);
+ setCoordinateIndices(0, pntsIndex);
+ setColors(0, colors);
+ setColorIndices(0, clrsIndex);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronITA.java b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronITA.java
new file mode 100644
index 0000000..e3f378e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronITA.java
@@ -0,0 +1,104 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class TetrahedronITA extends IndexedTriangleArray {
+
+ TetrahedronITA() {
+ super(4, GeometryArray.COORDINATES | GeometryArray.COLOR_3, 12);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(1.0f,1.0f,1.0f);
+ verts[1] = new Point3f(1.0f,-1.0f,-1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f,1.0f);
+ verts[3] = new Point3f(-1.0f,1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+
+ int pntsIndex[] = new int[12];
+ int clrsIndex[] = new int[12];
+
+ pntsIndex[0] = 2;
+ clrsIndex[0] = 0;
+ pntsIndex[1] = 1;
+ clrsIndex[1] = 0;
+ pntsIndex[2] = 0;
+ clrsIndex[2] = 0;
+
+ pntsIndex[3] = 3;
+ clrsIndex[3] = 1;
+ pntsIndex[4] = 2;
+ clrsIndex[4] = 1;
+ pntsIndex[5] = 0;
+ clrsIndex[5] = 1;
+
+ pntsIndex[6] = 1;
+ clrsIndex[6] = 2;
+ pntsIndex[7] = 2;
+ clrsIndex[7] = 2;
+ pntsIndex[8] = 3;
+ clrsIndex[8] = 2;
+
+ pntsIndex[9] = 1;
+ clrsIndex[9] = 3;
+ pntsIndex[10] = 3;
+ clrsIndex[10] = 3;
+ pntsIndex[11] = 0;
+ clrsIndex[11] = 3;
+
+ setCoordinates(0, verts);
+ setCoordinateIndices(0, pntsIndex);
+ setColors(0, colors);
+ setColorIndices(0, clrsIndex);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLA.java b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLA.java
new file mode 100644
index 0000000..84467af
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLA.java
@@ -0,0 +1,104 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class TetrahedronLA extends LineArray {
+
+ TetrahedronLA() {
+ super(12, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(1.0f,1.0f,1.0f);
+ verts[1] = new Point3f(1.0f,-1.0f,-1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f,1.0f);
+ verts[3] = new Point3f(-1.0f,1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+
+ Point3f pnts[] = new Point3f[12];
+ Color3f clrs[] = new Color3f[12];
+
+ pnts[0] = verts[0];
+ clrs[0] = colors[0];
+ pnts[1] = verts[1];
+ clrs[1] = colors[1];
+
+ pnts[2] = verts[1];
+ clrs[2] = colors[1];
+ pnts[3] = verts[2];
+ clrs[3] = colors[2];
+
+ pnts[4] = verts[2];
+ clrs[4] = colors[2];
+ pnts[5] = verts[0];
+ clrs[5] = colors[0];
+
+ pnts[6] = verts[1];
+ clrs[6] = colors[1];
+ pnts[7] = verts[3];
+ clrs[7] = colors[3];
+
+ pnts[8] = verts[2];
+ clrs[8] = colors[2];
+ pnts[9] = verts[3];
+ clrs[9] = colors[3];
+
+ pnts[10] = verts[0];
+ clrs[10] = colors[0];
+ pnts[11] = verts[3];
+ clrs[11] = colors[3];
+
+ setCoordinates(0, pnts);
+ setColors(0, clrs);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java
new file mode 100644
index 0000000..320e6e9
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java
@@ -0,0 +1,94 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class TetrahedronLSA extends LineStripArray {
+ private static final int[] lineLengths = {
+ 4, 4
+ };
+ TetrahedronLSA() {
+ super(8, GeometryArray.COORDINATES | GeometryArray.COLOR_3, lineLengths);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(1.0f,1.0f,1.0f);
+ verts[1] = new Point3f(1.0f,-1.0f,-1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f,1.0f);
+ verts[3] = new Point3f(-1.0f,1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+
+ Point3f pnts[] = new Point3f[8];
+ Color3f clrs[] = new Color3f[8];
+
+ pnts[0] = verts[0];
+ clrs[0] = colors[0];
+ pnts[1] = verts[1];
+ clrs[1] = colors[1];
+ pnts[2] = verts[3];
+ clrs[2] = colors[3];
+ pnts[3] = verts[2];
+ clrs[3] = colors[2];
+
+ pnts[4] = verts[1];
+ clrs[4] = colors[1];
+ pnts[5] = verts[2];
+ clrs[5] = colors[2];
+ pnts[6] = verts[0];
+ clrs[6] = colors[0];
+ pnts[7] = verts[3];
+ clrs[7] = colors[3];
+
+ setCoordinates(0, pnts);
+ setColors(0, clrs);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronPA.java b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronPA.java
new file mode 100644
index 0000000..bba5235
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronPA.java
@@ -0,0 +1,71 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class TetrahedronPA extends PointArray {
+
+ TetrahedronPA() {
+ super(4, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(1.0f,1.0f,1.0f);
+ verts[1] = new Point3f(1.0f,-1.0f,-1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f,1.0f);
+ verts[3] = new Point3f(-1.0f,1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+
+ setCoordinates(0, verts);
+ setColors(0, colors);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronTA.java b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronTA.java
new file mode 100644
index 0000000..f41b977
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TetrahedronTA.java
@@ -0,0 +1,102 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+class TetrahedronTA extends TriangleArray {
+
+ TetrahedronTA() {
+ super(12, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
+
+ Point3f verts[] = new Point3f[4];
+ Color3f colors[] = new Color3f[4];
+
+ verts[0] = new Point3f(1.0f,1.0f,1.0f);
+ verts[1] = new Point3f(1.0f,-1.0f,-1.0f);
+ verts[2] = new Point3f(-1.0f,-1.0f,1.0f);
+ verts[3] = new Point3f(-1.0f,1.0f,-1.0f);
+
+ colors[0] = new Color3f(1.0f, 0.0f, 0.0f);
+ colors[1] = new Color3f(0.0f, 1.0f, 0.0f);
+ colors[2] = new Color3f(0.0f, 0.0f, 1.0f);
+ colors[3] = new Color3f(1.0f, 1.0f, 0.0f);
+
+ Point3f pnts[] = new Point3f[12];
+ Color3f clrs[] = new Color3f[12];
+
+ pnts[0] = verts[2];
+ clrs[0] = colors[0];
+ pnts[1] = verts[1];
+ clrs[1] = colors[0];
+ pnts[2] = verts[0];
+ clrs[2] = colors[0];
+
+ pnts[3] = verts[3];
+ clrs[3] = colors[1];
+ pnts[4] = verts[2];
+ clrs[4] = colors[1];
+ pnts[5] = verts[0];
+ clrs[5] = colors[1];
+
+ pnts[6] = verts[1];
+ clrs[6] = colors[2];
+ pnts[7] = verts[2];
+ clrs[7] = colors[2];
+ pnts[8] = verts[3];
+ clrs[8] = colors[2];
+
+ pnts[9] = verts[1];
+ clrs[9] = colors[3];
+ pnts[10] = verts[3];
+ clrs[10] = colors[3];
+ pnts[11] = verts[0];
+ clrs[11] = colors[3];
+
+ setCoordinates(0, pnts);
+ setColors(0, clrs);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/picking/TickTockPicking.java b/src/classes/org/jdesktop/j3d/examples/picking/TickTockPicking.java
new file mode 100644
index 0000000..29eaec0
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/picking/TickTockPicking.java
@@ -0,0 +1,448 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.picking;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class TickTockPicking extends Applet {
+
+ // path the the texture map image
+ private java.net.URL texImage = null;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(Canvas3D c) {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and behaviors
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ // Set up the global lights
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objScale.addChild(aLgt);
+ objScale.addChild(lgt1);
+
+ // Create a pair of transform group nodes and initialize them to
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behaviors can modify them at runtime. Add them to the
+ // root of the subgraph.
+ TransformGroup objTrans1 = new TransformGroup();
+ objTrans1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(objTrans1);
+
+ TransformGroup objTrans2 = new TransformGroup();
+ objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans1.addChild(objTrans2);
+
+ // Create the positioning and scaling transform group node.
+ Transform3D t = new Transform3D();
+ t.set(0.3, new Vector3d(0.0, -1.5, 0.0));
+ TransformGroup objTrans3 = new TransformGroup(t);
+ objTrans2.addChild(objTrans3);
+
+ // Create a simple shape leaf node, set it's appearance, and
+ // add it to the scene graph.
+ Shape3D shape = new Cube();
+ Appearance a = new Appearance();
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ a.setMaterial(new Material(objColor, black, objColor,
+ white, 80.0f));
+ shape.setAppearance(a);
+ shape.setCapability(shape.ALLOW_APPEARANCE_READ);
+ shape.setCapability(shape.ALLOW_APPEARANCE_WRITE);
+ objTrans3.addChild(shape);
+
+ // Create a new Behavior object that will perform the desired
+ // rotation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis1 = new Transform3D();
+ yAxis1.rotX(Math.PI/2.0);
+ Alpha tickTockAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 5000, 2500, 200,
+ 5000, 2500, 200);
+
+ RotationInterpolator tickTock =
+ new RotationInterpolator(tickTockAlpha, objTrans1, yAxis1,
+ -(float) Math.PI/2.0f,
+ (float) Math.PI/2.0f);
+ tickTock.setSchedulingBounds(bounds);
+ objTrans2.addChild(tickTock);
+
+ // Create a new Behavior object that will perform the desired
+ // rotation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis2 = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans2, yAxis2,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans2.addChild(rotator);
+
+ // Now create the simple picking behavior
+ PickHighlightBehavior pickBeh = new
+ PickHighlightBehavior(c, objRoot, bounds);
+
+ // Create a bunch of objects with a behavior and add them
+ // into the scene graph.
+
+ int row, col;
+ Appearance[][] app = new Appearance[3][3];
+
+ for (row = 0; row < 3; row++)
+ for (col = 0; col < 3; col++)
+ app[row][col] = createAppearance(row * 3 + col);
+
+ for (int i = 0; i < 3; i++) {
+ double ypos = (double)(i - 1) * 1.5;
+ for (int j = 0; j < 3; j++) {
+ double xpos = (double)(j - 1) * 1.5;
+ objScale.addChild(createObject(app[i][j], 0.3, xpos, ypos));
+ }
+ }
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+
+ private Appearance createAppearance(int idx) {
+ Appearance app = new Appearance();
+
+ // Globally used colors
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+
+ switch (idx) {
+ // Unlit solid
+ case 0:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(1.0f, 0.2f, 0.4f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+ break;
+ }
+
+
+ // Unlit wire frame
+ case 1:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(1.0f, 0.4f, 0.0f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(pa.POLYGON_LINE);
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+ break;
+ }
+
+ // Unlit points
+ case 2:
+ {
+ // Set up the coloring properties
+ Color3f objColor = new Color3f(1.0f, 1.0f, 0.0f);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(objColor);
+ app.setColoringAttributes(ca);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(pa.POLYGON_POINT);
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+
+ // Set up point attributes
+ PointAttributes pta = new PointAttributes();
+ pta.setPointSize(5.0f);
+ app.setPointAttributes(pta);
+ break;
+ }
+
+ // Lit solid
+ case 3:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ white, 80.0f));
+ break;
+ }
+
+ // Texture mapped, lit solid
+ case 4:
+ {
+ // Set up the texture map
+ TextureLoader tex = new TextureLoader(texImage, this);
+ app.setTexture(tex.getTexture());
+
+ TextureAttributes texAttr = new TextureAttributes();
+ texAttr.setTextureMode(TextureAttributes.MODULATE);
+ app.setTextureAttributes(texAttr);
+
+ // Set up the material properties
+ app.setMaterial(new Material(white, black, white, black, 1.0f));
+ break;
+ }
+
+ // Transparent, lit solid
+ case 5:
+ {
+ // Set up the transparency properties
+ TransparencyAttributes ta = new TransparencyAttributes();
+ ta.setTransparencyMode(ta.BLENDED);
+ ta.setTransparency(0.6f);
+ app.setTransparencyAttributes(ta);
+
+ // Set up the polygon attributes
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setCullFace(pa.CULL_NONE);
+ app.setPolygonAttributes(pa);
+
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.7f, 0.8f, 1.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ black, 1.0f));
+ break;
+ }
+
+ // Lit solid, no specular
+ case 6:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ black, 80.0f));
+ break;
+ }
+
+ // Lit solid, specular only
+ case 7:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f);
+ app.setMaterial(new Material(black, black, black,
+ white, 80.0f));
+ break;
+ }
+
+ // Another lit solid with a different color
+ case 8:
+ {
+ // Set up the material properties
+ Color3f objColor = new Color3f(0.8f, 0.8f, 0.0f);
+ app.setMaterial(new Material(objColor, black, objColor,
+ white, 80.0f));
+ break;
+ }
+
+ default:
+ {
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(new Color3f(0.0f, 1.0f, 0.0f));
+ app.setColoringAttributes(ca);
+ }
+ }
+
+ return app;
+ }
+
+
+ private Group createObject(Appearance app, double scale,
+ double xpos, double ypos) {
+
+ // Create a transform group node to scale and position the object.
+ Transform3D t = new Transform3D();
+ t.set(scale, new Vector3d(xpos, ypos, 0.0));
+ TransformGroup objTrans = new TransformGroup(t);
+
+ // Create a second transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime.
+ TransformGroup spinTg = new TransformGroup();
+ spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+
+ // Create a simple shape leaf node and set the appearance
+ Shape3D shape = new Tetrahedron();
+ shape.setAppearance(app);
+ shape.setCapability(shape.ALLOW_APPEARANCE_READ);
+ shape.setCapability(shape.ALLOW_APPEARANCE_WRITE);
+
+ // add it to the scene graph.
+ spinTg.addChild(shape);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 5000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, spinTg, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ rotator.setSchedulingBounds(bounds);
+
+ // Add the behavior and the transform group to the object
+ objTrans.addChild(rotator);
+ objTrans.addChild(spinTg);
+
+ return objTrans;
+ }
+
+
+ public TickTockPicking() {
+ }
+
+ public TickTockPicking(java.net.URL url) {
+ texImage = url;
+ }
+
+ public void init() {
+ if (texImage == null) {
+ // the path to the image for an applet
+ try {
+ texImage = new java.net.URL(getCodeBase().toString() +
+ "../images/apimage.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph(c);
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows TickTockPicking to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ // the path the the texture map for an application
+ java.net.URL url = null;
+ try {
+ url = new java.net.URL("file:../images/apimage.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ new MainFrame(new TickTockPicking(url), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java b/src/classes/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java
new file mode 100644
index 0000000..1ae48bf
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java
@@ -0,0 +1,200 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.platform_geometry;
+
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.applet.Applet;
+import com.sun.j3d.utils.applet.MainFrame;
+import java.awt.*;
+
+/**
+ * This class demonstrates the use of the Universe builder for stand-alone
+ * applications along with the use of the PlatformGeometry node that is
+ * present in the Java 3D Universe Builder utility. The standard
+ * HelloWorld application is brought up. A transparent cylinder has been
+ * added to the PlatfromGeometry node of the ViewingPlatform and the
+ * MouseTranslate utility has been used to allow this sphere to be dragged
+ * around the canvas.
+ */
+public class SimpleGeometry extends Applet {
+
+ SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(objTrans);
+
+ // Create a simple shape leaf node, add it to the scene graph.
+ objTrans.addChild(new ColorCube());
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ /*
+ * Create the geometry to add to the platform geometry.
+ */
+ PlatformGeometry createAimer() {
+
+ PlatformGeometry pg = new PlatformGeometry();
+
+ // This TransformGroup will be used by the MouseTranslate
+ // utiltiy to move the cylinder around the canvas. when the
+ // the user holds down mouse button 3.
+ TransformGroup moveTG = new TransformGroup();
+ moveTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ moveTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ MouseTranslate mouseT = new MouseTranslate(moveTG);
+ moveTG.addChild(mouseT);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ mouseT.setSchedulingBounds(bounds);
+ pg.addChild(moveTG);
+
+ // This TransformGroup is used to place the cylinder in the scene.
+ // The cylinder will be rotated 90 degrees so it will appear as
+ // a circle on the screen (could be made into a nice gun site...).
+ // The cylinder is also displaced a little in Z so it is in front
+ // of the viewer.
+ Transform3D xForm = new Transform3D();
+ xForm.rotX(Math.PI/2.0);
+ xForm.setTranslation(new Vector3d(0.0, 0.0, -0.7));
+ TransformGroup placementTG = new TransformGroup(xForm);
+ moveTG.addChild(placementTG);
+
+ // Create the cylinder - make it thin and transparent.
+ Appearance cylinderAppearance = new Appearance();
+ TransparencyAttributes transAttrs =
+ new TransparencyAttributes(TransparencyAttributes.FASTEST, 0.5f);
+ // cylinderAppearance.setTransparencyAttributes(transAttrs);
+ Cylinder aimer = new Cylinder(0.06f, 0.005f, 0, cylinderAppearance);
+ placementTG.addChild(aimer);
+
+ return pg;
+ }
+
+ public void init() {
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+
+ u = new SimpleUniverse(c);
+
+ PlatformGeometry pg = createAimer();
+
+ // Now set the just created PlatformGeometry.
+ ViewingPlatform vp = u.getViewingPlatform();
+ vp.setPlatformGeometry(pg);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ // Add everthing to the scene graph - it will now be displayed.
+ u.addBranchGraph(scene);
+ }
+
+ public SimpleGeometry(String[] args) {
+ }
+
+ public SimpleGeometry() {
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public static void main(String[] args) {
+ new MainFrame(new SimpleGeometry(args), 256, 256);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java
new file mode 100644
index 0000000..9dd3def
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java
@@ -0,0 +1,130 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.print_canvas3d;
+
+import javax.swing.*;
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.awt.event.*;
+
+class ImageDisplayer extends JFrame implements ActionListener {
+ BufferedImage bImage;
+
+ private class ImagePanel extends JPanel {
+ public void paint(Graphics g) {
+ g.setColor(Color.black);
+ g.fillRect(0, 0, getSize().width, getSize().height);
+ g.drawImage(bImage, 0, 0, this);
+ }
+
+ private ImagePanel() {
+ setPreferredSize(new Dimension(bImage.getWidth(),
+ bImage.getHeight()));
+ }
+ }
+
+ private JMenuItem printItem;
+ private JMenuItem closeItem;
+
+ private void freeResources() {
+ this.removeAll();
+ this.setVisible(false);
+ bImage = null;
+ }
+
+ public void actionPerformed (ActionEvent event) {
+ Object target = event.getSource();
+
+ if (target == printItem) {
+ new ImagePrinter(bImage).print();
+ }
+ else if (target == closeItem) {
+ freeResources();
+ }
+ }
+
+ private JMenuBar createMenuBar() {
+ JMenuBar menuBar = new JMenuBar();
+ JMenu fileMenu = new JMenu("File");
+ printItem = new JMenuItem("Print...");
+ printItem.addActionListener(this);
+ closeItem = new JMenuItem("Close");
+ closeItem.addActionListener(this);
+ fileMenu.add(printItem);
+ fileMenu.add(new JSeparator());
+ fileMenu.add(closeItem);
+ menuBar.add(fileMenu);
+ return menuBar;
+ }
+
+ ImageDisplayer(BufferedImage bImage) {
+ this.bImage = bImage;
+ this.setTitle("Off-screen Canvas3D Snapshot");
+
+ // Create and initialize menu bar
+ this.setJMenuBar(createMenuBar());
+
+ // Create scroll pane, and embedded image panel
+ ImagePanel imagePanel = new ImagePanel();
+ JScrollPane scrollPane = new JScrollPane(imagePanel);
+ scrollPane.getViewport().setPreferredSize(new Dimension(700, 700));
+
+ // Handle the close event
+ this.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent winEvent) {
+ freeResources();
+ }
+ });
+
+ // Add scroll pane to the frame and make it visible
+ this.getContentPane().add(scrollPane);
+ this.pack();
+ this.setVisible(true);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java
new file mode 100644
index 0000000..1714373
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java
@@ -0,0 +1,112 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.print_canvas3d;
+
+import java.awt.print.*;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.awt.geom.AffineTransform;
+
+class ImagePrinter implements Printable, ImageObserver {
+ BufferedImage bImage;
+
+ public int print(Graphics g, PageFormat pf, int pi)
+ throws PrinterException {
+
+
+ if (pi >= 1) {
+ return Printable.NO_SUCH_PAGE;
+ }
+
+ Graphics2D g2d = (Graphics2D)g;
+ //g2d.translate(pf.getImageableX(), pf.getImageableY());
+ AffineTransform t2d = new AffineTransform();
+ t2d.translate(pf.getImageableX(), pf.getImageableY());
+ double xscale = pf.getImageableWidth() / (double)bImage.getWidth();
+ double yscale = pf.getImageableHeight() / (double)bImage.getHeight();
+ double scale = Math.min(xscale, yscale);
+ t2d.scale(scale, scale);
+ try {
+ g2d.drawImage(bImage,t2d, this);
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ return Printable.NO_SUCH_PAGE;
+ }
+ return Printable.PAGE_EXISTS;
+ }
+
+ void print() {
+ PrinterJob printJob = PrinterJob.getPrinterJob();
+ PageFormat pageFormat = printJob.defaultPage();
+ pageFormat.setOrientation(PageFormat.LANDSCAPE);
+ pageFormat = printJob.validatePage(pageFormat);
+ printJob.setPrintable(this, pageFormat);
+ if (printJob.printDialog()) {
+ try {
+ printJob.print();
+ }
+ catch (PrinterException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public boolean imageUpdate(Image img,
+ int infoflags,
+ int x,
+ int y,
+ int width,
+ int height) {
+ return false;
+ }
+
+ ImagePrinter(BufferedImage bImage) {
+ this.bImage = bImage;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java
new file mode 100644
index 0000000..474f386
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java
@@ -0,0 +1,82 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.print_canvas3d;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.image.BufferedImage;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+
+class OffScreenCanvas3D extends Canvas3D {
+ OffScreenCanvas3D(GraphicsConfiguration graphicsConfiguration,
+ boolean offScreen) {
+
+ super(graphicsConfiguration, offScreen);
+ }
+
+ BufferedImage doRender(int width, int height) {
+
+ BufferedImage bImage =
+ new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+
+ ImageComponent2D buffer =
+ new ImageComponent2D(ImageComponent.FORMAT_RGBA, bImage);
+
+ setOffScreenBuffer(buffer);
+ renderOffScreenBuffer();
+ waitForOffScreenRendering();
+ bImage = getOffScreenBuffer().getImage();
+
+ // To release the reference of buffer inside Java 3D.
+ setOffScreenBuffer(null);
+
+ return bImage;
+ }
+
+ public void postSwap() {
+ // No-op since we always wait for off-screen rendering to complete
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form
new file mode 100644
index 0000000..5150ee2
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <NonVisualComponents>
+ <Menu class="javax.swing.JMenuBar" name="jMenuBar1">
+ <SubComponents>
+ <Menu class="javax.swing.JMenu" name="fileMenu">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="File"/>
+ </Properties>
+ <SubComponents>
+ <MenuItem class="javax.swing.JMenuItem" name="snapShotMenuItem">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Snapshot"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="snapShotMenuItemActionPerformed"/>
+ </Events>
+ </MenuItem>
+ <MenuItem class="javax.swing.JMenuItem" name="printMenuItem">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Print"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="printMenuItemActionPerformed"/>
+ </Events>
+ </MenuItem>
+ <MenuItem class="javax.swing.JMenuItem" name="exitMenuItem">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Exit"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exitMenuItemActionPerformed"/>
+ </Events>
+ </MenuItem>
+ </SubComponents>
+ </Menu>
+ </SubComponents>
+ </Menu>
+ </NonVisualComponents>
+ <Properties>
+ <Property name="defaultCloseOperation" type="int" value="3"/>
+ <Property name="title" type="java.lang.String" value="Window Title"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="menuBar" type="java.lang.String" value="jMenuBar1"/>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="drawingPanel">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[500, 500]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java
new file mode 100644
index 0000000..c40993a
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java
@@ -0,0 +1,374 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.print_canvas3d;
+
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.*;
+import java.awt.GraphicsConfiguration;
+import javax.swing.JPopupMenu;
+
+import com.sun.j3d.loaders.objectfile.ObjectFile;
+import com.sun.j3d.loaders.ParsingErrorException;
+import com.sun.j3d.loaders.IncorrectFormatException;
+import com.sun.j3d.loaders.Scene;
+import java.awt.image.BufferedImage;
+import java.awt.event.*;
+import java.io.*;
+import com.sun.j3d.utils.behaviors.mouse.*;
+
+public class PrintCanvas3D extends javax.swing.JFrame {
+
+ private static final boolean noTriangulate = false;
+ private static final boolean noStripify = false;
+ private static final double creaseAngle = 60.0;
+ private Canvas3D onScreenCanvas3D;
+ private OffScreenCanvas3D offScreenCanvas3D;
+ private String filename = null;
+ private static final int OFF_SCREEN_SCALE = 3;
+
+ private SimpleUniverse univ = null;
+
+ public BranchGroup createSceneGraph(String args[]) {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.7);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(objTrans);
+
+ int flags = ObjectFile.RESIZE;
+ if (!noTriangulate) flags |= ObjectFile.TRIANGULATE;
+ if (!noStripify) flags |= ObjectFile.STRIPIFY;
+ ObjectFile f =
+ new ObjectFile(flags,
+ (float)(creaseAngle * Math.PI / 180.0));
+ Scene scene = null;
+ try {
+ scene = f.load(filename);
+ }
+ catch (FileNotFoundException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ catch (ParsingErrorException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ catch (IncorrectFormatException e) {
+ System.err.println(e);
+ System.exit(1);
+ }
+
+ objTrans.addChild(scene.getSceneGroup());
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Create the rotate behavior node
+ MouseRotate behavior = new MouseRotate();
+ behavior.setTransformGroup(objTrans);
+ objTrans.addChild(behavior);
+ behavior.setSchedulingBounds(bounds);
+
+ // Create the zoom behavior node
+ MouseZoom behavior2 = new MouseZoom();
+ behavior2.setTransformGroup(objTrans);
+ objTrans.addChild(behavior2);
+ behavior2.setSchedulingBounds(bounds);
+
+ // Create the translate behavior node
+ MouseTranslate behavior3 = new MouseTranslate();
+ behavior3.setTransformGroup(objTrans);
+ objTrans.addChild(behavior3);
+ behavior3.setSchedulingBounds(bounds);
+
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objRoot.addChild(bgNode);
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ objRoot.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
+ Color3f light2Color = new Color3f(0.3f, 0.3f, 0.4f);
+ Vector3f light2Direction = new Vector3f(-6.0f, -2.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ objRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ objRoot.addChild(light2);
+
+ return objRoot;
+ }
+
+ private void usage() {
+ System.out.println("Usage: java PrintCanvas3D <.obj file>");
+ System.exit(0);
+ } // End of usage
+
+ private OffScreenCanvas3D createOffScreenCanvas(Canvas3D onScreenCanvas3D) {
+ // Create the off-screen Canvas3D object
+ // request an offscreen Canvas3D with a single buffer configuration
+ GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
+ template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY);
+ GraphicsConfiguration gc =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getBestConfiguration(template);
+
+ offScreenCanvas3D = new OffScreenCanvas3D(gc, true);
+ // Set the off-screen size based on a scale factor times the
+ // on-screen size
+ Screen3D sOn = onScreenCanvas3D.getScreen3D();
+ Screen3D sOff = offScreenCanvas3D.getScreen3D();
+ Dimension dim = sOn.getSize();
+ dim.width *= OFF_SCREEN_SCALE;
+ dim.height *= OFF_SCREEN_SCALE;
+ sOff.setSize(dim);
+ sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth() *
+ OFF_SCREEN_SCALE);
+ sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight() *
+ OFF_SCREEN_SCALE);
+
+ // attach the offscreen canvas to the view
+ univ.getViewer().getView().addCanvas3D(offScreenCanvas3D);
+
+ return offScreenCanvas3D;
+
+ }
+
+ private Canvas3D createUniverse() {
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ univ = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ univ.getViewingPlatform().setNominalViewingTransform();
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return c;
+ }
+
+ /**
+ * Creates new form PrintCanvas3D
+ */
+ public PrintCanvas3D(String args[]) {
+
+ if (args.length == 0) {
+ usage();
+ } else {
+ for (int i = 0 ; i < args.length ; i++) {
+ if (args[i].startsWith("-")) {
+ System.err.println("Argument '" + args[i] + "' ignored.");
+ } else {
+ filename = args[i];
+ }
+ }
+ }
+
+ if (filename == null) {
+ usage();
+ }
+
+ // Initialize the GUI components
+ JPopupMenu.setDefaultLightWeightPopupEnabled(false);
+ initComponents();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ onScreenCanvas3D = createUniverse();
+ drawingPanel.add(onScreenCanvas3D, java.awt.BorderLayout.CENTER);
+
+ // Create the content branch and add it to the universe
+ BranchGroup scene = createSceneGraph(args);
+
+ // Create the off-screen Canvas3D object
+ createOffScreenCanvas(onScreenCanvas3D);
+
+ univ.addBranchGraph(scene);
+ }
+
+ // ----------------------------------------------------------------
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents() {
+ drawingPanel = new javax.swing.JPanel();
+ jMenuBar1 = new javax.swing.JMenuBar();
+ fileMenu = new javax.swing.JMenu();
+ snapShotMenuItem = new javax.swing.JMenuItem();
+ printMenuItem = new javax.swing.JMenuItem();
+ exitMenuItem = new javax.swing.JMenuItem();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("Window Title");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(500, 500));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ fileMenu.setText("File");
+ snapShotMenuItem.setText("Snapshot");
+ snapShotMenuItem.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ snapShotMenuItemActionPerformed(evt);
+ }
+ });
+
+ fileMenu.add(snapShotMenuItem);
+
+ printMenuItem.setText("Print");
+ printMenuItem.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ printMenuItemActionPerformed(evt);
+ }
+ });
+
+ fileMenu.add(printMenuItem);
+
+ exitMenuItem.setText("Exit");
+ exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ exitMenuItemActionPerformed(evt);
+ }
+ });
+
+ fileMenu.add(exitMenuItem);
+
+ jMenuBar1.add(fileMenu);
+
+ setJMenuBar(jMenuBar1);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void printMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_printMenuItemActionPerformed
+ Point loc = onScreenCanvas3D.getLocationOnScreen();
+ offScreenCanvas3D.setOffScreenLocation(loc);
+ Dimension dim = onScreenCanvas3D.getSize();
+ dim.width *= OFF_SCREEN_SCALE;
+ dim.height *= OFF_SCREEN_SCALE;
+ BufferedImage bImage =
+ offScreenCanvas3D.doRender(dim.width, dim.height);
+
+ new ImagePrinter(bImage).print();
+
+ }//GEN-LAST:event_printMenuItemActionPerformed
+
+ private void snapShotMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_snapShotMenuItemActionPerformed
+ Point loc = onScreenCanvas3D.getLocationOnScreen();
+ offScreenCanvas3D.setOffScreenLocation(loc);
+ Dimension dim = onScreenCanvas3D.getSize();
+ dim.width *= OFF_SCREEN_SCALE;
+ dim.height *= OFF_SCREEN_SCALE;
+ BufferedImage bImage =
+ offScreenCanvas3D.doRender(dim.width, dim.height);
+
+ new ImageDisplayer(bImage);
+
+
+ }//GEN-LAST:event_snapShotMenuItemActionPerformed
+
+ private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
+ System.exit(0);
+ }//GEN-LAST:event_exitMenuItemActionPerformed
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new PrintCanvas3D(args).setVisible(true);;
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+ private javax.swing.JMenuItem exitMenuItem;
+ private javax.swing.JMenu fileMenu;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JMenuItem printMenuItem;
+ private javax.swing.JMenuItem snapShotMenuItem;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java b/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java
new file mode 100644
index 0000000..72e5bdd
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java
@@ -0,0 +1,151 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.pure_immediate;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.GraphicsConfiguration;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+/**
+ * Pure immediate mode example program. In pure immediate mode, the
+ * renderer must be stopped on the Canvas being rendered into. In our
+ * example, this is done immediately after the canvas is created. A
+ * separate thread is started up to do the immediate mode rendering.
+ */
+public class PureImmediate extends Applet implements Runnable {
+
+ private Canvas3D canvas;
+ private GraphicsContext3D gc = null;
+ private Geometry cube = null;
+ private Transform3D cmt = new Transform3D();
+
+ // One rotation (2*PI radians) every 6 seconds
+ private Alpha rotAlpha = new Alpha(-1, 6000);
+
+ private SimpleUniverse u = null;
+
+ //
+ // Renders a single frame by clearing the canvas, drawing the
+ // geometry, and swapping the draw and display buffer.
+ //
+ public void render() {
+ if (gc == null) {
+ // Set up Graphics context
+ gc = canvas.getGraphicsContext3D();
+ gc.setAppearance(new Appearance());
+
+ // Set up geometry
+ cube = new ColorCube(0.4).getGeometry();
+ }
+
+ // Compute angle of rotation based on alpha value
+ double angle = rotAlpha.value() * 2.0*Math.PI;
+ cmt.rotY(angle);
+
+ // Render the geometry for this frame
+ gc.clear();
+ gc.setModelTransform(cmt);
+ gc.draw(cube);
+ canvas.swap();
+ }
+
+
+ //
+ // Run method for our immediate mode rendering thread.
+ //
+ public void run() {
+ System.out.println("PureImmediate.run: starting main loop");
+ while (true) {
+ render();
+ Thread.yield();
+ }
+ }
+
+
+ public PureImmediate() {
+ }
+
+ //
+ // init: create the canvas, stop the renderer,
+ // create the universe, and start the drawing thread.
+ //
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ canvas = new Canvas3D(config);
+ canvas.stopRenderer();
+ add("Center", canvas);
+
+ // Create the universe and viewing branch
+ u = new SimpleUniverse(canvas);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ // Start a new thread that will continuously render
+ new Thread(this).start();
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows PureImmediate to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new PureImmediate(), 256, 256);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java b/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java
new file mode 100644
index 0000000..8c52509
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java
@@ -0,0 +1,266 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.pure_immediate;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.util.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.geometry.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+/**
+ * Pure immediate mode stereo example program for stereo. In pure
+ * immediate mode, the renderer must be stopped on the Canvas being
+ * rendered into. In our example, this is done immediately after the
+ * canvas is created. A separate thread is started up to do the
+ * immediate mode rendering.
+ */
+public class PureImmediateStereo extends Applet implements Runnable {
+
+ // Set this to true when the graphics card use shared z buffer
+ // in stereo mode.
+ public static String defaultSharedStereoZbuffer = Boolean.TRUE.toString();
+
+ private boolean sharedStereoZbuffer;
+ private boolean stereoSupport;
+ private Canvas3D canvas;
+ private GraphicsContext3D gc;
+ private Shape3D leftConeBody, rightConeBody;
+ private Shape3D leftConeCap, rightConeCap;
+ private Transform3D cmt = new Transform3D();
+ private Vector3f leftTrans, rightTrans;
+
+ // One rotation (2*PI radians) every 6 seconds
+ private Alpha rotAlpha = new Alpha(-1, 6000);
+ private SimpleUniverse u = null;
+ private double angle;
+
+ // Compute data which is common for both
+ // left and right eye
+ void computeSharedData() {
+ // Compute angle of rotation based on alpha value
+ angle = rotAlpha.value() * 2.0*Math.PI;
+ cmt.rotY(angle);
+ }
+
+ // Render the geometry in right eye
+ void renderLeft() {
+ cmt.setTranslation(leftTrans);
+ gc.setModelTransform(cmt);
+
+ if (sharedStereoZbuffer) {
+ // Graphics card shared same z buffer in stereo mode,
+ // in this case we have to explicitly clearing both
+ // frame buffers.
+ gc.clear();
+ }
+ gc.draw(leftConeBody);
+ gc.draw(leftConeCap);
+ }
+
+ // Render the geometry for right eye
+ void renderRight() {
+ cmt.setTranslation(rightTrans);
+ gc.setModelTransform(cmt);
+
+ if (sharedStereoZbuffer) {
+ // Graphics card shared same z buffer in stereo mode,
+ // in this case we have to explicitly clearing both
+ // frame buffers.
+ gc.clear();
+ }
+ gc.draw(rightConeBody);
+ gc.draw(rightConeCap);
+ }
+
+ //
+ // Run method for our immediate mode rendering thread.
+ //
+ public void run() {
+ // Set up Graphics context
+ gc = canvas.getGraphicsContext3D();
+
+ // We always need to set this for PureImmediate
+ // stereo mode
+ gc.setBufferOverride(true);
+
+ Color3f lightColor = new Color3f(1, 1, 1);
+ Vector3f lightDir = new Vector3f(0, 0, -1);
+ DirectionalLight light = new DirectionalLight(lightColor,
+ lightDir);
+
+ gc.addLight(light);
+
+ Appearance redApp = new Appearance();
+ Appearance greenApp = new Appearance();
+ Color3f ambientColor = new Color3f(0, 0, 0);
+ Color3f emissiveColor = new Color3f(0, 0, 0);
+ Color3f diffuseColor = new Color3f(1, 0, 0);
+ Color3f specularColor = new Color3f(1, 1, 1);
+ redApp.setMaterial(new Material(ambientColor, emissiveColor,
+ diffuseColor, specularColor, 5));
+ diffuseColor = new Color3f(0, 1, 0);
+
+ greenApp.setMaterial(new Material(ambientColor, emissiveColor,
+ diffuseColor, specularColor, 5));
+
+ // Set up geometry
+ Cone leftCone = new Cone(0.4f, 0.6f,
+ Primitive.GENERATE_NORMALS, redApp);
+ Cone rightCone = new Cone(0.4f, 0.6f,
+ Primitive.GENERATE_NORMALS, greenApp);
+ leftConeBody = leftCone.getShape(Cone.BODY);
+ leftConeCap = leftCone.getShape(Cone.CAP);
+
+ rightConeBody = rightCone.getShape(Cone.BODY);
+ rightConeCap = rightCone.getShape(Cone.CAP);
+ leftTrans = new Vector3f(-0.6f, 0, 0);
+ rightTrans = new Vector3f(0.6f, 0, 0);
+
+
+ while (true) {
+ // compute data which is can be used
+ // for both left and right eye
+ computeSharedData();
+
+ if (stereoSupport) {
+ if (!sharedStereoZbuffer) {
+ gc.setStereoMode(GraphicsContext3D.STEREO_BOTH);
+ // This clear both left and right buffers, we
+ // must set STEREO_BOTH before it. Otherwise
+ // it only clear LEFT or RIGHT buffer unless
+ // this is invoke twice for each buffer.
+ gc.clear();
+ }
+
+ gc.setStereoMode(GraphicsContext3D.STEREO_LEFT);
+ renderLeft();
+
+ gc.setStereoMode(GraphicsContext3D.STEREO_RIGHT);
+ renderRight();
+ } else {
+ gc.clear();
+ renderLeft();
+ }
+
+ // This swap both left and right buffers so
+ // there is no need to set STEREO_BOTH before it
+ canvas.swap();
+
+ // Be polite to other threads !
+ Thread.yield();
+ }
+ }
+
+
+ public PureImmediateStereo() {
+ }
+
+ //
+ // init: create the canvas, stop the renderer,
+ // create the universe, and start the drawing thread.
+ //
+ public void init() {
+ setLayout(new BorderLayout());
+
+ // Preferred to use Stereo
+ GraphicsConfigTemplate3D gct = new GraphicsConfigTemplate3D();
+ gct.setStereo(GraphicsConfigTemplate3D.PREFERRED);
+
+ GraphicsConfiguration config =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(gct);
+
+ canvas = new Canvas3D(config);
+ Map map = canvas.queryProperties();
+
+ stereoSupport = canvas.getStereoAvailable();
+
+ if (stereoSupport) {
+ System.out.println("This machine support stereo, you should see a red cone on the left and green cone on the right.");
+ // User can overide the above default behavior using
+ // java3d property.
+ String str = System.getProperty("j3d.sharedstereozbuffer",
+ defaultSharedStereoZbuffer);
+ sharedStereoZbuffer = (new Boolean(str)).booleanValue();
+ } else {
+ System.out.println("Stereo is not support, you should only see the left red cone.");
+ }
+
+ if (!canvas.getDoubleBufferAvailable()) {
+ System.out.println("Double buffer is not support !");
+ }
+
+ // we must stop the Renderer in PureImmediate mode
+ canvas.stopRenderer();
+ add("Center", canvas);
+
+ // Create the universe and viewing branch
+ u = new SimpleUniverse(canvas);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ // Start a new thread that will continuously render
+ (new Thread(this)).start();
+ }
+
+ // Cleanup all Java3D threads and memory when this applet exit
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows PureImmediateStereo to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new PureImmediateStereo(), 512, 256);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/read_raster/ReadRaster.java b/src/classes/org/jdesktop/j3d/examples/read_raster/ReadRaster.java
new file mode 100644
index 0000000..a6be8f3
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/read_raster/ReadRaster.java
@@ -0,0 +1,224 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.read_raster;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.event.*;
+import java.awt.image.DataBufferInt;
+import java.awt.image.BufferedImage;
+import java.awt.GraphicsConfiguration;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+
+public class ReadRaster extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(BufferedImage bImage,
+ Raster readRaster) {
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Raster shape. Add it to the root of the subgraph
+
+ ImageComponent2D drawImageComponent = new ImageComponent2D(
+ ImageComponent.FORMAT_RGB, bImage);
+
+ Raster drawRaster= new Raster(new Point3f(0.0f, 0.0f, 0.0f),
+ Raster.RASTER_COLOR, 0, 0, bImage.getWidth(),
+ bImage.getHeight(), drawImageComponent, null);
+ Shape3D shape = new Shape3D(drawRaster);
+ drawRaster.setCapability(Raster.ALLOW_IMAGE_WRITE);
+ objRoot.addChild(shape);
+
+ // Ceate the transform greup node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+
+ TransformGroup cubeScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setTranslation(new Vector3d(-0.5, 0.5, 0.0));
+ cubeScale.setTransform(t3d);
+
+ cubeScale.addChild(objTrans);
+ objRoot.addChild(cubeScale);
+
+ // Create a simple shape leaf node, add it to the scene graph.
+ objTrans.addChild(new ColorCube(0.3));
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+ myRotationInterpolator rotator =
+ new myRotationInterpolator(drawRaster, readRaster,
+ rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public ReadRaster() {
+ }
+
+ public void init() {
+
+ int width = 128;
+ int height = 128;
+
+ ImageComponent2D readImageComponent = new ImageComponent2D(
+ ImageComponent.FORMAT_RGB, width, height);
+
+ Raster readRaster = new Raster(new Point3f(0.0f,0.0f,0.0f),
+ Raster.RASTER_COLOR, 0, 0, width,
+ height, readImageComponent, null);
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new myCanvas3D(config, readRaster);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BufferedImage bImage = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_ARGB);
+
+ BranchGroup scene = createSceneGraph(bImage, readRaster);
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows ReadRaster to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new ReadRaster(), 256, 256);
+ }
+}
+
+
+class myCanvas3D extends Canvas3D {
+
+ Raster readRaster;
+ GraphicsContext3D gc;
+
+ public myCanvas3D(GraphicsConfiguration graphicsConfiguration,
+ Raster readRaster) {
+
+ super(graphicsConfiguration);
+ this.readRaster = readRaster;
+ gc = getGraphicsContext3D();
+ }
+
+ public void postSwap() {
+ super.postSwap();
+ synchronized(readRaster) {
+ gc.readRaster(readRaster);
+ }
+ }
+}
+
+
+class myRotationInterpolator extends RotationInterpolator {
+ Point3f wPos = new Point3f(0.025f, -0.025f, 0.0f);
+ Raster drawRaster;
+ Raster readRaster;
+ BufferedImage bImage;
+ ImageComponent2D newImageComponent;
+
+ public myRotationInterpolator(Raster drawRaster, Raster readRaster,
+ Alpha alpha,
+ TransformGroup target,
+ Transform3D axisOfRotation,
+ float minimumAngle,
+ float maximumAngle) {
+
+ super(alpha, target, axisOfRotation, minimumAngle, maximumAngle);
+ this.drawRaster = drawRaster;
+ this.readRaster = readRaster;
+ }
+
+ public void processStimulus(Enumeration criteria) {
+
+ synchronized(readRaster) {
+ bImage = readRaster.getImage().getImage();
+ }
+ newImageComponent = new ImageComponent2D(ImageComponent.FORMAT_RGB,
+ bImage);
+ drawRaster.setImage(newImageComponent);
+ super.processStimulus(criteria);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/sound/AudioBehaviorMoveOne.java b/src/classes/org/jdesktop/j3d/examples/sound/AudioBehaviorMoveOne.java
new file mode 100644
index 0000000..e5fc463
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/sound/AudioBehaviorMoveOne.java
@@ -0,0 +1,106 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.sound;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+
+// User defined audio behavior class
+public class AudioBehaviorMoveOne extends Behavior {
+ WakeupOnElapsedTime wt;
+ WakeupOnBehaviorPost wp;
+ PointSound psound = new PointSound();
+ static int WAKEUP_SOUND = 0;
+ long dur;
+ // long time;
+ // long lastTime = -1;
+ boolean first_loop = true;
+ String fileName;
+
+ // Override Behavior's initialize method to setup wakeup criteria
+ public void initialize() {
+ MediaContainer sample = new MediaContainer();
+ sample.setCapability(MediaContainer.ALLOW_URL_WRITE);
+ sample.setCapability(MediaContainer.ALLOW_URL_READ);
+ sample.setURLString(fileName);
+ psound.setSoundData(sample);
+ // exaggerate the sound position now that viewPlatform
+ // tranform is taken into account
+ Point3f soundPos = new Point3f(-20.0f, 0.0f, 0.0f);
+ psound.setPosition(soundPos);
+ WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000);
+ wakeupOn(wp);
+ }
+
+ // Override Behavior's stimulus method to handle the event
+ public void processStimulus(Enumeration criteria) {
+ // time = System.currentTimeMillis();
+ if (first_loop) {
+ first_loop = false;
+ dur = psound.getDuration();
+ if (dur == Sound.DURATION_UNKNOWN)
+ dur = 2000; // Force iterations every 2 seconds
+ // System.out.println(" sound duration time " + dur);
+ wt = new WakeupOnElapsedTime(dur);
+ }
+ else {
+ // System.out.println(" time between setEnables calls "+
+ // (time - lastTime));
+ psound.setEnable(false) ;
+ }
+ psound.setEnable(true);
+ // lastTime = time;
+ wakeupOn(wt);
+ }
+
+ //
+ // Constructor for rotation behavior. Parameter: front and back Sound nodes
+ //
+ public AudioBehaviorMoveOne(PointSound psound, String filename) {
+ this.psound = psound;
+ this.fileName = filename;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/sound/AudioReverberate.java b/src/classes/org/jdesktop/j3d/examples/sound/AudioReverberate.java
new file mode 100644
index 0000000..1d83702
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/sound/AudioReverberate.java
@@ -0,0 +1,171 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.sound;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+
+/*
+ * Pick the JavaSound reverb type that matches the input parameters
+ * as best as possible.
+ *
+ * Hae Reverb Types Size Persistance Delay
+ * ================ ----------- ------------ -----------
+ * 1 None (dry)
+ * 2 "Closet" very small very short <.5 fast smooth
+ * 3 "Garage" med. large medium 1.0 medium
+ * 4 "Acoustic Lab" med. small short .5 med. fast
+ * 5 "Cavern" large long >2.0 very slow
+ * 6 "Dungeon" medium med. long 1.5 med. slow
+ *
+ *
+ * Order is NOT controllable, nor does it have a natural parallel.
+ * For this reason Order and Reflection are tied together as to
+ * affect 'Decay Speed'. This speed paired with the size of the
+ * space implied by the Delay parameter determine the JavaSound
+ * Reverb type that is set:
+ *
+ * | Short: Long:
+ * Speed | Coeff <= 0.9 Coeff > 0.9
+ * Size | Order <= 8 Order > 8
+ * ---------------------------------------------------------------
+ * small (<100ms) | 2 "Closet" 4 "Acoustic Lab"
+ * medium (<500ms) | 3 "Garage" 6 "Dungeon"
+ * large (>500ms) | 6 "Dungeon" 5 "Cavern"
+ */
+// User defined audio behavior class
+public class AudioReverberate extends Behavior {
+ WakeupOnElapsedTime wt;
+ WakeupOnBehaviorPost wp;
+ PointSound psound = new PointSound();
+ AuralAttributes sScape = null;
+ static int WAKEUP_SOUND = 0;
+ long dur;
+ long time;
+ boolean firstTime = true;
+ String fileName;
+ int lCount = 0;
+ int loopCount = 0;
+
+ // Override Behavior's initialize method to setup wakeup criteria
+ public void initialize() {
+ MediaContainer sample = new MediaContainer();
+ sample.setCacheEnable(true);
+ sample.setURLString(fileName);
+ psound.setSoundData(sample);
+ Point3f soundPos = new Point3f(-23.0f, 0.0f, 0.0f);
+ psound.setPosition(soundPos);
+ psound.setLoop(3);
+ firstTime = true;
+ System.out.println("Reverb Name Size Reflect Order Delay ");
+ System.out.println("----------- ---- ------- ----- ----- ");
+ WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000);
+ wakeupOn(wp);
+ }
+
+ // Override Behavior's stimulus method to handle the event
+ public void processStimulus(Enumeration criteria) {
+ // time = System.currentTimeMillis();
+ if (firstTime) {
+ wt = new WakeupOnElapsedTime(10000);
+ firstTime = false;
+ }
+ else
+ psound.setEnable(false) ;
+
+ if (++lCount > 6)
+ lCount = 1;
+
+ if (lCount == 1) {
+ sScape.setReverbDelay(10.0f) ;
+ sScape.setReflectionCoefficient(0.5f) ;
+ sScape.setReverbOrder(5) ;
+ System.out.println("Closet sm 0.5 5 10.0 ");
+ }
+ else if (lCount == 2) {
+ sScape.setReverbDelay(10.0f) ;
+ sScape.setReflectionCoefficient(0.999f) ;
+ sScape.setReverbOrder(9) ;
+ System.out.println("Acoustic Lab sm 0.999 9 10.0 ");
+ }
+ else if (lCount == 3) {
+ sScape.setReverbDelay(200.0f) ;
+ sScape.setReflectionCoefficient(0.4f) ;
+ sScape.setReverbOrder(3) ;
+ System.out.println("Garage med 0.4 3 200.0 ");
+ }
+ else if (lCount == 4) {
+ sScape.setReverbDelay(200.0f) ;
+ sScape.setReflectionCoefficient(0.99f) ;
+ sScape.setReverbOrder(10) ;
+ System.out.println("Dungeon med 0.99 10 200.0 ");
+ }
+ else if (lCount == 5) {
+ sScape.setReverbDelay(600.0f) ;
+ sScape.setReflectionCoefficient(0.33f) ;
+ sScape.setReverbOrder(7) ;
+ System.out.println("Dungeon lrg 0.33 7 600.0 ");
+ }
+ else if (lCount == 6) {
+ sScape.setReverbDelay(600.0f) ;
+ sScape.setReflectionCoefficient(1.0f) ;
+ sScape.setReverbOrder(20) ;
+ System.out.println("Cavern lrg 1.0 20 600.0 ");
+ }
+ psound.setEnable(true);
+ wakeupOn(wt);
+ }
+
+ //
+ // Constructor for rotation behavior. Parameter: front and back Sound nodes
+ //
+ public AudioReverberate(PointSound psound, String filename,
+ AuralAttributes sscape) {
+ this.psound = psound;
+ this.fileName = filename;
+ this.sScape = sscape;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/sound/MoveAppBoundingLeaf.java b/src/classes/org/jdesktop/j3d/examples/sound/MoveAppBoundingLeaf.java
new file mode 100644
index 0000000..7de3b46
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/sound/MoveAppBoundingLeaf.java
@@ -0,0 +1,389 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.sound;
+
+/*
+ * This Java3D program:
+ * Creates an instance of the JavaSoundMixer AudioDevice, initializing it
+ * and attaching it to the PhysicalEnvironment with a special version
+ * of UniverseBuilder (UniverseBuildJS).
+ * Creates one Point sound sources.
+ * Creates two Soundscapes with their own aural attributes. Each
+ * of these Soundscapes defines its own bounding leaf region.
+ * Creates and executes a custom behavior (AudioBehaviorMoveOne) that
+ * starts sound playing and transforms the AuralAttribute positions
+ * by modifying the TransformGroup that contains both soundscape
+ * nodes.
+ * Usage: java MoveAppBoundingLeaf [ URLpath [ name ]]
+ *
+ * The first optional command line parameter is the URL path to directory
+ * containing:
+ * (1) the files that will be named on the command line, or
+ * (2) the javaone/data/sounds directory that contains the default files
+ * If not given the default path is:
+ * file:/net/java3d/export/java3d/javaone/data/sounds
+ * NOTE: This default path is only valid on Solaris Eng Menlo Park network.
+ * A path must be supplied if sound files to be used are in a different
+ * directory location.
+ * NOTE: When running on Java3D Menlo Park Test WinTel platform path should
+ * be set to
+ * file:/java3d/export/java3d/javaone/data/sounds
+ *
+ * The second thru fourth optional command line parameters are sound file names
+ * If not given the default file name is:
+ * unicycle_close.au
+ */
+
+import java.applet.Applet;
+import java.net.URL;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.universe.*;
+import java.io.File;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class MoveAppBoundingLeaf extends Applet {
+
+ // File name of sound sample
+ private static int filenamesGiven = 0;
+ private static URL[] url = new URL[1];
+ private static String[] filename = new String[1];
+ private static String path = null;
+ private static boolean filenamesSet = false;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the subgraph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create the transform group node and initialize it to the identity.
+ // Enable the TRANSFORM_WRITE capability so that our behavior code
+ // can modify it at runtime. Add it to the root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // Create a simple shape leaf node and add it into the scene graph.
+ objTrans.addChild(new ColorCube(0.7));
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 20000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotation,
+ objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+ //
+ // Create a sound node and add it to the scene graph
+ //
+ PointSound sound = new PointSound();
+ sound.setCapability(PointSound.ALLOW_ENABLE_WRITE);
+ sound.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE);
+ sound.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE);
+ sound.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE);
+ sound.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE);
+ sound.setCapability(PointSound.ALLOW_RELEASE_WRITE);
+ sound.setCapability(PointSound.ALLOW_DURATION_READ);
+ sound.setCapability(PointSound.ALLOW_IS_PLAYING_READ);
+ sound.setCapability(PointSound.ALLOW_POSITION_WRITE);
+ sound.setCapability(PointSound.ALLOW_LOOP_WRITE);
+
+ BoundingSphere soundBounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ sound.setSchedulingBounds(soundBounds);
+ objTrans.addChild(sound);
+
+ /*
+ * Spheres denoting aural attribute regions
+ */
+ TransformGroup objTransChild1 = new TransformGroup();
+ TransformGroup objTransChild2 = new TransformGroup();
+ objTransChild1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTransChild2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ Transform3D translate1 = new Transform3D();
+ Transform3D translate2 = new Transform3D();
+ Vector3f vector1 = new Vector3f( 2.0f, 0.0f, 0.0f);
+ Vector3f vector2 = new Vector3f(-2.0f, 0.0f, 0.0f);
+ translate1.setTranslation(vector1);
+ translate2.setTranslation(vector2);
+ objTransChild1.setTransform(translate1);
+ objTransChild2.setTransform(translate2);
+ Sphere sphere1 = new Sphere(0.42f);
+ Sphere sphere2 = new Sphere(0.38f);
+
+ Appearance app = new Appearance();
+ app.setCapability( Appearance.ALLOW_POLYGON_ATTRIBUTES_WRITE );
+ sphere1.setAppearance( app );
+ sphere2.setAppearance( app );
+ objTransChild1.addChild(sphere1);
+ objTransChild2.addChild(sphere2);
+
+ objTrans.addChild(objTransChild1);
+ objTrans.addChild(objTransChild2);
+ /**
+ * Define Soundscapes/AuralAttributes
+ */
+ // First Aural Attributes
+ Point2f[] distanceFilter = new Point2f[2];
+ distanceFilter[0] = new Point2f(6.0f, 6000f);
+ distanceFilter[1] = new Point2f(17.0f, 700f);
+ AuralAttributes attributes = new AuralAttributes(1.0f, 2.0f, 0.3f,
+ 4.0f, 5, distanceFilter, 0.8f, 0.0f);
+ attributes.setReverbDelay(90.0f) ;
+ attributes.setReflectionCoefficient(0.999f) ;
+ attributes.setReverbOrder(9) ;
+
+ // SoundScape
+ BoundingSphere bounds1 =
+ new BoundingSphere(new Point3d(2.0,0.0,0.0), 3.5);
+
+ BoundingLeaf sScapeBounds1 = new BoundingLeaf(bounds1);
+ Soundscape soundScape = new Soundscape(null, attributes);
+ soundScape.setApplicationBoundingLeaf(sScapeBounds1);
+ /** addChild of BoundingLeaf as well**/
+ objTrans.addChild(sScapeBounds1);
+
+ AuralAttributes queryAttribs = new AuralAttributes();
+ if (queryAttribs == null)
+ System.out.println(" new AuralAttributes returned NULL");
+ // else
+ // System.out.println(" new AuralAttributes returned " + queryAttribs);
+ queryAttribs = soundScape.getAuralAttributes();
+ if (queryAttribs == null)
+ System.out.println("getAuralAttributes returned NULL");
+ // else
+ // System.out.println("AuralAttributes for Soundscape 1:");
+ float tmpFloat = queryAttribs.getAttributeGain();
+ // System.out.println(" Gain = " + tmpFloat);
+ tmpFloat = queryAttribs.getRolloff();
+ // System.out.println(" Rolloff = " + tmpFloat);
+ tmpFloat = queryAttribs.getReflectionCoefficient();
+ // System.out.println(" Reflection Coeff = " + tmpFloat);
+ tmpFloat = queryAttribs.getReverbDelay();
+ // System.out.println(" Delay = " + tmpFloat);
+ int tmpInt = queryAttribs.getReverbOrder();
+ // System.out.println(" Order = " + tmpInt);
+ int length = queryAttribs.getDistanceFilterLength();
+ // System.out.println(" Filter length = " + length);
+ Point2f[] tmpPoint = new Point2f[length];
+ tmpPoint = new Point2f[length];
+ for (int i=0; i< length; i++)
+ tmpPoint[i] = new Point2f();
+ queryAttribs.getDistanceFilter(tmpPoint);
+ // for (int i=0; i< length; i++)
+ // System.out.println(" Distance Filter = (" + tmpPoint[i].x +
+ // ", " + tmpPoint[i].y + ")" );
+ tmpFloat = queryAttribs.getFrequencyScaleFactor();
+ // System.out.println(" Freq scalefactor = " + tmpFloat);
+ tmpFloat = queryAttribs.getVelocityScaleFactor();
+ // System.out.println(" Velocity scalefactor= " + tmpFloat);
+ objTrans.addChild(soundScape);
+
+ // System.out.println("SoundScape2**********************************");
+ Soundscape soundScape2 = new Soundscape();
+ distanceFilter = new Point2f[2];
+ distanceFilter[0] = new Point2f(2.0f, 20000.0f);
+ distanceFilter[1] = new Point2f(20.0f, 2000.0f);
+ AuralAttributes attributes2 = new AuralAttributes();
+ attributes2.setAttributeGain(1.2f);
+ attributes2.setRolloff(2.2f);
+ attributes2.setReverbDelay(1313.0f) ;
+ attributes2.setReflectionCoefficient(1.0f) ;
+ attributes2.setReverbOrder(15) ;
+ distanceFilter[0] = new Point2f(5.0f, 15000.0f);
+ distanceFilter[1] = new Point2f(15.0f, 500.0f);
+ attributes2.setDistanceFilter(distanceFilter);
+ attributes2.setFrequencyScaleFactor(0.8f);
+ attributes2.setVelocityScaleFactor(0.0f);
+ BoundingSphere bounds2 =
+ new BoundingSphere(new Point3d(-2.0,0.0,0.0), 0.38);
+ BoundingLeaf sScapeBounds2 = new BoundingLeaf(bounds2);
+ soundScape2.setApplicationBoundingLeaf(sScapeBounds2);
+ // set BoundingLeaf as a child of transform node
+ objTrans.addChild(sScapeBounds2);
+ soundScape2.setAuralAttributes(attributes2);
+
+ queryAttribs = soundScape2.getAuralAttributes();
+ if (queryAttribs == null)
+ System.out.println(" new AuralAttributes returned NULL");
+ // else
+ // System.out.println(" new AuralAttributes returned " + queryAttribs);
+ // System.out.println("AuralAttributes for Soundscape 2:");
+ tmpFloat = queryAttribs.getAttributeGain();
+ // System.out.println(" Gain = " + tmpFloat);
+ tmpFloat = queryAttribs.getRolloff();
+ // System.out.println(" Rolloff = " + tmpFloat);
+ tmpFloat = queryAttribs.getReflectionCoefficient();
+ // System.out.println(" Reflection Coeff = " + tmpFloat);
+ tmpFloat = queryAttribs.getReverbDelay();
+ // System.out.println(" Delay = " + tmpFloat);
+ tmpInt = queryAttribs.getReverbOrder();
+ // System.out.println(" Order = " + tmpInt);
+ length = queryAttribs.getDistanceFilterLength();
+ // System.out.println(" Filter length = " + length);
+ tmpPoint = new Point2f[length];
+ for (int i=0; i< length; i++)
+ tmpPoint[i] = new Point2f();
+ queryAttribs.getDistanceFilter(tmpPoint);
+ // for (int i=0; i< length; i++)
+ // System.out.println(" Distance Filter = (" + tmpPoint[i].x +
+ // ", " + tmpPoint[i].y + ")" );
+ tmpFloat = queryAttribs.getFrequencyScaleFactor();
+ // System.out.println(" Freq scalefactor = " + tmpFloat);
+ tmpFloat = queryAttribs.getVelocityScaleFactor();
+ // System.out.println(" Velocity scalefactor= " + tmpFloat);
+ objTrans.addChild(soundScape2);
+
+ //
+ // Create a new Behavior object that will play the sound
+ //
+ AudioBehaviorMoveOne player = new AudioBehaviorMoveOne(sound,
+ filename[0]);
+ player.setSchedulingBounds(soundBounds);
+ objTrans.addChild(player);
+
+ return objRoot;
+ }
+
+ public MoveAppBoundingLeaf() {
+ }
+
+ public void init() {
+ if (!filenamesSet) {
+ // path is null if started from applet
+ if (path == null) {
+ path = getCodeBase().toString();
+ }
+
+ /*
+ * append given file name to given URL path
+ */
+ if (filenamesGiven > 0) {
+ filename[0] = new String(path + "/" + filename[0]);
+ }
+ else {
+ // fill in default file names if all three not given
+ filename[0] = new String(path + "/techno_machine.au");
+ }
+ filenamesSet = true;
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ /*
+ * Change filenames into URLs
+ */
+ String substr = filename[0].substring(0,4);
+ try {
+ url[0] = new URL(filename[0]);
+ }
+ catch (Exception e) {
+ return;
+ }
+ /*
+ * Create a simple scene and attach it to the virtual universe
+ */
+ u = new SimpleUniverse(c);
+ AudioDevice audioDev = u.getViewer().createAudioDevice();
+ BranchGroup scene = createSceneGraph();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows AuralAttributes to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ if (args.length > 0) {
+ if ( (args[0].startsWith("file"+File.pathSeparator)) ||
+ (args[0].startsWith("http"+File.pathSeparator)) ) {
+ path = args[0];
+ }
+ else {
+ path = "file:" + args[0];
+ }
+ }
+ else {
+ path = "file:.";
+ }
+
+ if (args.length > 1) {
+ filename[0] = args[1];
+ if (filename[0] != null) {
+ filenamesGiven++ ;
+ }
+ }
+
+ new MainFrame(new MoveAppBoundingLeaf(), 256, 256);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/sound/ReverberateSound.java b/src/classes/org/jdesktop/j3d/examples/sound/ReverberateSound.java
new file mode 100644
index 0000000..ad6a2e3
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/sound/ReverberateSound.java
@@ -0,0 +1,222 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.sound;
+
+/*
+ * ReverberateSound
+ *
+ * Same as MoveSound except this calls UniverseBuilderJS to use the
+ * JavaSoundMixer AudioDevice rather than the HolosketchMixer device.
+ *
+ * NOTE: To run this anywhere but the Solaris Eng Menlo Park network
+ * the URL path must be set to the java3d/javaone directory.
+ */
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import java.io.File;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class ReverberateSound extends Applet {
+
+ // File name of sound sample
+ private static String[] filename = new String[1];
+ private static String path = null;
+ private static int filenamesGiven = 0;
+ private static boolean filenamesSet = false;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the subgraph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create the transform group node and initialize it to the identity.
+ // Enable the TRANSFORM_WRITE capability so that our behavior code
+ // can modify it at runtime. Add it to the root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // Create a simple shape leaf node and add it into the scene graph.
+ objTrans.addChild(new ColorCube(0.4));
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 20000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotation,
+ objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+
+ //
+ // Create an AuralAttribute with reverb params set
+ //
+ Soundscape soundScape2 = new Soundscape();
+ AuralAttributes attributes2 = new AuralAttributes();
+ attributes2.setReverbOrder(6);
+ attributes2.setCapability(AuralAttributes.ALLOW_REVERB_ORDER_WRITE);
+ attributes2.setCapability(AuralAttributes.ALLOW_REVERB_DELAY_WRITE);
+ attributes2.setCapability(AuralAttributes.ALLOW_REFLECTION_COEFFICIENT_WRITE);
+ soundScape2.setApplicationBounds(bounds);
+ soundScape2.setAuralAttributes(attributes2);
+ objRoot.addChild(soundScape2);
+
+ //
+ // Create a sound node and add it to the scene graph
+ //
+ PointSound sound = new PointSound();
+ sound.setCapability(PointSound.ALLOW_ENABLE_WRITE);
+ sound.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE);
+ sound.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE);
+ sound.setCapability(PointSound.ALLOW_DURATION_READ);
+ sound.setCapability(PointSound.ALLOW_POSITION_WRITE);
+ sound.setCapability(PointSound.ALLOW_LOOP_WRITE);
+ sound.setSchedulingBounds(bounds);
+
+ objTrans.addChild(sound);
+ //
+ // Create a new Behavior object that will play the sound
+ //
+ AudioReverberate player = new AudioReverberate(sound, filename[0],
+ attributes2);
+ player.setSchedulingBounds(bounds);
+ objTrans.addChild(player);
+
+
+ return objRoot;
+ }
+
+ public ReverberateSound() {
+ }
+
+ public void init() {
+ if (!filenamesSet) {
+ // path is null if started from applet
+ if (path == null) {
+ // the path for an applet
+ path = getCodeBase().toString();
+ }
+
+ /*
+ * append given file name to given URL path
+ */
+ if (filenamesGiven > 0) {
+ filename[0] = new String(path + "/" + filename[0]);
+ }
+ else {
+ // fill in default file names if all three not given
+ filename[0] = new String(path + "/hello_universe.au");
+ }
+ filenamesSet = true;
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ /*
+ * Create a simple scene and attach it to the virtual universe
+ */
+ u = new SimpleUniverse(c);
+ AudioDevice audioDev = u.getViewer().createAudioDevice();
+ BranchGroup scene = createSceneGraph();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows ReverberateSound to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ if (args.length > 0) {
+ if ( (args[0].startsWith("file"+File.pathSeparator)) ||
+ (args[0].startsWith("http"+File.pathSeparator)) ) {
+ path = args[0];
+ }
+ else {
+ path = "file:" + args[0];
+ }
+ }
+ else {
+ path = "file:.";
+ }
+
+ if (args.length > 1) {
+ filename[0] = args[1];
+ if (filename[0] != null) {
+ filenamesGiven++ ;
+ }
+ }
+
+ new MainFrame(new ReverberateSound(), 256, 256);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/sound/SimpleSounds.java b/src/classes/org/jdesktop/j3d/examples/sound/SimpleSounds.java
new file mode 100644
index 0000000..d7c8c49
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/sound/SimpleSounds.java
@@ -0,0 +1,294 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.sound;
+
+import java.applet.Applet;
+import java.net.URL;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import java.io.File;
+import java.security.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+/*
+ * This Java3D program:
+ * Creates an instance of the JavaSoundMixer AudioDevice, initializing it
+ * and attaching it to the PhysicalEnvironment by using
+ * SimpleUniverse.
+ * Creates one cached Background and two cached Point sound sources.
+ * Creates and executes a custom behavior (SimpleSoundsBehavior) that
+ * starts the sound playing and transforms the PointSound source
+ * by modifying the TransformGroup that contains the Sound nodes.
+ *
+ * Usage:
+ * java SimpleSounds [URLpath [name1 [name2 [name2]]]]
+ *
+ * The first optional command line parameter is the URL path to directory
+ * containing "file:" or "http:" and then directory path string.
+ * If you are using the suppled default sound files in the same directory
+ * as this test program then only the URLpath need be supplied on the
+ * command line.
+ * If this parameter is not included then the current path to the directory
+ * this program is running in is used for an application
+ * and the codebase is used for an applet.
+ * The second thru fourth optional command line parameters are sound file names
+ * If not given, the default file names are:
+ * techno_machine.au
+ * hello_universe.au
+ * roar.au
+ * that correspond to the 3 'voice' quality, 8-bit, u-law, 8-kHz samples
+ * included in the same directory as this test program.
+ *
+ * Java Sound engine has been advertised to support the following 8- and 16-
+ * bit, linear and u-law, mono and stereo sound sample file formats: AU,
+ * AIFF, WAV, and PCM. Non-cached MIDI and RMF files are also supported.
+ * Neither compressed formats (DVI, GSM, MOD) nor A-law formated files are
+ * supported at this time, but they will be converted.
+ */
+
+public class SimpleSounds extends Applet {
+
+ // File name of sound sample
+ private static int filenamesGiven = 0;
+ private static URL[] url = new URL[3];
+ private static String[] filename = new String[3];
+ private static String path = null;
+ private static boolean filenamesSet = false;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the subgraph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create the transform group node and initialize it to the identity.
+ // Enable the TRANSFORM_WRITE capability so that our behavior code
+ // can modify it at runtime. Add it to the root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // Create a simple shape leaf node and add it into the scene graph.
+ objTrans.addChild(new ColorCube(0.4));
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 20000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotation,
+ objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+ /*
+ * Create a sound node and add it to the scene graph
+ */
+ BackgroundSound sound1 = new BackgroundSound();
+ PointSound sound2 = new PointSound();
+ PointSound sound3 = new PointSound();
+ sound1.setCapability(PointSound.ALLOW_ENABLE_WRITE);
+ sound1.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE);
+ sound1.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE);
+ sound1.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE);
+ sound1.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE);
+ sound1.setCapability(PointSound.ALLOW_RELEASE_WRITE);
+ sound1.setCapability(PointSound.ALLOW_DURATION_READ);
+ sound1.setCapability(PointSound.ALLOW_IS_PLAYING_READ);
+ sound1.setCapability(PointSound.ALLOW_LOOP_WRITE);
+ sound2.setCapability(PointSound.ALLOW_ENABLE_WRITE);
+ sound2.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE);
+ sound2.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE);
+ sound2.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE);
+ sound2.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE);
+ sound2.setCapability(PointSound.ALLOW_RELEASE_WRITE);
+ sound2.setCapability(PointSound.ALLOW_DURATION_READ);
+ sound2.setCapability(PointSound.ALLOW_IS_PLAYING_READ);
+ sound2.setCapability(PointSound.ALLOW_POSITION_WRITE);
+ sound2.setCapability(PointSound.ALLOW_LOOP_WRITE);
+ sound3.setCapability(PointSound.ALLOW_ENABLE_WRITE);
+ sound3.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE);
+ sound3.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE);
+ sound3.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE);
+ sound3.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE);
+ sound3.setCapability(PointSound.ALLOW_RELEASE_WRITE);
+ sound3.setCapability(PointSound.ALLOW_DURATION_READ);
+ sound3.setCapability(PointSound.ALLOW_IS_PLAYING_READ);
+ sound3.setCapability(PointSound.ALLOW_POSITION_WRITE);
+
+ BoundingSphere soundBounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ sound1.setSchedulingBounds(soundBounds);
+ sound2.setSchedulingBounds(soundBounds);
+ sound3.setSchedulingBounds(soundBounds);
+ objTrans.addChild(sound1);
+ objTrans.addChild(sound2);
+ objTrans.addChild(sound3);
+
+
+ /*
+ * Create a new Behavior object that will play the sound
+ */
+ SimpleSoundsBehavior player = new SimpleSoundsBehavior(
+ sound1, sound2, sound3,
+ url[0], url[1], url[2], soundBounds);
+ player.setSchedulingBounds(soundBounds);
+ objTrans.addChild(player);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public SimpleSounds() {
+ }
+
+ public void init() {
+ if (!filenamesSet) {
+ // path is null if started from appletviewer/browser
+ if (path == null) {
+ // the path for an applet
+ path = getCodeBase().toString();
+ }
+ int j;
+ /*
+ * append given file name to given URL path
+ */
+ for (j=0; j<filenamesGiven; j++)
+ filename[j] = new String(path + "/" + filename[j]);
+ /*
+ * fill in default file names if all three not given
+ */
+ for (int i=j; i<3; i++) {
+ if (i == 0)
+ filename[0] = new String(path + "/techno_machine.au");
+ if (i == 1)
+ filename[1] = new String(path + "/hello_universe.au");
+ if (i == 2)
+ filename[2] = new String(path + "/roar.au");
+ }
+ filenamesSet = true;
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ /*
+ * Change filenames into URLs
+ */
+ for (int i=0; i<3; i++) {
+ try {
+ url[i] = new URL(filename[i]);
+ }
+ catch (Exception e) {
+ System.out.println(e.getMessage());
+ return;
+ }
+ }
+
+ /*
+ * Create a simple scene and attach it to the virtual universe
+ */
+ u = new SimpleUniverse(c);
+ AudioDevice audioDev = u.getViewer().createAudioDevice();
+ BranchGroup scene = createSceneGraph();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ /*
+ * The following allows SimpleSounds to be run as an application
+ * as well as an applet
+ */
+ public static void main(String[] args) {
+ if (args.length > 0) {
+ if ( (args[0].startsWith("file"+File.pathSeparator)) ||
+ (args[0].startsWith("http"+File.pathSeparator)) ) {
+ path = args[0];
+ }
+ else {
+ path = "file:" + args[0];
+ }
+ }
+ else {
+ path = "file:.";
+ }
+
+ for (int i=0; i<3; i++) {
+ if (args.length > (i+1)) {
+ filename[i] = args[i+1];
+ if (filename[i] != null) {
+ filenamesGiven++ ;
+ }
+ }
+ else
+ break;
+ }
+ new MainFrame(new SimpleSounds(), args, 256, 256);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java b/src/classes/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java
new file mode 100644
index 0000000..862881f
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java
@@ -0,0 +1,179 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.sound;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.net.URL;
+import java.util.Enumeration;
+
+// User defined audio behavior class
+public class SimpleSoundsBehavior extends Behavior {
+ WakeupOnElapsedTime wt;
+ WakeupOnBehaviorPost wp;
+ BackgroundSound sound1 = new BackgroundSound();
+ PointSound sound2 = new PointSound();
+ PointSound sound3 = new PointSound();
+ static int WAKEUP_SOUND = 0;
+ int soundIndex = 0;
+ URL URLName1;
+ URL URLName2;
+ URL URLName3;
+ BoundingSphere bounds;
+
+ // Override Behavior's initialize method to setup wakeup criteria
+ public void initialize() {
+ MediaContainer sample1 = new MediaContainer();
+ MediaContainer sample2 = new MediaContainer();
+ MediaContainer sample3 = new MediaContainer();
+ sample1.setCapability(MediaContainer.ALLOW_URL_WRITE);
+ sample1.setCapability(MediaContainer.ALLOW_URL_READ);
+ sample1.setURLObject(URLName1);
+ //sample1.setCacheEnable(false);
+ sound1.setLoop(0);
+ sound1.setContinuousEnable(false);
+ sound1.setReleaseEnable(false);
+ sound1.setSoundData(sample1);
+ sound1.setInitialGain(0.7f);
+ sample2.setCapability(MediaContainer.ALLOW_URL_WRITE);
+ sample2.setCapability(MediaContainer.ALLOW_URL_READ);
+ sample2.setURLObject(URLName2);
+ sound2.setLoop(Sound.INFINITE_LOOPS);
+ sound2.setContinuousEnable(false);
+ sound2.setReleaseEnable(false);
+ sound2.setSoundData(sample2);
+ sound2.setInitialGain(2.0f);
+ Point3f sound2Pos = new Point3f(-30.0f, 0.0f, 0.0f);
+ sound2.setPosition(sound2Pos);
+ sample3.setCapability(MediaContainer.ALLOW_URL_WRITE);
+ sample3.setCapability(MediaContainer.ALLOW_URL_READ);
+ sample3.setURLObject(URLName3);
+ sound3.setContinuousEnable(false);
+ sound3.setReleaseEnable(false);
+ sound3.setSoundData(sample3);
+ sound3.setInitialGain(4.0f);
+ Point3f sound3Pos = new Point3f(30.0f, 0.0f, 0.0f);
+ sound3.setPosition(sound3Pos);
+
+ wt = new WakeupOnElapsedTime(2000);
+ WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000);
+ wakeupOn(wp);
+ }
+
+ // Override Behavior's stimulus method to handle the event
+ public void processStimulus(Enumeration criteria) {
+
+ switch (soundIndex)
+ {
+ // Active
+ case 0:
+ // System.out.println("****Enable First Sound");
+ sound1.setEnable(true);
+ wakeupOn(wt);
+ break;
+ case 1:
+ // System.out.println("********Enable Second Sound");
+ sound2.setEnable(true);
+ wakeupOn(wt);
+ break;
+ case 2:
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ // System.out.println("************Enable Third Sound");
+ sound3.setEnable(true);
+ wakeupOn(wt);
+ break;
+ case 3:
+ case 5:
+ case 7:
+ case 9:
+ // System.out.println("************Disable Third Sound");
+ sound3.setEnable(false);
+ wakeupOn(wt);
+ break;
+
+ case 11:
+ // System.out.println("********Disable Second Sound");
+ sound2.setEnable(false) ;
+ wakeupOn(wt);
+ break;
+ case 12:
+ // System.out.println("****Disable First Sound");
+ sound1.setEnable(false) ;
+ System.out.println("SimpleSounds: test complete");
+ wt = new WakeupOnElapsedTime(400000);
+ wakeupOn(wt);
+ break;
+
+ default:
+ break;
+ }
+ soundIndex++;
+ }
+
+ //
+ // Constructor for rotation behavior.
+ // Parameters: sound node
+ // sample file name
+ // sound node's bounds
+ //
+ public SimpleSoundsBehavior(BackgroundSound sound1,
+ PointSound sound2,
+ PointSound sound3,
+ URL urlName1,
+ URL urlName2,
+ URL urlName3,
+ BoundingSphere soundBounds) {
+ this.sound1 = sound1;
+ this.sound2 = sound2;
+ this.sound3 = sound3;
+ this.URLName1 = urlName1;
+ this.URLName2 = urlName2;
+ this.URLName3 = urlName3;
+ this.bounds = (BoundingSphere)soundBounds.clone();
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java b/src/classes/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java
new file mode 100644
index 0000000..49b3293
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java
@@ -0,0 +1,303 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.sphere_motion;
+
+import java.applet.Applet;
+import java.awt.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.Sphere;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.util.Enumeration;
+
+public class SphereMotion extends Applet {
+
+ // Constants for type of light to use
+ private static final int DIRECTIONAL_LIGHT = 0;
+ private static final int POINT_LIGHT = 1;
+ private static final int SPOT_LIGHT = 2;
+
+ // Flag indicates type of lights: directional, point, or spot
+ // lights. This flag is set based on command line argument
+ private static int lightType = POINT_LIGHT;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(SimpleUniverse u) {
+ Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f);
+ Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f);
+ Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
+
+ Transform3D t;
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create a bounds for the background and lights
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Set up the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ objScale.addChild(bg);
+
+ // Create a Sphere object, generate one copy of the sphere,
+ // and add it into the scene graph.
+ Material m = new Material(objColor, eColor, objColor, sColor, 100.0f);
+ Appearance a = new Appearance();
+ m.setLightingEnable(true);
+ a.setMaterial(m);
+ Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS, 80, a);
+ objScale.addChild(sph);
+
+ // Create the transform group node for the each light and initialize
+ // it to the identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add them to the root
+ // of the subgraph.
+ TransformGroup l1RotTrans = new TransformGroup();
+ l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(l1RotTrans);
+
+ TransformGroup l2RotTrans = new TransformGroup();
+ l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objScale.addChild(l2RotTrans);
+
+ // Create transformations for the positional lights
+ t = new Transform3D();
+ Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0);
+ t.set(lPos1);
+ TransformGroup l1Trans = new TransformGroup(t);
+ l1RotTrans.addChild(l1Trans);
+
+ t = new Transform3D();
+ Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0);
+ t.set(lPos2);
+ TransformGroup l2Trans = new TransformGroup(t);
+ l2RotTrans.addChild(l2Trans);
+
+ // Create Geometry for point lights
+ ColoringAttributes caL1 = new ColoringAttributes();
+ ColoringAttributes caL2 = new ColoringAttributes();
+ caL1.setColor(lColor1);
+ caL2.setColor(lColor2);
+ Appearance appL1 = new Appearance();
+ Appearance appL2 = new Appearance();
+ appL1.setColoringAttributes(caL1);
+ appL2.setColoringAttributes(caL2);
+ l1Trans.addChild(new Sphere(0.05f, appL1));
+ l2Trans.addChild(new Sphere(0.05f, appL2));
+
+ // Create lights
+ AmbientLight aLgt = new AmbientLight(alColor);
+
+ Light lgt1 = null;
+ Light lgt2 = null;
+
+ Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f atten = new Point3f(1.0f, 0.0f, 0.0f);
+ Vector3f lDirect1 = new Vector3f(lPos1);
+ Vector3f lDirect2 = new Vector3f(lPos2);
+ lDirect1.negate();
+ lDirect2.negate();
+
+ switch (lightType) {
+ case DIRECTIONAL_LIGHT:
+ lgt1 = new DirectionalLight(lColor1, lDirect1);
+ lgt2 = new DirectionalLight(lColor2, lDirect2);
+ break;
+ case POINT_LIGHT:
+ lgt1 = new PointLight(lColor1, lPoint, atten);
+ lgt2 = new PointLight(lColor2, lPoint, atten);
+ break;
+ case SPOT_LIGHT:
+ lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1,
+ 25.0f * (float)Math.PI / 180.0f, 10.0f);
+ lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2,
+ 25.0f * (float)Math.PI / 180.0f, 10.0f);
+ break;
+ }
+
+ // Set the influencing bounds
+ aLgt.setInfluencingBounds(bounds);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+
+ // Add the lights into the scene graph
+ objScale.addChild(aLgt);
+ l1Trans.addChild(lgt1);
+ l2Trans.addChild(lgt2);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator1 =
+ new RotationInterpolator(rotor1Alpha,
+ l1RotTrans,
+ yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator1.setSchedulingBounds(bounds);
+ l1RotTrans.addChild(rotator1);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into the
+ // scene graph.
+ Alpha rotor2Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 1000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator2 =
+ new RotationInterpolator(rotor2Alpha,
+ l2RotTrans,
+ yAxis,
+ 0.0f, 0.0f);
+ bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator2.setSchedulingBounds(bounds);
+ l2RotTrans.addChild(rotator2);
+
+ // Create a position interpolator and attach it to the view
+ // platform
+ TransformGroup vpTrans =
+ u.getViewingPlatform().getViewPlatformTransform();
+ Transform3D axisOfTranslation = new Transform3D();
+ Alpha transAlpha = new Alpha(-1,
+ Alpha.INCREASING_ENABLE |
+ Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 5000, 0, 0,
+ 5000, 0, 0);
+ axisOfTranslation.rotY(-Math.PI/2.0);
+ PositionInterpolator translator =
+ new PositionInterpolator(transAlpha,
+ vpTrans,
+ axisOfTranslation,
+ 2.0f, 3.5f);
+ translator.setSchedulingBounds(bounds);
+ objScale.addChild(translator);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public SphereMotion() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ u = new SimpleUniverse(c);
+ BranchGroup scene = createSceneGraph(u);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows SphereMotion to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ // Parse the Input Arguments
+ String usage = "Usage: java SphereMotion [-point | -spot | -dir]";
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].equals("-point")) {
+ System.out.println("Using point lights");
+ lightType = POINT_LIGHT;
+ }
+ else if (args[i].equals("-spot")) {
+ System.out.println("Using spot lights");
+ lightType = SPOT_LIGHT;
+ }
+ else if (args[i].equals("-dir")) {
+ System.out.println("Using directional lights");
+ lightType = DIRECTIONAL_LIGHT;
+ }
+ else {
+ System.out.println(usage);
+ System.exit(0);
+ }
+ }
+ else {
+ System.out.println(usage);
+ System.exit(0);
+ }
+ }
+
+ new MainFrame(new SphereMotion(), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java b/src/classes/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java
new file mode 100644
index 0000000..1e5c965
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java
@@ -0,0 +1,603 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.spline_anim;
+
+import java.io.*;
+import java.applet.Applet;
+import java.awt.FlowLayout;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Hashtable;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.*;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.loaders.Scene;
+import com.sun.j3d.loaders.objectfile.ObjectFile;
+import com.sun.j3d.loaders.ParsingErrorException;
+import com.sun.j3d.loaders.IncorrectFormatException;
+import com.sun.j3d.utils.behaviors.vp.*;
+import com.sun.j3d.utils.behaviors.interpolators.*;
+
+
+
+/*
+ * This program demonstrates the use of KBRotPosScaleSplinePathInterpolator
+ * in order to to do spline animation paths using Kochanek-Bartels (also
+ * known as TCB or Tension-Continuity-Bias ) splines. A cone red cone
+ * is animated along a spline path specified by 5 knot points, which
+ * are showns as cyan spheres.
+ *
+ * Use the left mouse button to changes orientation of scene.
+ * Use the middle mouse button to zoom in/out
+ * Use the right mouse button to pan the scene
+ */
+public class SplineAnim extends Applet implements ActionListener,
+ AdjustmentListener,
+ ItemListener {
+
+ // 3D Canvas
+ Canvas3D canvas;
+
+ // UI Components
+ Panel controlPanel;
+ Panel canvasPanel;
+ Button animateButton;
+ Choice interpChoice;
+ Scrollbar speedSlider;
+ Label speedLabel;
+ Label interpLabel;
+
+ // Scene Graph
+ BoundingSphere bounds;
+ BranchGroup root;
+ BranchGroup behaviorBranch;
+ Transform3D sceneTransform;
+ TransformGroup sceneTransformGroup;
+ Transform3D objTransform;
+ TransformGroup objTransformGroup;
+ Transform3D lightTransform1;
+ Transform3D lightTransform2;
+ TransformGroup light1TransformGroup;
+ TransformGroup light2TransformGroup;
+
+ // Key Frames & Interpolator
+ int duration = 5000;
+ Alpha animAlpha;
+ Transform3D yAxis;
+ KBKeyFrame[] linearKeyFrames = new KBKeyFrame[6];
+ KBKeyFrame[] splineKeyFrames = new KBKeyFrame[6];
+ KBRotPosScaleSplinePathInterpolator splineInterpolator;
+ KBRotPosScaleSplinePathInterpolator linearInterpolator;
+
+ // Data: Knot positions & transform groups
+ Vector3f pos0 = new Vector3f(-5.0f, -5.0f, 0.0f);
+ Vector3f pos1 = new Vector3f(-5.0f, 5.0f, 0.0f);
+ Vector3f pos2 = new Vector3f( 0.0f, 5.0f, 0.0f);
+ Vector3f pos3 = new Vector3f( 0.0f, -5.0f, 0.0f);
+ Vector3f pos4 = new Vector3f( 5.0f, -5.0f, 0.0f);
+ Vector3f pos5 = new Vector3f( 5.0f, 5.0f, 0.0f);
+ TransformGroup k0TransformGroup;
+ TransformGroup k1TransformGroup;
+ TransformGroup k2TransformGroup;
+ TransformGroup k3TransformGroup;
+ TransformGroup k4TransformGroup;
+ TransformGroup k5TransformGroup;
+
+ // Flags
+ boolean animationOn = true;
+ boolean linear = false;
+
+ private SimpleUniverse u = null;
+
+ public SplineAnim() {
+ }
+
+ public void init() {
+ this.setLayout(new FlowLayout());
+
+ // Create the canvas and the UI
+ canvasPanel = new Panel();
+ controlPanel = new Panel();
+ createCanvasPanel(canvasPanel);
+ this.add(canvasPanel);
+ createControlPanel(controlPanel);
+ this.add(controlPanel);
+
+ // Create the scene.
+ BranchGroup scene = createSceneGraph();
+
+ // Setup keyframe data for our animation
+ setupSplineKeyFrames ();
+ setupLinearKeyFrames ();
+
+ // Setup alpha, create the interpolators and start them. We
+ // create both a linear and a spline interpolator and turn on
+ // one depending on user selection. The default is spline.
+ setupAnimationData ();
+ createInterpolators();
+ startInterpolator();
+
+ // Add viewing platform
+ u = new SimpleUniverse(canvas);
+
+ // add mouse behaviors to ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ viewingPlatform.setNominalViewingTransform();
+
+ // add orbit behavior to the ViewingPlatform
+ OrbitBehavior orbit = new OrbitBehavior(canvas,
+ OrbitBehavior.REVERSE_ALL);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ /*
+ * This creates the control panel which contains a choice menu to
+ * toggle between spline and linear interpolation, a slider to
+ * adjust the speed of the animation and a animation start/stop
+ * button.
+ */
+ private void createControlPanel(Panel p) {
+
+ GridBagLayout gl = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ p.setLayout (gl);
+ gbc.weightx = 100; gbc.weighty = 100;
+ gbc.fill = GridBagConstraints.BOTH;
+
+ gbc.gridx = 0; gbc.gridy = 0;
+ gbc.gridwidth = 1; gbc.gridheight = 1;
+ interpLabel = new Label("Interpolation Type", Label.LEFT);
+ p.add(interpLabel, gbc);
+
+ gbc.gridx = 1; gbc.gridy = 0;
+ gbc.gridwidth = 1; gbc.gridheight = 1;
+ interpChoice = new Choice();
+ interpChoice.add("Spline");
+ interpChoice.add("Linear");
+ p.add(interpChoice, gbc);
+ interpChoice.addItemListener (this);
+
+ gbc.gridx = 0; gbc.gridy = 2;
+ gbc.gridwidth = 2; gbc.gridheight = 1;
+ speedSlider = new Scrollbar(Scrollbar.HORIZONTAL, 2, 1, 0, 11);
+ speedSlider.setUnitIncrement (1);
+ p.add(speedSlider, gbc);
+ speedSlider.addAdjustmentListener(this);
+
+ gbc.gridx = 0; gbc.gridy = 3;
+ gbc.gridwidth = 2; gbc.gridheight = 1;
+ speedLabel = new Label(" - Animation Speed +", Label.CENTER);
+ p.add(speedLabel, gbc);
+
+ gbc.gridx = 0; gbc.gridy = 5;
+ gbc.gridwidth = 2; gbc.gridheight = 1;
+ animateButton = new Button("Stop Animation");
+ p.add(animateButton, gbc);
+ animateButton.addActionListener (this);
+
+
+ }
+
+ /*
+ * This creates the Java3D canvas
+ */
+ private void createCanvasPanel(Panel p) {
+
+ GridBagLayout gl = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ p.setLayout(gl);
+ gbc.gridx = 0; gbc.gridy = 0;
+ gbc.gridwidth = 5; gbc.gridheight = 5;
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ canvas = new Canvas3D(config);
+ canvas.setSize(490,490);
+ p.add(canvas,gbc);
+
+ }
+
+ /*
+ * This creates the scene with 5 knot points represented by cyan
+ * spheres, a cone obejct that will be transformed, and two directional
+ * lights + and ambient light.
+ */
+ public BranchGroup createSceneGraph() {
+
+ // Colors for lights and objects
+ Color3f aColor = new Color3f(0.2f, 0.2f, 0.2f);
+ Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f);
+ Color3f coneColor = new Color3f(0.9f, 0.1f, 0.1f);
+ Color3f sphereColor= new Color3f(0.1f, 0.7f, 0.9f);
+ Color3f bgColor = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f lightColor = new Color3f(1.0f, 1.0f, 1.0f);
+
+ // Root of the branch grsph
+ BranchGroup root = new BranchGroup();
+
+ // Create transforms such that all objects appears in the scene
+ sceneTransform = new Transform3D();
+ sceneTransform.setScale(0.14f);
+ Transform3D yrot = new Transform3D();
+ yrot.rotY(-Math.PI/5.0d);
+ sceneTransform.mul(yrot);
+ sceneTransformGroup = new TransformGroup(sceneTransform);
+ sceneTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ sceneTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ root.addChild(sceneTransformGroup);
+
+ // Create bounds for the background and lights
+ bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0f);
+
+ // Set up the background
+ Background bg = new Background(bgColor);
+ bg.setApplicationBounds(bounds);
+ sceneTransformGroup.addChild(bg);
+
+ // Create the transform group node for the lights
+ lightTransform1 = new Transform3D();
+ lightTransform2 = new Transform3D();
+ Vector3d lightPos1 = new Vector3d(0.0, 0.0, 2.0);
+ Vector3d lightPos2 = new Vector3d(1.0, 0.0, -2.0);
+ lightTransform1.set(lightPos1);
+ lightTransform2.set(lightPos2);
+ light1TransformGroup = new TransformGroup(lightTransform1);
+ light2TransformGroup = new TransformGroup(lightTransform2);
+ sceneTransformGroup.addChild(light1TransformGroup);
+ sceneTransformGroup.addChild(light2TransformGroup);
+
+ // Create lights
+ AmbientLight ambLight = new AmbientLight(aColor);
+ Light dirLight1;
+ Light dirLight2;
+
+ Vector3f lightDir1 = new Vector3f(lightPos1);
+ Vector3f lightDir2 = new Vector3f(lightPos2);
+ lightDir1.negate();
+ lightDir2.negate();
+ dirLight1 = new DirectionalLight(lightColor, lightDir1);
+ dirLight2 = new DirectionalLight(lightColor, lightDir2);
+
+ // Set the influencing bounds
+ ambLight.setInfluencingBounds(bounds);
+ dirLight1.setInfluencingBounds(bounds);
+ dirLight2.setInfluencingBounds(bounds);
+
+ // Add the lights into the scene graph
+ sceneTransformGroup.addChild(ambLight);
+ sceneTransformGroup.addChild(dirLight1);
+ sceneTransformGroup.addChild(dirLight2);
+
+ // Create a cone and add it to the scene graph.
+ objTransform = new Transform3D();
+ objTransformGroup = new TransformGroup(objTransform);
+ objTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ sceneTransformGroup.addChild(objTransformGroup);
+
+ Material m = new Material(coneColor, eColor, coneColor, sColor, 100.0f);
+ Appearance a = new Appearance();
+ m.setLightingEnable(true);
+ a.setMaterial(m);
+ Cone cone = new Cone(0.4f, 1.0f);
+ cone.setAppearance(a);
+ objTransformGroup.addChild(cone);
+
+ // Create transform groups for each knot point
+ // knot point 0
+ Transform3D t3dKnot = new Transform3D();
+ t3dKnot.set (pos0);
+ TransformGroup k0TransformGroup = new TransformGroup(t3dKnot);
+ sceneTransformGroup.addChild(k0TransformGroup);
+
+ // knot point 1
+ t3dKnot = new Transform3D();
+ t3dKnot.set (pos1);
+ TransformGroup k1TransformGroup = new TransformGroup(t3dKnot);
+ sceneTransformGroup.addChild(k1TransformGroup);
+
+ // knot point 2
+ t3dKnot = new Transform3D();
+ t3dKnot.set (pos2);
+ TransformGroup k2TransformGroup = new TransformGroup(t3dKnot);
+ sceneTransformGroup.addChild(k2TransformGroup);
+
+ // knot point 3
+ t3dKnot = new Transform3D();
+ t3dKnot.set (pos3);
+ TransformGroup k3TransformGroup = new TransformGroup(t3dKnot);
+ sceneTransformGroup.addChild(k3TransformGroup);
+
+ // knot point 4
+ t3dKnot = new Transform3D();
+ t3dKnot.set (pos4);
+ TransformGroup k4TransformGroup = new TransformGroup(t3dKnot);
+ sceneTransformGroup.addChild(k4TransformGroup);
+
+ // knot point 5
+ t3dKnot = new Transform3D();
+ t3dKnot.set (pos5);
+ TransformGroup k5TransformGroup = new TransformGroup(t3dKnot);
+ sceneTransformGroup.addChild(k5TransformGroup);
+
+ // Create spheres for each knot point's transform group
+ ColoringAttributes sphereColorAttr = new ColoringAttributes();
+ sphereColorAttr.setColor(sphereColor);
+ Appearance sphereAppearance = new Appearance();
+ sphereAppearance.setColoringAttributes(sphereColorAttr);
+ k0TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
+ k1TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
+ k2TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
+ k3TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
+ k4TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
+ k5TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
+
+ return root;
+ }
+
+ /*
+ * This sets up the key frame data for the spline interpolator. Each knot
+ * point has a scale and rotation component specified. The second argument
+ * to KBKeyFrame (in this case 0) tells the interpolator that this is
+ * to be interpolated using splines. The last three arguments to
+ * KBKeyFrame are Tension, Continuity, and Bias components for each
+ * key frame.
+ */
+ private void setupSplineKeyFrames () {
+ // Prepare spline keyframe data
+ Point3f p = new Point3f (pos0); // position
+ float head = (float)Math.PI/2.0f; // heading
+ float pitch = 0.0f; // pitch
+ float bank = 0.0f; // bank
+ Point3f s = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale
+ splineKeyFrames[0] =
+ new KBKeyFrame(0.0f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos1);
+ head = 0.0f; // heading
+ pitch = 0.0f; // pitch
+ bank = (float)-Math.PI/2.0f; // bank
+ s = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale
+ splineKeyFrames[1] =
+ new KBKeyFrame(0.2f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos2);
+ head = 0.0f; // heading
+ pitch = 0.0f; // pitch
+ bank = 0.0f; // bank
+ s = new Point3f(0.7f, 0.7f, 0.7f); // uniform scale
+ splineKeyFrames[2] =
+ new KBKeyFrame(0.4f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos3);
+ head = (float)Math.PI/2.0f; // heading
+ pitch = 0.0f; // pitch
+ bank = (float)Math.PI/2.0f; // bank
+ s = new Point3f(0.5f, 0.5f, 0.5f); // uniform scale
+ splineKeyFrames[3] =
+ new KBKeyFrame(0.6f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos4);
+ head = (float)-Math.PI/2.0f; // heading
+ pitch = (float)-Math.PI/2.0f; // pitch
+ bank = (float)Math.PI/2.0f; // bank
+ s = new Point3f(0.4f, 0.4f, 0.4f); // uniform scale
+ splineKeyFrames[4] =
+ new KBKeyFrame(0.8f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos5);
+ head = 0.0f; // heading
+ pitch = 0.0f; // pitch
+ bank = 0.0f; // bank
+ s = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale
+ splineKeyFrames[5] =
+ new KBKeyFrame(1.0f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+ }
+
+ /*
+ * This sets up the key frame data for the linear interpolator. Each knot
+ * point has a scale and rotation component specified. The second argument
+ * to KBKeyFrame (in this case 1) tells the interpolator that this is
+ * to be interpolated linearly. The last three arguments to TCBKeyFrame
+ * are Tension, Continuity, and Bias components for each key frame.
+ */
+ private void setupLinearKeyFrames () {
+ // Prepare linear keyframe data
+ Point3f p = new Point3f (pos0);
+ float head = 0.0f; // heading
+ float pitch = 0.0f; // pitch
+ float bank = 0.0f; // bank
+ Point3f s = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale
+ linearKeyFrames[0] =
+ new KBKeyFrame(0.0f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos1);
+ linearKeyFrames[1] =
+ new KBKeyFrame(0.2f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos2);
+ linearKeyFrames[2] =
+ new KBKeyFrame(0.4f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos3);
+ linearKeyFrames[3] =
+ new KBKeyFrame(0.6f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos4);
+ linearKeyFrames[4] =
+ new KBKeyFrame(0.8f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+
+ p = new Point3f (pos5);
+ linearKeyFrames[5] =
+ new KBKeyFrame(1.0f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f);
+ }
+
+
+ /*
+ * This sets up alpha for the interpolator
+ */
+ private void setupAnimationData () {
+ yAxis = new Transform3D();
+ animAlpha = new Alpha (-1,Alpha.INCREASING_ENABLE,0,0,duration,0,0,0,0,0);
+ }
+
+ /*
+ * create a spline and a linear interpolator, but we will activate only
+ * one in startInterpolator()
+ */
+ private void createInterpolators () {
+
+ behaviorBranch = new BranchGroup();
+
+ // create spline interpolator
+ splineInterpolator =
+ new KBRotPosScaleSplinePathInterpolator(animAlpha, objTransformGroup,
+ yAxis, splineKeyFrames);
+ splineInterpolator.setSchedulingBounds(bounds);
+ behaviorBranch.addChild(splineInterpolator);
+
+ // create linear interpolator
+ linearInterpolator =
+ new KBRotPosScaleSplinePathInterpolator(animAlpha, objTransformGroup,
+ yAxis, linearKeyFrames);
+ linearInterpolator.setSchedulingBounds(bounds);
+ behaviorBranch.addChild(linearInterpolator);
+ objTransformGroup.addChild(behaviorBranch);
+
+ }
+
+ /*
+ * This activates one of the interpolators depending on the state of the
+ * linear boolean flag which may be toggled by the user using the choice
+ * menu.
+ */
+ public void startInterpolator () {
+ if (animationOn) {
+ if (linear) {
+ splineInterpolator.setEnable(false);
+ linearInterpolator.setEnable(true);
+ } else {
+ linearInterpolator.setEnable(false);
+ splineInterpolator.setEnable(true);
+ }
+ }
+ }
+
+
+ /*
+ * Toggle animation
+ */
+ public void actionPerformed (ActionEvent event) {
+ Object source = event.getSource();
+ if (source == animateButton) {
+ try {
+ // toggle animation
+ if (animationOn) {
+ animationOn = false;
+ splineInterpolator.setEnable(false);
+ linearInterpolator.setEnable(false);
+ animateButton.setLabel("Start Animation");
+ } else {
+ animationOn = true;
+ startInterpolator();
+ animateButton.setLabel("Stop Animation");
+ }
+ } catch (Exception e) {
+ System.err.println ("Exception " + e);
+ }
+ }
+ }
+
+ /*
+ * Toggle the interpolators
+ */
+ public void itemStateChanged (ItemEvent event) {
+ Object source = event.getSource();
+ ItemSelectable ie = event.getItemSelectable();
+ if (source == interpChoice) {
+ try {
+ if (ie.getSelectedObjects()[0] == "Spline") {
+ linear = false;
+ }
+ if (ie.getSelectedObjects()[0] == "Linear") {
+ linear = true;
+ }
+ startInterpolator();
+ } catch (Exception e) {
+ System.err.println ("Exception " + e);
+ }
+ }
+ }
+
+
+ /*
+ * Adjust the speed of the animations
+ */
+ public void adjustmentValueChanged (AdjustmentEvent e) {
+ int value = e.getValue();
+ duration = 6000 - (500 * value);
+ animAlpha.setIncreasingAlphaDuration(duration);
+ }
+
+
+
+ public static void main(String[] args) {
+ Frame frame = new MainFrame(new SplineAnim(), 500, 600);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form b/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form
new file mode 100644
index 0000000..591580c
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+ <NonVisualComponents>
+ <Menu class="javax.swing.JMenuBar" name="jMenuBar1">
+ <SubComponents>
+ <Menu class="javax.swing.JMenu" name="fileMenu">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="File"/>
+ </Properties>
+ <SubComponents>
+ <MenuItem class="javax.swing.JMenuItem" name="exitMenuItem">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Exit"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exitMenuItemActionPerformed"/>
+ </Events>
+ </MenuItem>
+ </SubComponents>
+ </Menu>
+ </SubComponents>
+ </Menu>
+ </NonVisualComponents>
+ <Properties>
+ <Property name="defaultCloseOperation" type="int" value="3"/>
+ <Property name="title" type="java.lang.String" value="Swing Interaction Test"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="menuBar" type="java.lang.String" value="jMenuBar1"/>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="guiPanel">
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="North"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JButton" name="rotateButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Rotate"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rotateButtonActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="4" insetsRight="4" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ </SubComponents>
+ </Container>
+ <Container class="javax.swing.JPanel" name="drawingPanel">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[500, 500]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
+ <BorderConstraints direction="Center"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java b/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java
new file mode 100644
index 0000000..cde026b
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java
@@ -0,0 +1,252 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.swing_interaction;
+
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.geometry.ColorCube;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.GraphicsConfiguration;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+import java.util.Enumeration;
+import javax.swing.JPopupMenu;
+
+/**
+ * Simple Java 3D test program created in NetBeans to illustrate interacting
+ * with a Java 3D scene graph from an Swing-based program.
+ */
+public class SwingInteraction extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ private TransformGroup objTrans;
+ private RotateBehavior awtBehavior;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // Create a simple shape leaf node, add it to the scene graph.
+ objTrans.addChild(new ColorCube(0.4));
+
+ // create the RotateBehavior
+ awtBehavior = new RotateBehavior(objTrans);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
+ 100.0);
+ awtBehavior.setSchedulingBounds(bounds);
+ objRoot.addChild(awtBehavior);
+
+ return objRoot;
+ }
+
+ private Canvas3D createUniverse() {
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ univ = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ univ.getViewingPlatform().setNominalViewingTransform();
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return c;
+ }
+
+ /**
+ * Creates new form SwingInteraction
+ */
+ public SwingInteraction() {
+ // Initialize the GUI components
+ JPopupMenu.setDefaultLightWeightPopupEnabled(false);
+ initComponents();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ Canvas3D c = createUniverse();
+ drawingPanel.add(c, java.awt.BorderLayout.CENTER);
+
+ // Create the content branch and add it to the universe
+ scene = createSceneGraph();
+ univ.addBranchGraph(scene);
+ }
+
+ /**
+ * Behavior class that waits for a behavior post from the AWT event handler
+ */
+ class RotateBehavior extends Behavior {
+
+ private TransformGroup transformGroup;
+ private Transform3D trans = new Transform3D();
+ private WakeupCriterion criterion;
+ private float angle = 0.0f;
+
+ private final int ROTATE = 1;
+
+ // create a new RotateBehavior
+ RotateBehavior(TransformGroup tg) {
+ transformGroup = tg;
+ }
+
+ // initialize behavior to wakeup on a behavior post with id = ROTATE
+ public void initialize() {
+ criterion = new WakeupOnBehaviorPost(this, ROTATE);
+ wakeupOn(criterion);
+ }
+
+ // processStimulus to rotate the cube
+ public void processStimulus(Enumeration criteria) {
+ angle += Math.toRadians(10.0);
+ trans.rotY(angle);
+ transformGroup.setTransform(trans);
+ wakeupOn(criterion);
+ }
+
+ // when the mouse is clicked, postId for the behavior
+ void rotate() {
+ postId(ROTATE);
+ }
+ }
+
+ // ----------------------------------------------------------------
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ guiPanel = new javax.swing.JPanel();
+ rotateButton = new javax.swing.JButton();
+ drawingPanel = new javax.swing.JPanel();
+ jMenuBar1 = new javax.swing.JMenuBar();
+ fileMenu = new javax.swing.JMenu();
+ exitMenuItem = new javax.swing.JMenuItem();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("Swing Interaction Test");
+ guiPanel.setLayout(new java.awt.GridBagLayout());
+
+ rotateButton.setText("Rotate");
+ rotateButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ rotateButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
+ guiPanel.add(rotateButton, gridBagConstraints);
+
+ getContentPane().add(guiPanel, java.awt.BorderLayout.NORTH);
+
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(500, 500));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ fileMenu.setText("File");
+ exitMenuItem.setText("Exit");
+ exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ exitMenuItemActionPerformed(evt);
+ }
+ });
+
+ fileMenu.add(exitMenuItem);
+
+ jMenuBar1.add(fileMenu);
+
+ setJMenuBar(jMenuBar1);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void rotateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rotateButtonActionPerformed
+ awtBehavior.rotate();
+ }//GEN-LAST:event_rotateButtonActionPerformed
+
+ private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
+ System.exit(0);
+ }//GEN-LAST:event_exitMenuItemActionPerformed
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new SwingInteraction().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+ private javax.swing.JMenuItem exitMenuItem;
+ private javax.swing.JMenu fileMenu;
+ private javax.swing.JPanel guiPanel;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JButton rotateButton;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/text2d/MoverBehavior.java b/src/classes/org/jdesktop/j3d/examples/text2d/MoverBehavior.java
new file mode 100644
index 0000000..c73f5e1
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/text2d/MoverBehavior.java
@@ -0,0 +1,141 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.text2d;
+
+import java.awt.event.*;
+import java.awt.AWTEvent;
+import javax.media.j3d.*;
+import java.util.Enumeration;
+import javax.vecmath.*;
+
+// Mover behavior class - used to allow viewer to move using arrow keys
+class MoverBehavior extends Behavior
+{
+ WakeupOnAWTEvent w1 = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED);
+ WakeupCriterion[] w2 = {w1};
+ WakeupCondition w = new WakeupOr(w2);
+ TransformGroup viewTransformGroup;
+ double rotation = 0.0; // holds current rotation radians
+
+ public void initialize() {
+ // Establish initial wakeup criteria
+ wakeupOn(w);
+ }
+
+
+ /**
+ * Override Behavior's stimulus method to handle the event.
+ */
+ public void processStimulus(Enumeration criteria) {
+ WakeupOnAWTEvent ev;
+ WakeupCriterion genericEvt;
+ AWTEvent[] events;
+
+ while (criteria.hasMoreElements()) {
+ genericEvt = (WakeupCriterion) criteria.nextElement();
+ if (genericEvt instanceof WakeupOnAWTEvent) {
+ ev = (WakeupOnAWTEvent) genericEvt;
+ events = ev.getAWTEvent();
+ processManualEvent(events);
+ }
+ }
+ // Set wakeup criteria for next time
+ wakeupOn(w);
+ }
+
+
+ /**
+ * Process a keyboard event to move or rotate the viewer.
+ */
+ void processManualEvent(AWTEvent[] events) {
+
+ for (int i = 0; i < events.length; ++i) {
+ if (events[i] instanceof KeyEvent) {
+ KeyEvent event = (KeyEvent)events[i];
+ if (event.getKeyCode() == KeyEvent.VK_EQUALS) {
+ continue;
+ }
+ Transform3D t = new Transform3D();
+ viewTransformGroup.getTransform(t);
+ Vector3f viewDir = new Vector3f(0f, 0f, -1f);
+ Vector3f translation = new Vector3f();
+ t.get(translation);
+ t.transform(viewDir);
+ if (event.getKeyCode() == KeyEvent.VK_UP) {
+ translation.x += viewDir.x;
+ translation.y += viewDir.y;
+ translation.z += viewDir.z;
+ }
+ else if (event.getKeyCode() == KeyEvent.VK_DOWN) {
+ translation.x -= viewDir.x;
+ translation.y -= viewDir.y;
+ translation.z -= viewDir.z;
+ }
+ else if (event.getKeyCode() == KeyEvent.VK_RIGHT) {
+ rotation += -.1;
+ }
+ else if (event.getKeyCode() == KeyEvent.VK_LEFT) {
+ rotation += .1;
+ }
+ t.rotY(rotation);
+ t.setTranslation(translation);
+ viewTransformGroup.setTransform(t);
+ }
+ }
+ }
+
+
+ /**
+ * Constructor
+ */
+ public MoverBehavior(TransformGroup trans) {
+ viewTransformGroup = trans;
+ Bounds bound = new BoundingSphere(new Point3d(0.0,0.0,0.0),10000.0);
+ this.setSchedulingBounds(bound);
+ }
+}
+
+
+
diff --git a/src/classes/org/jdesktop/j3d/examples/text2d/Text2DTest.java b/src/classes/org/jdesktop/j3d/examples/text2d/Text2DTest.java
new file mode 100644
index 0000000..a6c6275
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/text2d/Text2DTest.java
@@ -0,0 +1,193 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.text2d;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.Font;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.Text2D;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Text2DTest extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ TransformGroup textTranslationGroup;
+ Transform3D textTranslation;
+ float yPos = -.5f;
+ Shape3D textObject = new Text2D("Rotating Yellow Text",
+ new Color3f(1f, 1f, 0f),
+ "Serif",
+ 60,
+ Font.BOLD);
+ Appearance app = textObject.getAppearance();
+
+ PolygonAttributes pa = app.getPolygonAttributes();
+ if (pa == null)
+ pa = new PolygonAttributes();
+ pa.setCullFace(PolygonAttributes.CULL_NONE);
+ if (app.getPolygonAttributes() == null)
+ app.setPolygonAttributes(pa);
+ objTrans.addChild(textObject);
+
+
+ textTranslation = new Transform3D();
+ textTranslation.setTranslation(new Vector3f(0f, yPos, 0f));
+ textTranslationGroup = new TransformGroup(textTranslation);
+ textTranslationGroup.addChild(objTrans);
+ objScale.addChild(textTranslationGroup);
+ yPos += .5f;
+
+ /* Blue 40point text*/
+ textObject = new Text2D("Blue 40point Text",
+ new Color3f(0f, 0f, 1f),
+ "Serif",
+ 40,
+ Font.BOLD);
+ textTranslation = new Transform3D();
+ textTranslation.setTranslation(new Vector3f(0f, yPos, 0f));
+ textTranslationGroup = new TransformGroup(textTranslation);
+ textTranslationGroup.addChild(textObject);
+ objScale.addChild(textTranslationGroup);
+ yPos += .5f;
+
+ /* Green italic text*/
+ textObject = new Text2D("Green Italic Text",
+ new Color3f(0f, 1f, 0f),
+ "Serif",
+ 70,
+ Font.ITALIC);
+ textTranslation = new Transform3D();
+ textTranslation.setTranslation(new Vector3f(0f, yPos, 0f));
+ textTranslationGroup = new TransformGroup(textTranslation);
+ textTranslationGroup.addChild(textObject);
+ objScale.addChild(textTranslationGroup);
+ yPos += .5f;
+
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+
+ return objRoot;
+ }
+
+ public Text2DTest() {
+ }
+
+ public void init() {
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+ MoverBehavior navigator =
+ new MoverBehavior(u.getViewingPlatform().getViewPlatformTransform());
+ scene.addChild(navigator);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ scene.compile();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows HelloUniverse to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new Text2DTest(), 256, 256);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/text3d/Text3DLoad.java b/src/classes/org/jdesktop/j3d/examples/text3d/Text3DLoad.java
new file mode 100644
index 0000000..3ff6955
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/text3d/Text3DLoad.java
@@ -0,0 +1,286 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.text3d;
+
+import com.sun.j3d.loaders.objectfile.*;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.io.*;
+import com.sun.j3d.utils.behaviors.vp.*;
+import com.sun.j3d.utils.behaviors.keyboard.*;
+
+public class Text3DLoad extends Applet implements ActionListener {
+
+ private String fontName = "TestFont";
+ private String textString = null;
+ private double tessellation = 0.0;
+
+ private SimpleUniverse u;
+
+ private Button button;
+ private boolean behaviorsOn = false;
+ private OrbitBehavior orbit;
+
+ public BranchGroup createSceneGraph() {
+ float sl = textString.length();
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ // Assuming uniform size chars, set scale to fit string in view
+ t3d.setScale(1.2/sl);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+ objScale.addChild(objTrans);
+
+ Font3D f3d;
+ if (tessellation > 0.0) {
+ f3d = new Font3D(new Font(fontName, Font.PLAIN, 2),
+ tessellation,
+ new FontExtrusion());
+ }
+ else {
+ f3d = new Font3D(new Font(fontName, Font.PLAIN, 2),
+ new FontExtrusion());
+ }
+ Text3D txt = new Text3D(f3d, textString,
+ new Point3f( -sl/2.0f, -1.f, -1.f));
+ Shape3D sh = new Shape3D();
+ Appearance app = new Appearance();
+ Material mm = new Material();
+ mm.setLightingEnable(true);
+ app.setMaterial(mm);
+ sh.setGeometry(txt);
+ sh.setAppearance(app);
+ objTrans.addChild(sh);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ if (false) {
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+ }
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+ Background bgNode = new Background(bgColor);
+ bgNode.setApplicationBounds(bounds);
+ objRoot.addChild(bgNode);
+
+ // Set up the ambient light
+ Color3f ambientColor = new Color3f(0.3f, 0.3f, 0.3f);
+ AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+ ambientLightNode.setInfluencingBounds(bounds);
+ objRoot.addChild(ambientLightNode);
+
+ // Set up the directional lights
+ Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+ Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f);
+ Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+
+ DirectionalLight light1
+ = new DirectionalLight(light1Color, light1Direction);
+ light1.setInfluencingBounds(bounds);
+ objRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ objRoot.addChild(light2);
+
+ return objRoot;
+ }
+
+ private void usage()
+ {
+ System.out.println(
+ "Usage: java Text3DLoad [-f fontname] [-t tessellation] [<text>]");
+ System.exit(0);
+ } // End of usage
+
+ public Text3DLoad() {}
+
+ public Text3DLoad(String args[]) {
+
+ if (args.length == 0) {
+// usage();
+ textString = "Java3D";
+ }
+ else {
+ for (int i = 0 ; i < args.length ; i++) {
+ if (args[i].startsWith("-")) {
+ if (args[i].equals("-f")) {
+ if (i < args.length - 1) {
+ fontName = args[++i];
+ }
+ else {
+ usage();
+ }
+ }
+ else if (args[i].equals("-t")) {
+ if (i < args.length - 1) {
+ tessellation = Double.parseDouble(args[++i]);
+ }
+ else {
+ usage();
+ }
+ }
+ else {
+ System.err.println("Argument '" + args[i] +
+ "' ignored.");
+ }
+ }
+ else {
+ textString = args[i];
+ }
+ }
+ }
+
+ if (textString == null) {
+ usage();
+ }
+
+ }
+
+ public void init() {
+
+ if (textString == null) {
+ textString = "Java3D";
+ }
+ setLayout(new BorderLayout());
+
+ button = new Button("remove behaviors");
+ button.addActionListener(this);
+ Panel p = new Panel();
+ p.add(button);
+ add("South", p);
+
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+
+ // create a SimpleUniverse with 4 TransformGroups for the mouse
+ // behaviors
+ u = new SimpleUniverse(c);
+
+ // add the behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+
+ viewingPlatform.setNominalViewingTransform();
+
+ // add orbit behavior to ViewingPlatform
+ orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL |
+ OrbitBehavior.STOP_ZOOM);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ behaviorsOn = true;
+
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == button) {
+ ViewingPlatform v = u.getViewingPlatform();
+ if (behaviorsOn) {
+ v.setViewPlatformBehavior(null);
+ button.setLabel("add behaviors");
+ behaviorsOn = false;
+ }
+ else {
+ v.setViewPlatformBehavior(orbit);
+ button.setLabel("remove behaviors");
+ behaviorsOn = true;
+ }
+ }
+ }
+
+ //
+ // The following allows Text3DLoad to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ new MainFrame(new Text3DLoad(args), 700, 700);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/texture/MultiTextureTest.java b/src/classes/org/jdesktop/j3d/examples/texture/MultiTextureTest.java
new file mode 100644
index 0000000..026cfe9
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/texture/MultiTextureTest.java
@@ -0,0 +1,320 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.texture;
+
+import com.sun.j3d.utils.image.TextureLoader;
+import com.sun.j3d.utils.geometry.Box;
+import com.sun.j3d.utils.behaviors.vp.*;
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.image.BufferedImage;
+
+public class MultiTextureTest extends Applet implements ItemListener{
+
+ Choice choice;
+ TextureUnitState textureUnitState[] = new TextureUnitState[2];
+ Texture stoneTex;
+ Texture skyTex;
+ Texture lightTex;
+
+ private java.net.URL stoneImage = null;
+ private java.net.URL skyImage = null;
+
+ private SimpleUniverse u = null;
+
+ public Texture createLightMap(){
+
+ int width = 128;
+ int height = 128;
+ BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ int [] rgbArray = new int[width * height];
+ int index, index2;
+ int rgbInc = 256 / (width / 2 - 20);
+ int rgbValue = 0;
+ int k = width/2 - 5;
+ int i, j, rgb;
+
+ rgb = 0xff;
+ rgbValue = rgb | (rgb << 8) | (rgb << 16) | (rgb << 24);
+ for ( i = width / 2 - 1, j = 0; j < 10; j++, i--) {
+ rgbArray[i] = rgbValue;
+ }
+
+ for (; i > 8; i--, rgb -= rgbInc) {
+ rgbValue = rgb | (rgb << 8) | (rgb << 16) | (rgb << 24);
+ rgbArray[i] = rgbValue;
+ }
+
+ for (; i >= 0; i--) {
+ rgbArray[i] = rgbValue;
+ }
+
+ for (i = 0; i < width/2; i++) {
+ rgbValue = rgbArray[i];
+ index = i;
+ index2 = (width - i - 1);
+ for (j = 0; j < height; j++) {
+ rgbArray[index] = rgbArray[index2] = rgbValue;
+ index += width;
+ index2 += width;
+ }
+ }
+
+ bimage.setRGB(0, 0, width, height, rgbArray, 0, width);
+
+
+ ImageComponent2D grayImage = new ImageComponent2D(ImageComponent.FORMAT_RGB, bimage);
+
+ lightTex = new Texture2D(Texture.BASE_LEVEL, Texture.RGB, width, height);
+ lightTex.setImage(0, grayImage);
+
+ return lightTex;
+ }
+
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create a Transformgroup to scale all objects so they
+ // appear in the scene.
+ TransformGroup objScale = new TransformGroup();
+ Transform3D t3d = new Transform3D();
+ t3d.setScale(0.4);
+ objScale.setTransform(t3d);
+ objRoot.addChild(objScale);
+
+ TransformGroup objTrans = new TransformGroup();
+ //write-enable for behaviors
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.setCapability( TransformGroup.ALLOW_TRANSFORM_READ );
+ objTrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
+ objScale.addChild(objTrans);
+
+ Appearance ap = new Appearance();
+
+ // load textures
+ TextureAttributes texAttr1 = new TextureAttributes();
+ texAttr1.setTextureMode(TextureAttributes.DECAL);
+ TextureAttributes texAttr2 = new TextureAttributes();
+ texAttr2.setTextureMode(TextureAttributes.MODULATE);
+
+ TextureLoader tex = new TextureLoader(stoneImage, new String("RGB"), this);
+ if (tex == null)
+ return null;
+ stoneTex = tex.getTexture();
+
+ tex = new TextureLoader(skyImage, new String("RGB"), this);
+ if (tex == null)
+ return null;
+ skyTex = tex.getTexture();
+
+ lightTex = createLightMap();
+
+
+ textureUnitState[0] = new TextureUnitState(stoneTex, texAttr1, null);
+ textureUnitState[0].setCapability(TextureUnitState.ALLOW_STATE_WRITE);
+
+ textureUnitState[1] = new TextureUnitState(lightTex, texAttr2, null);
+ textureUnitState[1].setCapability(TextureUnitState.ALLOW_STATE_WRITE);
+
+ ap.setTextureUnitState(textureUnitState);
+
+ //Create a Box
+ Box BoxObj = new Box(1.5f, 1.5f, 0.8f, Box.GENERATE_NORMALS |
+ Box.GENERATE_TEXTURE_COORDS, ap, 2);
+ // add it to the scene graph.
+ objTrans.addChild(BoxObj);
+
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ //Shine it with two lights.
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Color3f lColor2 = new Color3f(0.2f, 0.2f, 0.1f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
+ Vector3f lDir2 = new Vector3f(0.0f, 0.0f, -1.0f);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2);
+ lgt1.setInfluencingBounds(bounds);
+ lgt2.setInfluencingBounds(bounds);
+ objScale.addChild(lgt1);
+ objScale.addChild(lgt2);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public MultiTextureTest (){
+ }
+
+ public MultiTextureTest(java.net.URL stoneURL, java.net.URL skyURL) {
+ stoneImage = stoneURL;
+ skyImage = skyURL;
+ }
+
+ public void init() {
+ if (stoneImage == null) {
+ // the path to the image for an applet
+ try {
+ stoneImage = new java.net.URL(getCodeBase().toString() +
+ "../images/stone.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ if (skyImage == null) {
+ // the path to the image for an applet
+ try {
+ skyImage = new java.net.URL(getCodeBase().toString() +
+ "../images/bg.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ ViewingPlatform viewingPlatform = u.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ // add orbit behavior but disable translate
+ OrbitBehavior orbit =
+ new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL |
+ OrbitBehavior.DISABLE_TRANSLATE);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ u.addBranchGraph(scene);
+
+ // create the gui
+ choice = new Choice();
+ choice.addItem("stone + light");
+ choice.addItem("stone");
+ choice.addItem("lightMap");
+ choice.addItem("sky");
+ choice.addItem("stone + sky");
+ choice.addItemListener(this);
+ add("North", choice);
+
+ }
+
+ public void destroy() {
+ // Cleanup reference to Java3D
+ textureUnitState = new TextureUnitState[2];
+ u.cleanup();
+ }
+
+ public void itemStateChanged(ItemEvent e)
+ {
+ int index = choice.getSelectedIndex();
+
+ switch (index) {
+ case 0 : /* stone + light */
+ textureUnitState[0].setTexture(stoneTex);
+ textureUnitState[1].setTexture(lightTex);
+ break;
+ case 1 : /* stone */
+ textureUnitState[0].setTexture(stoneTex);
+ textureUnitState[1].setTexture(null);
+ break;
+ case 2 : /* light */
+ textureUnitState[0].setTexture(null);
+ textureUnitState[1].setTexture(lightTex);
+ break;
+ case 3 : /* sky */
+ textureUnitState[0].setTexture(null);
+ textureUnitState[1].setTexture(skyTex);
+ break;
+ case 4 : /* stone + sky */
+ textureUnitState[0].setTexture(stoneTex);
+ textureUnitState[1].setTexture(skyTex);
+ break;
+ default: /* both */
+ break;
+ }
+ }
+
+ public static void main(String argv[])
+ {
+ java.net.URL stoneURL = null;
+ java.net.URL skyURL = null;
+ // the path to the image for an application
+ try {
+ stoneURL = new java.net.URL("file:../images/stone.jpg");
+ skyURL = new java.net.URL("file:../images/bg.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ new MainFrame(new MultiTextureTest(stoneURL, skyURL), 750, 750);
+ }
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/texture/TextureImage.java b/src/classes/org/jdesktop/j3d/examples/texture/TextureImage.java
new file mode 100644
index 0000000..b6ab08f
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/texture/TextureImage.java
@@ -0,0 +1,180 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.texture;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import com.sun.j3d.utils.geometry.Box;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class TextureImage extends Applet {
+
+ private java.net.URL texImage = null;
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create the transform group node and initialize it to the
+ // identity. Enable the TRANSFORM_WRITE capability so that
+ // our behavior code can modify it at runtime. Add it to the
+ // root of the subgraph.
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // Create appearance object for textured cube
+ Appearance app = new Appearance();
+ Texture tex = new TextureLoader(texImage, this).getTexture();
+ app.setTexture(tex);
+ TextureAttributes texAttr = new TextureAttributes();
+ texAttr.setTextureMode(TextureAttributes.MODULATE);
+ app.setTextureAttributes(texAttr);
+
+ // Create textured cube and add it to the scene graph.
+ Box textureCube = new Box(0.4f, 0.4f, 0.4f,
+ Box.GENERATE_TEXTURE_COORDS, app);
+ objTrans.addChild(textureCube);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into
+ // the scene graph.
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public TextureImage() {
+ }
+
+ public TextureImage(java.net.URL url) {
+ texImage = url;
+ }
+
+ public void init() {
+ if (texImage == null) {
+ // the path to the image for an applet
+ try {
+ texImage = new java.net.URL(getCodeBase().toString() +
+ "../images/stone.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ u.getViewingPlatform().setNominalViewingTransform();
+
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+ //
+ // The following allows TextureImage to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {
+ java.net.URL url = null;
+ if (args.length > 0) {
+ try {
+ url = new java.net.URL("file:" + args[0]);
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ else {
+ // the path to the image for an application
+ try {
+ url = new java.net.URL("file:../images/stone.jpg");
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ new MainFrame(new TextureImage(url), 256, 256);
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java
new file mode 100644
index 0000000..66c9fef
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java
@@ -0,0 +1,317 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.texture_by_ref;
+
+import javax.media.j3d.*;
+import java.awt.image.BufferedImage;
+import java.awt.*;
+import com.sun.j3d.utils.image.TextureLoader;
+import java.util.Enumeration;
+
+public class AnimateTexturesBehavior extends Behavior {
+
+
+ // what image are we on
+ private int current;
+ private int max;
+
+ // the images
+ private ImageComponent2D[] images;
+
+ // the target
+ private Texture2D texture;
+ private Appearance appearance;
+
+ // the wakeup criterion
+ private WakeupCriterion wakeupC;
+
+ // are the images flipped?
+ private boolean flip;
+
+ // need the current type because by copy changes all images
+ // to TYPE_INT_ARGB
+ private int currentType;
+
+ // for custom types
+ public static final int TYPE_CUSTOM_RGBA = 0x01;
+ public static final int TYPE_CUSTOM_RGB = 0x02;
+
+ private int customType;
+
+ // create a new AnimateTextureBehavior
+ // initialize the images
+ public AnimateTexturesBehavior(Texture2D texP,
+ java.net.URL[] fnames,
+ Appearance appP,
+ TextureByReference applet) {
+ int size = fnames.length;
+ images = new ImageComponent2D[size];
+ BufferedImage bImage;
+ TextureLoader loader;
+ for (int i = 0; i < size; i++) {
+ loader = new TextureLoader(fnames[i],
+ TextureLoader.BY_REFERENCE |
+ TextureLoader.Y_UP, applet);
+ images[i] = loader.getImage();
+ bImage = images[i].getImage();
+
+ // convert the image to TYPE_4BYTE_ABGR
+ currentType = BufferedImage.TYPE_4BYTE_ABGR;
+ bImage = ImageOps.convertImage(bImage, currentType);
+ // flip the image
+ flip = true;
+ ImageOps.flipImage(bImage);
+
+ // set the image on the ImageComponent to the new one
+ images[i].set(bImage);
+
+ images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ);
+ images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ);
+ }
+ texture = texP;
+ current = 0;
+ max = size;
+ wakeupC = new WakeupOnElapsedFrames(20);
+ appearance = appP;
+ }
+
+ // initialize to the first image
+ public void initialize() {
+ texture.setImage(0, images[current]);
+ if (current < max-1) current++;
+ else current = 0;
+ wakeupOn(wakeupC);
+ }
+
+ // procesStimulus changes the ImageComponent of the texture
+ public void processStimulus(Enumeration criteria) {
+ // ImageOps.printType(images[current].getImage());
+ texture.setImage(0, images[current]);
+ appearance.setTexture(texture);
+ if (current < max-1) current++;
+ else current = 0;
+ wakeupOn(wakeupC);
+ }
+
+ // flip the image -- useful depending on yUp
+ public void setFlipImages(boolean b) {
+ // double check that flipping is necessary
+ if (b != flip) {
+ BufferedImage bImage;
+
+ // these are the same for all images so get info once
+ int format = images[0].getFormat();
+ boolean byRef = images[0].isByReference();
+ boolean yUp = images[0].isYUp();
+
+ // flip all the images
+ // have to new ImageComponents because can't set the image at runtime
+ for (int i = 0; i < images.length; i++) {
+ bImage = images[i].getImage();
+ ImageOps.flipImage(bImage);
+ // if we are byRef and the bImage type does not match currentType
+ // we need to convert it. If we are not byRef we will
+ // save converting until it is changed to byRef
+ if (byRef && bImage.getType() != currentType) {
+ if (currentType != BufferedImage.TYPE_CUSTOM) {
+ bImage = ImageOps.convertImage(bImage, currentType);
+ }
+ else if (customType == this.TYPE_CUSTOM_RGBA) {
+ bImage = ImageOps.convertToCustomRGBA(bImage);
+ }
+ else {
+ bImage = ImageOps.convertToCustomRGB(bImage);
+ }
+ }
+ images[i] = new ImageComponent2D(format, bImage, byRef, yUp);
+ images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ);
+ images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ);
+ }
+
+ // set flip to new value
+ flip = b;
+ }
+ }
+
+ // create new ImageComponents with yUp set to the parameter. yUp on
+ // an ImageComponent cannot be changed at runtim
+ public void setYUp(boolean b) {
+ // double check that changing yUp is necessary
+ if (b != images[0].isYUp()) {
+
+ // these are the same for all images so get info once
+ int format = images[0].getFormat();
+ boolean byRef = images[0].isByReference();
+
+ // reset yUp on all the images -- have to new ImageComponents because
+ // cannot change the value at runtime
+ for (int i = 0; i < images.length; i++) {
+ // if we are byRef and the bImage type does not match currentType
+ // we need to convert it. If we are not byRef we will
+ // save converting until it is changed to byRef
+ BufferedImage bImage = images[i].getImage();
+ if (byRef && bImage.getType() != currentType) {
+ // bImage = ImageOps.convertImage(bImage, currentType);
+ if (currentType != BufferedImage.TYPE_CUSTOM) {
+ bImage = ImageOps.convertImage(bImage, currentType);
+ }
+ else if (customType == this.TYPE_CUSTOM_RGBA) {
+ bImage = ImageOps.convertToCustomRGBA(bImage);
+ }
+ else {
+ bImage = ImageOps.convertToCustomRGB(bImage);
+ }
+ }
+ images[i] = new ImageComponent2D(format, bImage,
+ byRef, b);
+ images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ);
+ images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ);
+ }
+ }
+ }
+
+ // create new ImageComponents with ByReference set by parameter.
+ // by reference cannot be changed on an image component at runtime
+ public void setByReference(boolean b) {
+ // double check that changing is necessary
+ if (b != images[0].isByReference()) {
+
+ // these are the same for all images so get info once
+ int format = images[0].getFormat();
+ boolean yUp = images[0].isYUp();
+
+ // reset yUp on all the images
+ // have to new ImageComponents because cannot set value
+ for (int i = 0; i < images.length; i++) {
+ // if the bImage type does not match currentType and we are setting
+ // to byRef we need to convert it
+ BufferedImage bImage = images[i].getImage();
+ if (bImage.getType() != currentType && b) {
+ // bImage = ImageOps.convertImage(bImage, currentType);
+ if (currentType != BufferedImage.TYPE_CUSTOM) {
+ bImage = ImageOps.convertImage(bImage, currentType);
+ }
+ else if (customType == this.TYPE_CUSTOM_RGBA) {
+ bImage = ImageOps.convertToCustomRGBA(bImage);
+ }
+ else {
+ bImage = ImageOps.convertToCustomRGB(bImage);
+ }
+ }
+ images[i] = new ImageComponent2D(format, bImage, b, yUp);
+ images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ);
+ images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ);
+ }
+ }
+ }
+
+ // make a new wakeup criterion object based on the new delay time
+ public void setFrameDelay(int delay) {
+ wakeupC = new WakeupOnElapsedFrames(delay);
+ }
+
+ //change the type of image
+ public void setImageType(int newType) {
+ currentType = newType;
+
+ // only need to change the images if we are byRef otherwise will change
+ // them when we chnage to byRef
+ if (images[0].isByReference() == true) {
+ // this information is the same for all
+ int format = images[0].getFormat();
+ boolean yUp = images[0].isYUp();
+ boolean byRef = true;
+ for (int i = 0; i < images.length; i++) {
+ BufferedImage bImage = images[i].getImage();
+ bImage = ImageOps.convertImage(bImage, currentType);
+ images[i] = new ImageComponent2D(format, bImage, byRef, yUp);
+ images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ);
+ images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ);
+ }
+ }
+ }
+
+ public void setImageTypeCustomRGBA() {
+ currentType = BufferedImage.TYPE_CUSTOM;
+ customType = this.TYPE_CUSTOM_RGBA;
+
+ // only need to change images if we are byRef otherwise will change
+ // them when we change to byRef
+ if (images[0].isByReference()) {
+ // this information is the same for all
+ int format = images[0].getFormat();
+ boolean yUp = images[0].isYUp();
+ boolean byRef = true;
+ for (int i = 0; i < images.length; i++) {
+ BufferedImage bImage = images[i].getImage();
+ bImage = ImageOps.convertToCustomRGBA(bImage);
+ images[i] = new ImageComponent2D(format, bImage, byRef, yUp);
+ images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ);
+ images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ);
+ }
+ }
+ }
+
+ public void setImageTypeCustomRGB() {
+ currentType = BufferedImage.TYPE_CUSTOM;
+ customType = this.TYPE_CUSTOM_RGB;
+
+ // only need to change images if we are byRef otherwise will change
+ // them when we change to byRef
+ if (images[0].isByReference()) {
+ // this information is the same for all
+ int format = images[0].getFormat();
+ boolean yUp = images[0].isYUp();
+ boolean byRef = true;
+ for (int i = 0; i < images.length; i++) {
+ BufferedImage bImage = images[i].getImage();
+ bImage = ImageOps.convertToCustomRGB(bImage);
+ images[i] = new ImageComponent2D(format, bImage, byRef, yUp);
+ images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ);
+ images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ);
+ }
+ }
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java
new file mode 100644
index 0000000..97d5387
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java
@@ -0,0 +1,175 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.texture_by_ref;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.color.*;
+
+// some useful, static image operations
+
+public class ImageOps {
+
+ // flip the image
+ public static void flipImage(BufferedImage bImage) {
+ int width = bImage.getWidth();
+ int height = bImage.getHeight();
+ int[] rgbArray = new int[width*height];
+ bImage.getRGB(0, 0, width, height, rgbArray, 0, width);
+ int[] tempArray = new int[width*height];
+ int y2 = 0;
+ for (int y = height-1; y >= 0; y--) {
+ for (int x = 0; x < width; x++) {
+ tempArray[y2*width+x] = rgbArray[y*width+x];
+ }
+ y2++;
+ }
+ bImage.setRGB(0, 0, width, height, tempArray, 0, width);
+ }
+
+
+ // convert the image to a specified BufferedImage type and return it
+ public static BufferedImage convertImage(BufferedImage bImage, int type) {
+ int width = bImage.getWidth();
+ int height = bImage.getHeight();
+ BufferedImage newImage = new BufferedImage(width, height, type);
+ int[] rgbArray = new int[width*height];
+ bImage.getRGB(0, 0, width, height, rgbArray, 0, width);
+ newImage.setRGB(0, 0, width, height, rgbArray, 0, width);
+ return newImage;
+ }
+
+ // print out some of the types of BufferedImages
+ static void printType(BufferedImage bImage) {
+ int type = bImage.getType();
+ if (type == BufferedImage.TYPE_4BYTE_ABGR) {
+ System.out.println("TYPE_4BYTE_ABGR");
+ }
+ else if (type == BufferedImage.TYPE_INT_ARGB) {
+ System.out.println("TYPE_INT_ARGB");
+ }
+ else if (type == BufferedImage.TYPE_3BYTE_BGR) {
+ System.out.println("TYPE_3BYTE_BGR");
+ }
+ else if (type == BufferedImage.TYPE_CUSTOM) {
+ System.out.println("TYPE_CUSTOM");
+ }
+ else System.out.println(type);
+ }
+
+ public static BufferedImage convertToCustomRGBA(BufferedImage bImage) {
+ if (bImage.getType() != BufferedImage.TYPE_INT_ARGB) {
+ ImageOps.convertImage(bImage, BufferedImage.TYPE_INT_ARGB);
+ }
+
+ int width = bImage.getWidth();
+ int height = bImage.getHeight();
+
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ int[] nBits = {8, 8, 8, 8};
+ ColorModel cm = new ComponentColorModel(cs, nBits, true, false,
+ Transparency.OPAQUE, 0);
+ int[] bandOffset = {0, 1, 2, 3};
+
+ WritableRaster newRaster =
+ Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
+ width*4, 4, bandOffset, null);
+ byte[] byteData = ((DataBufferByte)newRaster.getDataBuffer()).getData();
+ Raster origRaster = bImage.getData();
+ int[] pixel = new int[4];
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ pixel = origRaster.getPixel(i, j, pixel);
+ byteData[k++] = (byte)(pixel[0]);
+ byteData[k++] = (byte)(pixel[1]);
+ byteData[k++] = (byte)(pixel[2]);
+ byteData[k++] = (byte)(pixel[3]);
+ }
+ }
+ BufferedImage newImage = new BufferedImage(cm, newRaster, false, null);
+// if (newImage.getType() == BufferedImage.TYPE_CUSTOM) {
+// System.out.println("Type is custom");
+// }
+ return newImage;
+ }
+
+ public static BufferedImage convertToCustomRGB(BufferedImage bImage) {
+ if (bImage.getType() != BufferedImage.TYPE_INT_ARGB) {
+ ImageOps.convertImage(bImage, BufferedImage.TYPE_INT_ARGB);
+ }
+
+ int width = bImage.getWidth();
+ int height = bImage.getHeight();
+
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ int[] nBits = {8, 8, 8};
+ ColorModel cm = new ComponentColorModel(cs, nBits, false, false,
+ Transparency.OPAQUE, 0);
+ int[] bandOffset = {0, 1, 2};
+
+ WritableRaster newRaster =
+ Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
+ width*3, 3, bandOffset, null);
+ byte[] byteData = ((DataBufferByte)newRaster.getDataBuffer()).getData();
+ Raster origRaster = bImage.getData();
+ int[] pixel = new int[4];
+ int k = 0;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ pixel = origRaster.getPixel(i, j, pixel);
+ byteData[k++] = (byte)(pixel[0]);
+ byteData[k++] = (byte)(pixel[1]);
+ byteData[k++] = (byte)(pixel[2]);
+ }
+ }
+ BufferedImage newImage = new BufferedImage(cm, newRaster, false, null);
+// if (newImage.getType() == BufferedImage.TYPE_CUSTOM) {
+// System.out.println("Type is custom");
+// }
+ return newImage;
+ }
+}
+
diff --git a/src/classes/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java
new file mode 100644
index 0000000..bd564a7
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java
@@ -0,0 +1,223 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.texture_by_ref;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+
+public class Tetrahedron extends Shape3D {
+
+ private static final float sqrt3 = (float) Math.sqrt(3.0);
+ private static final float sqrt3_3 = sqrt3 / 3.0f;
+ private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;
+
+ private static final float ycenter = 0.5f * sqrt24_3;
+ private static final float zcenter = -sqrt3_3;
+
+ private static final Point3f p1 = new Point3f(-1.0f, -ycenter, -zcenter);
+ private static final Point3f p2 = new Point3f(1.0f, -ycenter, -zcenter);
+ private static final Point3f p3 = new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
+ private static final Point3f p4 = new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);
+
+ private static final Point3f[] verts = {
+ p1, p2, p4, // front face
+ p1, p4, p3, // left, back face
+ p2, p3, p4, // right, back face
+ p1, p3, p2, // bottom face
+ };
+
+ private Point2f texCoord[] = {
+ new Point2f(-0.25f, 0.0f),
+ new Point2f(1.25f, 0.0f),
+ new Point2f(0.5f, 2.0f),
+ };
+
+ private TriangleArray geometryByRef;
+ private TriangleArray geometryByCopy;
+
+ // for geometry by reference
+ private Point3f[] verticesArray = new Point3f[12];
+ private TexCoord2f[] textureCoordsArray = new TexCoord2f[12];
+ private Vector3f[] normalsArray = new Vector3f[12];
+
+ // default to geometry by copy
+ public Tetrahedron() {
+ this(false);
+ }
+
+ // creates a tetrahedron with geometry by reference or by copy depending on
+ // the byRef parameter
+ public Tetrahedron(boolean byRef) {
+ if (byRef) {
+ createGeometryByRef();
+ this.setGeometry(geometryByRef);
+ }
+ else {
+ createGeometryByCopy();
+ this.setGeometry(geometryByCopy);
+ }
+ this.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
+ this.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
+ setAppearance(new Appearance());
+ }
+
+ // create the geometry by reference and
+ // store it in the geometryByRef variable
+ public void createGeometryByRef() {
+// System.out.println("createGeometryByRef");
+ geometryByRef = new TriangleArray(12, TriangleArray.COORDINATES |
+ TriangleArray.NORMALS |
+ TriangleArray.TEXTURE_COORDINATE_2 |
+ TriangleArray.BY_REFERENCE);
+
+ int i;
+
+ // the coordinates
+ for (i = 0; i < 12; i++) {
+ verticesArray[i] = new Point3f(verts[i]);
+ }
+ geometryByRef.setCoordRef3f(verticesArray);
+// System.out.println("coordinates set");
+// Point3f[] temp1 = geometryByRef.getCoordRef3f();
+// for (i = 0; i < 12; i++) {
+// System.out.println(temp1[i]);
+// }
+
+ // the texture coordinates
+ for (i = 0; i < 12; i++) {
+ textureCoordsArray[i] = new TexCoord2f(texCoord[i%3]);
+ }
+ geometryByRef.setTexCoordRef2f(0, textureCoordsArray);
+// System.out.println("texture coords set");
+// TexCoord2f[] temp2 = geometryByRef.getTexCoordRef2f(0);
+// for (i = 0; i < 12; i++) {
+// System.out.println(temp2[i]);
+// }
+
+ // the normals
+ Vector3f normal = new Vector3f();
+ Vector3f v1 = new Vector3f();
+ Vector3f v2 = new Vector3f();
+ Point3f[] pts = new Point3f[3];
+ for (int face = 0; face < 4; face++) {
+ pts[0] = new Point3f(verts[face*3]);
+ pts[1] = new Point3f(verts[face*3+1]);
+ pts[2] = new Point3f(verts[face*3+2]);
+ v1.sub(pts[1], pts[0]);
+ v2.sub(pts[2], pts[0]);
+ normal.cross(v1, v2);
+ normal.normalize();
+ for (i = 0; i < 3; i++) {
+ normalsArray[face*3+i] = new Vector3f(normal);
+ }
+ }
+ geometryByRef.setNormalRef3f(normalsArray);
+// System.out.println("normals set");
+// Vector3f[] temp3 = geometryByRef.getNormalRef3f();
+// for (i = 0; i < 12; i++) {
+// System.out.println(temp3[i]);
+// }
+ }
+
+ // create the geometry by copy and store it in the geometryByCopy variable
+ public void createGeometryByCopy() {
+ int i;
+ geometryByCopy = new TriangleArray(12, TriangleArray.COORDINATES |
+ TriangleArray.NORMALS |
+ TriangleArray.TEXTURE_COORDINATE_2);
+
+ geometryByCopy.setCoordinates(0, verts);
+
+ for (i = 0; i < 12; i++) {
+ geometryByCopy.setTextureCoordinate(0, i,
+ new TexCoord2f(texCoord[i%3]));
+ }
+
+ int face;
+ Vector3f normal = new Vector3f();
+ Vector3f v1 = new Vector3f();
+ Vector3f v2 = new Vector3f();
+ Point3f [] pts = new Point3f[3];
+ for (i = 0; i < 3; i++) pts[i] = new Point3f();
+
+ for (face = 0; face < 4; face++) {
+ geometryByCopy.getCoordinates(face*3, pts);
+ v1.sub(pts[1], pts[0]);
+ v2.sub(pts[2], pts[0]);
+ normal.cross(v1, v2);
+ normal.normalize();
+ for (i = 0; i < 3; i++) {
+ geometryByCopy.setNormal((face * 3 + i), normal);
+ }
+ }
+ }
+
+ // set the geometry to geometryByRef or geometryByCopy depending on the
+ // parameter. Create geometryByRef or geometryByCopy if necessary
+ public void setByReference(boolean b) {
+// System.out.println("Tetrahedron.setByReference " + b);
+ // by reference is true
+ if (b) {
+ // if there is no geometryByRef, create it
+ if (geometryByRef == null) {
+ createGeometryByRef();
+ }
+ // set the geometry
+ this.setGeometry(geometryByRef);
+ }
+ // by reference is false
+ else {
+ // if there is no geometryByCopy, create it
+ if (geometryByCopy == null) {
+ createGeometryByCopy();
+ }
+ // set the geometry
+ this.setGeometry(geometryByCopy);
+ }
+ }
+}
+
+
diff --git a/src/classes/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java
new file mode 100644
index 0000000..1faad7e
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java
@@ -0,0 +1,532 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.texture_by_ref;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.image.*;
+import java.awt.color.ColorSpace;
+import com.sun.j3d.utils.image.TextureLoader;
+import javax.swing.*;
+import javax.swing.event.*;
+
+
+public class TextureByReference extends Applet
+implements ItemListener, ActionListener, ChangeListener {
+
+ // need reference to animation behavior
+ private AnimateTexturesBehavior animate;
+
+ // need reference to tetrahedron
+ private Tetrahedron tetra;
+
+ // the gui buttons
+ private JCheckBox flipB;
+ private JRadioButton texByRef;
+ private JRadioButton texByCopy;
+ private JRadioButton geomByRef;
+ private JRadioButton geomByCopy;
+ private JRadioButton img4ByteABGR;
+ private JRadioButton img3ByteBGR;
+ private JRadioButton imgIntARGB;
+ private JRadioButton imgCustomRGBA;
+ private JRadioButton imgCustomRGB;
+ private JRadioButton yUp;
+ private JRadioButton yDown;
+ private JButton animationB;
+ private JSlider frameDelay;
+
+ private SimpleUniverse universe = null;
+
+ // image files used for the Texture animation for the applet,
+ // or if no parameters are passed in for the application
+ public static final String[] defaultFiles = {
+ "../images/animation1.gif",
+ "../images/animation2.gif",
+ "../images/animation3.gif",
+ "../images/animation4.gif",
+ "../images/animation5.gif",
+ "../images/animation6.gif",
+ "../images/animation7.gif",
+ "../images/animation8.gif",
+ "../images/animation9.gif",
+ "../images/animation10.gif"};
+
+ private java.net.URL[] urls = null;
+
+
+ public TextureByReference() {
+ }
+
+ public TextureByReference(java.net.URL[] fnamesP) {
+ urls = fnamesP;
+ }
+
+ public void init() {
+ if (urls == null) {
+ urls = new java.net.URL[defaultFiles.length];
+ for (int i = 0; i < defaultFiles.length; i++) {
+ try {
+ urls[i] = new java.net.URL(getCodeBase().toString() +
+ defaultFiles[i]);
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ }
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D canvas = new Canvas3D(config);
+
+ add("Center", canvas);
+
+ // create a simple scene graph and attach it to a simple universe
+ BranchGroup scene = createSceneGraph();
+ universe = new SimpleUniverse(canvas);
+ universe.getViewingPlatform().setNominalViewingTransform();
+ universe.addBranchGraph(scene);
+
+ // create the gui
+ JPanel gui = buildGui();
+
+ this.add("South", gui);
+ }
+
+ public void destroy() {
+ universe.cleanup();
+ }
+
+ public JPanel buildGui() {
+ flipB = new JCheckBox("flip image", true);
+ flipB.addItemListener(this);
+ javax.swing.Box flipBox = new javax.swing.Box(BoxLayout.Y_AXIS);
+ flipBox.add(flipB);
+ Component strut1 = flipBox.createVerticalStrut(flipB.getPreferredSize().height);
+ Component strut2 = flipBox.createVerticalStrut(flipB.getPreferredSize().height);
+ Component strut3 = flipBox.createVerticalStrut(flipB.getPreferredSize().height);
+ Component strut4 = flipBox.createVerticalStrut(flipB.getPreferredSize().height);
+ Component strut5 = flipBox.createVerticalStrut(flipB.getPreferredSize().height);
+ flipBox.add(strut1);
+ flipBox.add(strut2);
+ flipBox.add(strut3);
+ flipBox.add(strut4);
+ flipBox.add(strut5);
+
+ yUp = new JRadioButton("y up");
+ yUp.addActionListener(this);
+ yUp.setSelected(true);
+ yDown = new JRadioButton("y down");
+ yDown.addActionListener(this);
+ ButtonGroup yGroup = new ButtonGroup();
+ yGroup.add(yUp);
+ yGroup.add(yDown);
+ JLabel yLabel = new JLabel("Image Orientation:");
+ javax.swing.Box yBox = new javax.swing.Box(BoxLayout.Y_AXIS);
+ yBox.add(yLabel);
+ yBox.add(yUp);
+ yBox.add(yDown);
+ strut1 = yBox.createVerticalStrut(yUp.getPreferredSize().height);
+ strut2 = yBox.createVerticalStrut(yUp.getPreferredSize().height);
+ strut3 = yBox.createVerticalStrut(yUp.getPreferredSize().height);
+ yBox.add(strut1);
+ yBox.add(strut2);
+ yBox.add(strut3);
+
+ texByRef = new JRadioButton("by reference");
+ texByRef.addActionListener(this);
+ texByRef.setSelected(true);
+ texByCopy = new JRadioButton("by copy");
+ texByCopy.addActionListener(this);
+ ButtonGroup texGroup = new ButtonGroup();
+ texGroup.add(texByRef);
+ texGroup.add(texByCopy);
+ JLabel texLabel = new JLabel("Texture:*");
+ javax.swing.Box texBox = new javax.swing.Box(BoxLayout.Y_AXIS);
+ texBox.add(texLabel);
+ texBox.add(texByRef);
+ texBox.add(texByCopy);
+ strut1 = texBox.createVerticalStrut(texByRef.getPreferredSize().height);
+ strut2 = texBox.createVerticalStrut(texByRef.getPreferredSize().height);
+ strut3 = texBox.createVerticalStrut(texByRef.getPreferredSize().height);
+ texBox.add(strut1);
+ texBox.add(strut2);
+ texBox.add(strut3);
+
+ geomByRef = new JRadioButton("by reference");
+ geomByRef.addActionListener(this);
+ geomByRef.setSelected(true);
+ geomByCopy = new JRadioButton("by copy");
+ geomByCopy.addActionListener(this);
+ ButtonGroup geomGroup = new ButtonGroup();
+ geomGroup.add(geomByRef);
+ geomGroup.add(geomByCopy);
+ JLabel geomLabel = new JLabel("Geometry:");
+ javax.swing.Box geomBox = new javax.swing.Box(BoxLayout.Y_AXIS);
+ geomBox.add(geomLabel);
+ geomBox.add(geomByRef);
+ geomBox.add(geomByCopy);
+ strut1 = geomBox.createVerticalStrut(geomByRef.getPreferredSize().height);
+ strut2 = geomBox.createVerticalStrut(geomByRef.getPreferredSize().height);
+ strut3 = geomBox.createVerticalStrut(geomByRef.getPreferredSize().height);
+ geomBox.add(strut1);
+ geomBox.add(strut2);
+ geomBox.add(strut3);
+
+ img4ByteABGR = new JRadioButton("TYPE_4BYTE_ABGR");
+ img4ByteABGR.addActionListener(this);
+ img4ByteABGR.setSelected(true);
+ img3ByteBGR = new JRadioButton("TYPE_3BYTE_BGR");
+ img3ByteBGR.addActionListener(this);
+ imgIntARGB = new JRadioButton("TYPE_INT_ARGB");
+ imgIntARGB.addActionListener(this);
+ imgCustomRGBA = new JRadioButton("TYPE_CUSTOM RGBA");
+ imgCustomRGBA.addActionListener(this);
+ imgCustomRGB = new JRadioButton("TYPE_CUSTOM RGB");
+ imgCustomRGB.addActionListener(this);
+ ButtonGroup imgGroup = new ButtonGroup();
+ imgGroup.add(img4ByteABGR);
+ imgGroup.add(img3ByteBGR);
+ imgGroup.add(imgIntARGB);
+ imgGroup.add(imgCustomRGBA);
+ imgGroup.add(imgCustomRGB);
+ JLabel imgLabel = new JLabel("Image Type:*");
+ javax.swing.Box imgBox = new javax.swing.Box(BoxLayout.Y_AXIS);
+ imgBox.add(imgLabel);
+ imgBox.add(img4ByteABGR);
+ imgBox.add(img3ByteBGR);
+ imgBox.add(imgIntARGB);
+ imgBox.add(imgCustomRGBA);
+ imgBox.add(imgCustomRGB);
+
+ javax.swing.Box topBox = new javax.swing.Box(BoxLayout.X_AXIS);
+ topBox.add(flipBox);
+ topBox.add(texBox);
+ topBox.add(geomBox);
+ topBox.add(yBox);
+ Component strut = topBox.createRigidArea(new Dimension(10, 10));
+ topBox.add(strut);
+ topBox.add(imgBox);
+
+ frameDelay = new JSlider(0, 50, 0);
+ frameDelay.addChangeListener(this);
+ frameDelay.setSnapToTicks(true);
+ frameDelay.setPaintTicks(true);
+ frameDelay.setPaintLabels(true);
+ frameDelay.setMajorTickSpacing(10);
+ frameDelay.setMinorTickSpacing(1);
+ frameDelay.setValue(20);
+ JLabel delayL = new JLabel("frame delay");
+ javax.swing.Box delayBox = new javax.swing.Box(BoxLayout.X_AXIS);
+ delayBox.add(delayL);
+ delayBox.add(frameDelay);
+
+ animationB = new JButton(" stop animation ");
+ animationB.addActionListener(this);
+
+ JLabel texInfo1 = new JLabel("*To use ImageComponent by reference feature, use TYPE_4BYTE_ABGR on Solaris");
+ JLabel texInfo2 = new JLabel("and TYPE_3BYTE_BGR on Windows");
+
+ JPanel buttonP = new JPanel();
+ GridBagLayout gridbag = new GridBagLayout();
+ GridBagConstraints c = new GridBagConstraints();
+ buttonP.setLayout(gridbag);
+ c.anchor = GridBagConstraints.CENTER;
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ gridbag.setConstraints(topBox, c);
+ buttonP.add(topBox);
+ gridbag.setConstraints(delayBox, c);
+ buttonP.add(delayBox);
+ gridbag.setConstraints(animationB, c);
+ buttonP.add(animationB);
+ gridbag.setConstraints(texInfo1, c);
+ buttonP.add(texInfo1);
+ gridbag.setConstraints(texInfo2, c);
+ buttonP.add(texInfo2);
+
+ return buttonP;
+
+ }
+
+ public BranchGroup createSceneGraph() {
+
+ // create the root of the branch group
+ BranchGroup objRoot = new BranchGroup();
+
+ // create the transform group node and initialize it
+ // enable the TRANSFORM_WRITE capability so that it can be modified
+ // at runtime. Add it to the root of the subgraph
+ Transform3D rotate = new Transform3D();
+ TransformGroup objTrans = new TransformGroup(rotate);
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+
+ // bounds
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // set up some light
+ Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
+ Vector3f lDir1 = new Vector3f(-1.0f, -0.5f, -1.0f);
+ Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);
+
+ AmbientLight aLgt = new AmbientLight(alColor);
+ aLgt.setInfluencingBounds(bounds);
+ DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
+ lgt1.setInfluencingBounds(bounds);
+ objRoot.addChild(aLgt);
+ objRoot.addChild(lgt1);
+
+
+ Appearance appearance = new Appearance();
+
+ // enable the TEXTURE_WRITE so we can modify it at runtime
+ appearance.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
+
+ // load the first texture
+ TextureLoader loader = new TextureLoader(urls[0],
+ TextureLoader.BY_REFERENCE |
+ TextureLoader.Y_UP,
+ this);
+ // get the texture from the loader
+ Texture2D tex = (Texture2D)loader.getTexture();
+
+ // get the BufferedImage to convert to TYPE_4BYTE_ABGR and flip
+ // get the ImageComponent because we need it anyway
+ ImageComponent2D imageComp = (ImageComponent2D)tex.getImage(0);
+ BufferedImage bImage = imageComp.getImage();
+ // convert the image
+ bImage = ImageOps.convertImage(bImage, BufferedImage.TYPE_4BYTE_ABGR);
+ // flip the image
+ ImageOps.flipImage(bImage);
+ imageComp.set(bImage);
+
+ tex.setCapability(Texture.ALLOW_IMAGE_WRITE);
+ tex.setBoundaryModeS(Texture.CLAMP);
+ tex.setBoundaryModeT(Texture.CLAMP);
+ tex.setBoundaryColor(1.0f, 1.0f, 1.0f, 1.0f);
+
+ // set the image of the texture
+ tex.setImage(0, imageComp);
+
+ // set the texture on the appearance
+ appearance.setTexture(tex);
+
+ // set texture attributes
+ TextureAttributes texAttr = new TextureAttributes();
+ texAttr.setTextureMode(TextureAttributes.MODULATE);
+ appearance.setTextureAttributes(texAttr);
+
+ // set material properties
+ Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
+ Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
+ appearance.setMaterial(new Material(white, black, white, black, 1.0f));
+
+ // create a scale transform
+ Transform3D scale = new Transform3D();
+ scale.set(.6);
+ TransformGroup objScale = new TransformGroup(scale);
+ objTrans.addChild(objScale);
+
+ tetra = new Tetrahedron(true);
+ tetra.setAppearance(appearance);
+ objScale.addChild(tetra);
+
+ // create the behavior
+ animate = new AnimateTexturesBehavior(tex,
+ urls,
+ appearance,
+ this);
+ animate.setSchedulingBounds(bounds);
+
+ objTrans.addChild(animate);
+
+ // add a rotation behavior so we can see all sides of the tetrahedron
+ Transform3D yAxis = new Transform3D();
+ Alpha rotorAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotorAlpha,
+ objTrans,
+ yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+
+
+ // have java3d perform optimizations on this scene graph
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ // callback for the animation button and delay text field
+ public void actionPerformed(ActionEvent e) {
+ Object o = e.getSource();
+
+ // for the animation button
+ if (o == animationB) {
+ if (animate.getEnable()) {
+ animate.setEnable(false);
+ animationB.setText("start animation");
+ }
+ else {
+ animate.setEnable(true);
+ animationB.setText(" stop animation ");
+ }
+ }
+
+ // for the texByRef button
+ else if (o == texByRef && texByRef.isSelected()) {
+ animate.setByReference(true);
+ }
+ // texByCopy button
+ else if (o == texByCopy && texByCopy.isSelected()) {
+ animate.setByReference(false);
+ }
+ // yUp button
+ else if (o == yUp && yUp.isSelected()) {
+ animate.setYUp(true);
+ }
+ // ydown button
+ else if (o == yDown && yDown.isSelected()) {
+ animate.setYUp(false);
+ }
+ //geomByRef button
+ else if (o == geomByRef) {
+ tetra.setByReference(true);
+ }
+ // geomByCopy button
+ else if (o == geomByCopy) {
+ tetra.setByReference(false);
+ }
+ // TYPE_INT_ARGB
+ else if (o == imgIntARGB) {
+ animate.setImageType(BufferedImage.TYPE_INT_ARGB);
+ }
+ // TYPE_4BYTE_ABGR
+ else if (o == img4ByteABGR) {
+ animate.setImageType(BufferedImage.TYPE_4BYTE_ABGR);
+ }
+ // TYPE_3BYTE_BGR
+ else if (o == img3ByteBGR) {
+ animate.setImageType(BufferedImage.TYPE_3BYTE_BGR);
+ }
+ // TYPE_CUSTOM RGBA
+ else if (o == imgCustomRGBA) {
+ animate.setImageTypeCustomRGBA();
+ }
+ // TYPE_CUSTOM RGB
+ else if (o == imgCustomRGB) {
+ animate.setImageTypeCustomRGB();
+ }
+ }
+
+ // callback for the checkboxes
+ public void itemStateChanged(ItemEvent e) {
+ Object o = e.getSource();
+ // for the flip checkbox
+ if (o == flipB) {
+ if (e.getStateChange() == ItemEvent.DESELECTED) {
+ animate.setFlipImages(false);
+ }
+ else animate.setFlipImages(true);
+ }
+ }
+
+ // callback for the slider
+ public void stateChanged(ChangeEvent e) {
+ Object o = e.getSource();
+ // for the frame delay
+ if (o == frameDelay) {
+ animate.setFrameDelay(frameDelay.getValue());
+ }
+ }
+
+ // allows TextureByReference to be run as an application as well as an applet
+ public static void main(String[] args) {
+ java.net.URL fnames[] = null;
+ if (args.length > 1) {
+ fnames = new java.net.URL[args.length];
+ for (int i = 0; i < args.length; i++) {
+ try {
+ fnames[i] = new java.net.URL("file:" + args[i]);
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ }
+ }
+ }
+ else {
+ fnames = new java.net.URL[TextureByReference.defaultFiles.length];
+ for (int i = 0; i < TextureByReference.defaultFiles.length; i++) {
+ try {
+ fnames[i] = new java.net.URL("file:" +
+ TextureByReference.defaultFiles[i]);
+ }
+ catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ }
+ }
+ new MainFrame((new TextureByReference(fnames)), 650, 750);
+ }
+}
+
+
+
+
+
+
diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java
new file mode 100644
index 0000000..b10e59b
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java
@@ -0,0 +1,209 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.virtual_input_device;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.vecmath.*;
+import javax.media.j3d.*;
+
+public class ButtonPositionControls extends Panel implements PositionControls, MouseListener {
+ private final static int STILL=0;
+ private final static int MOVING_UP=1;
+ private final static int MOVING_DOWN=2;
+ private final static int MOVING_LEFT=3;
+ private final static int MOVING_RIGHT=4;
+ private final static int MOVING_FORWARD=5;
+ private final static int MOVING_BACK=6;
+
+ // initial mode
+ private int mode = STILL;
+
+ Vector3f position = new Vector3f();
+ Vector3f orig_position = new Vector3f();
+
+ private Button leftB = new Button("Move Left");
+ private Button rightB = new Button("Move Right");
+ private Button upB = new Button("Move Up");
+ private Button downB = new Button("Move Down");
+
+ private Button forwardB = new Button("Move Forward");
+ private Button backwardB = new Button("Move Back");
+
+ private Button reset = new Button("Reset");
+ private InputDevice device;
+
+ private float step_rate = 0.0023f; // movement rate per millisecond
+ private long time_last_state_change = System.currentTimeMillis();
+
+ // the constructor arguments are the intitial X, Y, and Z positions
+ public ButtonPositionControls( float x, float y, float z ) {
+
+ // up, down, right, and left movement buttons
+ Panel panPanel = new Panel();
+ panPanel.setLayout( new BorderLayout() );
+ panPanel.add("North", upB);
+ panPanel.add("East", rightB);
+ panPanel.add("South", downB);
+ panPanel.add("West", leftB);
+
+ // forward, backward, and reset buttons
+ Panel p = new Panel();
+ p.setLayout( new GridLayout(0,1,0,0) );
+ p.add(forwardB);
+ p.add(backwardB);
+ p.add(reset);
+
+ // set the initial position
+ position.x = x;
+ position.y = y;
+ position.z = z;
+ orig_position.set(position);
+
+ // add a mouse listener to each button
+ upB.addMouseListener(this);
+ downB.addMouseListener(this);
+ leftB.addMouseListener(this);
+ rightB.addMouseListener(this);
+ forwardB.addMouseListener(this);
+ backwardB.addMouseListener(this);
+ reset.addMouseListener(this);
+
+ this.setLayout( new BorderLayout() );
+ add("East", p );
+ add("West", panPanel );
+ }
+
+ public void setDevice ( InputDevice device) {
+ this.device = device;
+ }
+
+ public void getPosition(Vector3f pos ) {
+ calculateMotion();
+ pos.set(position);
+ }
+
+ public void setPosition(Vector3f pos ) {
+ position.set(pos);
+ }
+
+ public void setStepRate( float stepRate ) {
+ step_rate = stepRate;
+ }
+
+ private void calculateMotion() {
+
+ long current_time = System.currentTimeMillis();
+ long elapsed_time = current_time - time_last_state_change;
+
+ switch(mode) {
+ case STILL:
+ break;
+ case MOVING_LEFT:
+ position.x = orig_position.x - step_rate*elapsed_time;
+ break;
+ case MOVING_RIGHT:
+ position.x = orig_position.x + step_rate*elapsed_time;
+ break;
+ case MOVING_UP:
+ position.y = orig_position.y + step_rate*elapsed_time;
+ break;
+ case MOVING_DOWN:
+ position.y = orig_position.y - step_rate*elapsed_time;
+ break;
+ case MOVING_FORWARD:
+ position.z = orig_position.z - step_rate*elapsed_time;
+ break;
+ case MOVING_BACK:
+ position.z = orig_position.z + step_rate*elapsed_time;
+ break;
+ default:
+ throw( new RuntimeException("Unknown motion"));
+ }
+ }
+
+ public void mouseClicked( MouseEvent e ) {
+ }
+
+ public void mouseEntered( MouseEvent e ) {
+ }
+
+ public void mouseExited( MouseEvent e ) {
+ }
+
+ public void mousePressed( MouseEvent e ) {
+ if (e.getSource()==leftB && mode != MOVING_LEFT) {
+ time_last_state_change = System.currentTimeMillis();
+ mode = MOVING_LEFT;
+ orig_position.set(position);
+ } else if (e.getSource()==rightB && mode != MOVING_RIGHT) {
+ time_last_state_change = System.currentTimeMillis();
+ mode = MOVING_RIGHT;
+ orig_position.set(position);
+ } else if (e.getSource()==upB && mode != MOVING_UP) {
+ time_last_state_change = System.currentTimeMillis();
+ mode = MOVING_UP;
+ orig_position.set(position);
+ } else if (e.getSource()==downB && mode != MOVING_DOWN) {
+ time_last_state_change = System.currentTimeMillis();
+ mode = MOVING_DOWN;
+ orig_position.set(position);
+ } else if (e.getSource()==forwardB && mode != MOVING_FORWARD) {
+ time_last_state_change = System.currentTimeMillis();
+ mode = MOVING_FORWARD;
+ orig_position.set(position);
+ } else if (e.getSource()==backwardB && mode != MOVING_BACK) {
+ time_last_state_change = System.currentTimeMillis();
+ mode = MOVING_BACK;
+ orig_position.set(position);
+ } else if (e.getSource()==reset) {
+ device.setNominalPositionAndOrientation();
+ }
+ }
+
+ public void mouseReleased( MouseEvent e ) {
+ mode = STILL;
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java
new file mode 100644
index 0000000..6c83eb8
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java
@@ -0,0 +1,70 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.virtual_input_device;
+
+import java.awt.Component;
+import javax.vecmath.Vector3f;
+
+// Classes that implement this interface must be a
+// subclass of java.awt.Component
+public interface PositionControls {
+
+ /**
+ * Get the position
+ */
+ public void getPosition( Vector3f pos);
+
+ /**
+ * Set the position
+ */
+ public void setPosition( Vector3f pos);
+
+ /**
+ * Increment added to position each time mouse is pressed
+ * or if the mouse is held down each time the Sensor is
+ * read
+ */
+ public void setStepRate( float stepRate );
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/README.txt b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/README.txt
new file mode 100644
index 0000000..f769dac
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/README.txt
@@ -0,0 +1,195 @@
+ Java 3D (TM) Input Device Driver Development Guide
+
+Topics
+
+ * Write Once, Run Anywhere (TM)
+ * Overview of the InputDevice and Sensor APIs
+ * Recipe for an Application Program that Uses Input Devices
+ * Location for Installation of Device Drivers
+ * Using a Preexistent Native Driver
+ * Package Naming Conventions
+ * Device Driver Constructor
+ * Driver Scheduling and Blocking Semantics
+
+
+Write Once, Run Anywhere
+
+Platform independence is the cornerstone of the Java (TM) platform.
+This vision now extends to external input devices as well. The
+overarching goal of the Java 3D input device architecture is to enable
+Java programs that use devices to run in a platform independent
+manner.
+
+We encourage developers to use Java APIs for their drivers. APIs such
+as the javax.comm API allow platform independent access to serial and
+parallel ports. However, even if a driver is partially written with
+native code, the Java 3D InputDevice interface is layered on top of the
+driver such that once the native portion of the driver has been
+installed into the local JRE, the application code is platform
+independent.
+
+In a future release, the Java 3D team is going to release a registry
+mechanism that will reside in the JRE as part of the Java 3D
+installation and allow registration of device drivers. The
+SimpleUniverse utility will be modified to allow querying of devices by
+generic characteristics, and will subsequently look up and instantiate
+the appropriate device driver registered with the registry mechanism.
+The Java 3D team also expects to release a set of generic mappings for
+devices. This will enable applications to count on the same behavior
+from different drivers for similar types of devices. There will also
+be personalized profiles that enable a user to specify device mappings
+for features like dominant hand preference and eye position.
+
+
+Overview of the InputDevice and Sensor APIs
+
+Java 3D abstracts the concept of a device via the InputDevice
+interface. The developer's implementation of the InputDevice interface
+is layered on top of the device driver. The device may be a real
+device such as a joystick or it may be a virtual device such as a piece
+of Java code that does transform calculations.
+
+A device sends data back to Java 3D by placing values into Sensor
+objects which the device code manages and updates. The Sensor class
+encapsulates a transform and a timestamp. The transform is specified
+in the TrackerBase coordinate system.
+
+Java 3D schedules calls to the device's pollAndProcessInput routine,
+which is a method in the InputDevice interface. This method is
+responsible for updating the devices sensor values. The sensors'
+values and time stamps are read by a user's behavior code and/or each
+frame (by the Java 3D implementation) when head tracking is enabled.
+There are several options for scheduling, and they are detailed in the
+InputDevice javadoc and in the section below entitled "Driver
+Scheduling and Blocking Semantics."
+
+Please read the javadocs for InputDevice and Sensor for more detailed
+information. There is also a sample program in the Java 3D release
+called VirtualInputDevice, which implements these concepts in Java code.
+
+
+Recipe for an Application Program that Uses Input Devices
+
+Please see the Java 3D example program in the examples directory called
+VirtualInputDevice for an example of using this code recipe:
+ 1) Implement the InputDevice interface with a class of your own
+ 2) Call the device's constructor from your main program
+ 3) Call initialize() on the device
+ 4) Call PhysicalEnvironment.addInputDevice(InputDevice) or if you are
+ using SimpleUniverse, call SimpleUniverse.getViewer().
+ getPhysicalEnvironment().addInputDevice(InputDevice)
+ 5) Assuming you want to modify the viewer's transform with the device:
+ add a WakeupOnElapsedFrames behavior to your scene graph that wakes
+ up every frame and in the processStimulus method modify the view
+ transform with the transform you pull out of Sensor.getRead.
+
+In a future release, it will be possible to replace steps 2, 3, & 4 with
+a single method call to the SimpleUniverse utility.
+
+
+Location for Installation of Device Drivers
+
+There are two suggested ways to package and distribute drivers.
+
+If a driver is written entirely in Java and if it is tightly coupled
+with a particular application without the expectation of reuse in other
+applications, then it should be bundled and distributed with the
+application itself.
+
+If a driver is not associated with any particular application program,
+if it contains any native code, or if it is expected to be used by more
+than one application program, then it should be installed directly into
+the end user's local JRE. It is expected that most drivers for real
+devices fall into this category. On the Solaris platform, the Java
+portion of the driver should be installed into jre/lib/ext as a
+uniquely named jar file and if there is native code it should be
+compiled into a shared object and installed into jre/lib/sparc. On the
+Win32 platform, the Java portion of the driver should be installed into
+jre\lib\ext as a uniquely named jar file and if there is native code it
+should be compiled into a standard dynamically linked library (dll) and
+installed into jre\bin.
+
+
+Using a Preexistent Native Driver
+
+It is possible to make a Java 3D driver out of a preexistent native
+driver. In order to do this, you need to create an InputDevice
+interface that uses JNI to access the associated native driver methods
+whenever the corresponding InputDevice interface method is called from
+Java 3D. The native portion of the driver must be installed into the
+target JRE.
+
+
+Package Naming Conventions
+
+All device drivers that are installed into the JRE should be part of a
+package that follows both standard Java and Java 3D naming
+conventions. For instance, an input device driver should be placed
+into a package called
+com.<company_name>.j3d.drivers.input.<device_name>. The package should
+be jarred up into a jar file that has a unique name.
+
+Any native .so or .dll files installed into the JRE should be uniquely
+named.
+
+
+Device Driver Constructor
+
+The constructor arguments for a device driver must be an array of
+strings. So a driver should have a single public constructor that
+takes an array of strings. The idea behind this requirement is that
+eventually the Java 3D registry will contain an array of string
+arguments to be sent to the device constructor at instantiation time.
+The SimpleUniverse API will also make a provision for optional String
+arguments to be added to the array of String arguments found in the
+registry.
+
+
+Driver Scheduling and Blocking Semantics
+
+When a device is registered with Java 3D via the
+PhysicalEnvironment.addInputDevice(InputDevice) method call,
+InputDevice.getProcessingMode() is called on the registered device.
+This method should return one of the three processing modes defined in
+the InputDevice interface: BLOCKING, NON_BLOCKING, and DEMAND_DRIVEN.
+
+ BLOCKING signifies that the driver for a device is a blocking driver
+ and that it should be scheduled for regular reads by Java 3D. A
+ blocking driver is defined as a driver that can cause the thread
+ accessing the driver (the Java 3D implementation thread calling the
+ pollAndProcessInput method) to block while the data is being accessed
+ from the driver.
+
+ NON_BLOCKING signifies that the driver for a device is a non-blocking
+ driver and that it should be scheduled for regular reads by Java 3D.
+ A non-blocking driver is defined as a driver that does not cause the
+ calling thread to block while data is being retrieved from the
+ driver. If no data is available from the device, pollAndProcessInput
+ should return without updating the sensor read value.
+
+ DEMAND_DRIVEN signifies that the Java 3D implementation should not
+ schedule regular reads on the sensors of this device; the Java 3D
+ implementation will only call pollAndProcessInput when one of the
+ device's sensors' getRead methods is called. A DEMAND_DRIVEN driver
+ must always provide the current value of the sensor on demand
+ whenever pollAndProcessInput is called. This means that DEMAND_DRIVEN
+ drivers are non-blocking by definition.
+
+It is important that you correctly classify your driver. If it is a
+NON_BLOCKING driver, most Java 3D implementations will choose to add
+inertia inside the scheduling thread to avoid starvation of the other
+Java 3D threads. If it is a BLOCKING driver, most Java 3D
+implementations will choose to spawn a separate scheduling thread for
+each BLOCKING device. If your driver is a DEMAND_DRIVEN driver, your
+driver must always provide the current value upon request along with
+the current time stamp.
+
+When running drivers with the Solaris operating system using the
+Solaris reference 1.2 JRE and green threads, you should be aware that
+there is a bug that forces all drivers to be BLOCKING. Thus, you
+should be careful to always use native threads on the Solaris reference
+1.2 JRE in order to get the expected behavior. This is not an issue
+with the Solaris 1.2 Performance JRE release, which is native threads
+only.
+
+
diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java
new file mode 100644
index 0000000..22fa5e3
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java
@@ -0,0 +1,73 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.virtual_input_device;
+
+import java.awt.Component;
+
+// Classes that implement this interface must be a subclass
+// of java.awt.Component
+
+public interface RotationControls {
+
+ /**
+ * Get the angle of Rotation around the X Axis
+ */
+ public abstract float getXAngle();
+
+ /**
+ * Get the angle or Rotation around the Y Axis
+ */
+ public abstract float getYAngle();
+
+ /**
+ * Get the angle or Rotation around the Z Axis
+ */
+ public abstract float getZAngle();
+
+ /**
+ * Reset angles to original angle.
+ */
+ public abstract void reset();
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java
new file mode 100644
index 0000000..4194599
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java
@@ -0,0 +1,72 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.virtual_input_device;
+
+import javax.media.j3d.*;
+import java.util.*;
+
+public class SensorBehavior extends Behavior {
+
+ private WakeupOnElapsedFrames conditions = new WakeupOnElapsedFrames(0);
+ private TransformGroup transformGroup;
+ private Sensor sensor;
+ private Transform3D transform = new Transform3D();
+
+ public SensorBehavior( TransformGroup tg, Sensor sensor ) {
+ transformGroup = tg;
+ this.sensor = sensor;
+ }
+
+ public void initialize() {
+ wakeupOn( conditions );
+ }
+
+ public void processStimulus( Enumeration criteria ) {
+ sensor.getRead( transform );
+ transformGroup.setTransform( transform );
+ wakeupOn( conditions );
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java
new file mode 100644
index 0000000..5d71a42
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java
@@ -0,0 +1,260 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.virtual_input_device;
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.*;
+import java.awt.event.*;
+
+public class VirtualInputDevice implements InputDevice {
+
+ private Vector3f position = new Vector3f();
+ private Transform3D newTransform = new Transform3D();
+ Sensor sensors[] = new Sensor[1];
+
+ // The wheel controls control the view platform orientation
+ private RotationControls rotControls;
+
+ // The button position controls control the view platform position
+ private PositionControls positionControls;
+
+ private Transform3D rotTransX = new Transform3D();
+ private Transform3D rotTransY = new Transform3D();
+ private Transform3D rotTransZ = new Transform3D();
+
+ private Vector3f initPos = new Vector3f();
+
+ private int processingMode;
+ private SensorRead sensorRead = new SensorRead();
+
+ // These are the settable parameters.
+ private boolean printvalues;
+ private int xscreeninitloc;
+ private int yscreeninitloc;
+ private int xscreensize;
+ private int yscreensize;
+ private float xobjinitloc;
+ private float yobjinitloc;
+ private float zobjinitloc;
+ private float xaxisrotinit;
+ private float yaxisrotinit;
+ private float zaxisrotinit;
+
+ /*
+ * Create a device, and use the string arguments in args to construct
+ * the device with user preferences.
+ */
+ public VirtualInputDevice( String[] args ) {
+
+ // default user-definable values
+ printvalues = false;
+ xscreeninitloc = 400;
+ yscreeninitloc = 0;
+ xscreensize = 400;
+ yscreensize = 200;
+ xobjinitloc = 0.0f;
+ yobjinitloc = 0.0f;
+ zobjinitloc = 2.2f;
+ xaxisrotinit = 0.0f;
+ yaxisrotinit = 0.0f;
+ zaxisrotinit = 0.0f;
+
+
+ for(int i=0 ; i<args.length ; i+=2) {
+ if(args[i] == null)
+ break;
+ else if(args[i] == "printvalues")
+ printvalues = (Boolean.valueOf(args[i+1])).booleanValue();
+ else if(args[i] == "xscreeninitloc")
+ xscreeninitloc = (Integer.valueOf(args[i+1])).intValue();
+ else if(args[i] == "yscreeninitloc")
+ yscreeninitloc = (Integer.valueOf(args[i+1])).intValue();
+ else if(args[i] == "xscreensize")
+ xscreensize = (Integer.valueOf(args[i+1])).intValue();
+ else if(args[i] == "yscreensize")
+ yscreensize = (Integer.valueOf(args[i+1])).intValue();
+ else if(args[i] == "xobjinitloc")
+ xobjinitloc = (Float.valueOf(args[i+1])).floatValue();
+ else if(args[i] == "yobjinitloc")
+ yobjinitloc = (Float.valueOf(args[i+1])).floatValue();
+ else if(args[i] == "zobjinitloc")
+ zobjinitloc = (Integer.valueOf(args[i+1])).floatValue();
+ }
+
+ if(printvalues == true) {
+ System.out.println("Initial values for VirtualInputDevice:");
+ System.out.println("xscreeninitloc = " + xscreeninitloc);
+ System.out.println("yscreeninitloc = " + yscreeninitloc);
+ System.out.println("xscreeninitsize = " + xscreensize);
+ System.out.println("yscreeninitsize = " + yscreensize);
+ System.out.println("xobjinitloc = " + xobjinitloc);
+ System.out.println("yobjinitloc = " + yobjinitloc);
+ System.out.println("zobjinitloc = " + zobjinitloc);
+ System.out.println("xaxisrotinit = " + xaxisrotinit);
+ System.out.println("yaxisrotinit = " + yaxisrotinit);
+ System.out.println("zaxisrotinit = " + zaxisrotinit);
+ }
+
+
+ // initialize the InputDevice GUI
+ Frame deviceFrame = new Frame();
+ deviceFrame.setSize(xscreensize,yscreensize);
+ deviceFrame.setLocation(xscreeninitloc, yscreeninitloc);
+ deviceFrame.setTitle("Virtual Input Device");
+ ButtonPositionControls positionControls;
+ // initialize position with initial x, y, and z position
+ positionControls = new ButtonPositionControls( xobjinitloc,
+ yobjinitloc, zobjinitloc);
+ WheelControls rotControls;
+ // initialize rotations with initial angles in radians)
+ rotControls = new WheelControls(xaxisrotinit, yaxisrotinit,
+ zaxisrotinit);
+ positionControls.setDevice (this);
+ Panel devicePanel = new Panel();
+ devicePanel.setLayout( new BorderLayout() );
+ devicePanel.add("East", positionControls );
+ devicePanel.add("West", rotControls );
+ deviceFrame.add( devicePanel );
+ deviceFrame.pack();
+ deviceFrame.setVisible(true);
+
+ initPos.set(xobjinitloc, yobjinitloc, zobjinitloc);
+
+ this.positionControls = positionControls;
+ this.rotControls = rotControls;
+
+ // default processing mode
+ processingMode = InputDevice.DEMAND_DRIVEN;
+
+ sensors[0] = new Sensor(this);
+ }
+
+ public void close() {
+ }
+
+ public int getProcessingMode() {
+ return processingMode;
+ }
+
+ public int getSensorCount() {
+ return sensors.length;
+ }
+
+ public Sensor getSensor( int sensorIndex ) {
+ return sensors[sensorIndex];
+ }
+
+ public boolean initialize() {
+ return true;
+ }
+
+ public void pollAndProcessInput() {
+
+ sensorRead.setTime( System.currentTimeMillis() );
+
+ rotTransX.rotX(-rotControls.getXAngle());
+ rotTransY.rotY(-rotControls.getYAngle());
+ rotTransZ.rotZ(-rotControls.getZAngle());
+
+ positionControls.getPosition(position);
+ newTransform.set(position);
+ newTransform.mul( rotTransX );
+
+ newTransform.mul(rotTransY);
+ newTransform.mul(rotTransZ);
+
+ sensorRead.set( newTransform );
+ sensors[0].setNextSensorRead( sensorRead );
+ }
+
+
+ public void processStreamInput() {
+ }
+
+
+ public void setNominalPositionAndOrientation() {
+
+ sensorRead.setTime( System.currentTimeMillis() );
+
+ rotTransX.rotX(xaxisrotinit);
+ rotTransY.rotY(yaxisrotinit);
+ rotTransZ.rotZ(zaxisrotinit);
+
+ position.set(initPos);
+
+ newTransform.set( position );
+
+ newTransform.mul(rotTransX);
+ newTransform.mul(rotTransY);
+ newTransform.mul(rotTransZ);
+
+ sensorRead.set( newTransform );
+ sensors[0].setNextSensorRead( sensorRead );
+ rotControls.reset();
+ positionControls.setPosition(initPos);
+ }
+
+
+
+ public void setProcessingMode( int mode ) {
+
+ // A typical driver might implement only one of these modes, and
+ // throw an exception when there is an attempt to switch modes.
+ // However, this example allows one to use any processing mode.
+
+ switch(mode) {
+ case InputDevice.DEMAND_DRIVEN:
+ case InputDevice.NON_BLOCKING:
+ case InputDevice.BLOCKING:
+ processingMode = mode;
+ break;
+ default:
+ throw new IllegalArgumentException("Processing mode must " +
+ "be one of DEMAND_DRIVEN, NON_BLOCKING, or BLOCKING");
+ }
+ }
+
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java
new file mode 100644
index 0000000..76136d3
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java
@@ -0,0 +1,136 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.virtual_input_device;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class VirtualInputDeviceTest extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph() {
+
+ BranchGroup objRoot = new BranchGroup();
+ TransformGroup objTrans = new TransformGroup();
+ objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+ objTrans.addChild(new ColorCube(0.2));
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
+ 0, 0,
+ 4000, 0, 0,
+ 0, 0, 0);
+ RotationInterpolator rotator =
+ new RotationInterpolator(rotationAlpha, objTrans, yAxis,
+ 0.0f, (float) Math.PI*2.0f);
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ rotator.setSchedulingBounds(bounds);
+ objTrans.addChild(rotator);
+ return objRoot;
+ }
+
+
+ public VirtualInputDeviceTest() {
+
+ }
+
+ public void init() {
+ // These are the string arguments given to the VirtualInputDevice
+ // constructor. These are settable parameters. Look in the
+ // VirtualInputDevice constructor for a complete list.
+ String[] args = new String[10];
+ args[0] = "printvalues";
+ args[1] = "true";
+ args[2] = "yscreeninitloc";
+ args[3] = "50";
+ args[4] = null;
+
+ InputDevice device = new VirtualInputDevice( args );
+
+ // now create the VirtualInputDeviceTest Canvas
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph();
+ u = new SimpleUniverse(c);
+
+ // The InputDevice must be initialized before registering it
+ // with the PhysicalEnvironment object.
+ device.initialize();
+
+ // Register the VirtualInputDevice with Java 3D
+ u.getViewer().getPhysicalEnvironment().addInputDevice( device );
+
+ TransformGroup viewTrans =
+ u.getViewingPlatform().getViewPlatformTransform();
+ SensorBehavior s = new SensorBehavior( viewTrans, device.getSensor(0) );
+ s.setSchedulingBounds( new BoundingSphere
+ ( new Point3d(0.0,0.0,0.0), Float.MAX_VALUE ));
+ scene.addChild( s );
+ u.addBranchGraph(scene);
+ }
+
+ public void destroy() {
+ u.cleanup();
+ }
+
+
+ public static void main(String[] args) {
+ new MainFrame(new VirtualInputDeviceTest(), 350, 350);
+ }
+}
diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java
new file mode 100644
index 0000000..b4af9ad
--- /dev/null
+++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java
@@ -0,0 +1,401 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+package org.jdesktop.j3d.examples.virtual_input_device;
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.event.*;
+
+public class WheelControls extends Canvas implements RotationControls, MouseMotionListener, MouseListener {
+
+ private final static int NONE=0;
+ private final static int SLIDE_Y=1;
+ private final static int SLIDE_X=2;
+ private final static int SLIDE_Z=3;
+
+ private int mode = NONE;
+
+ private Dimension size;
+ private int thickness;
+ private int diameter;
+ private int space;
+ private int pipSize;
+ private int pipOffset; // Amount pip is below wheel
+ private int margin; // Margin between edge of Canvas and
+ // controls
+
+ private Polygon yPip;
+ private Rectangle yBackClip;
+
+ private Polygon xPip;
+ private Rectangle xBackClip;
+
+ private Polygon zPip;
+
+ private Rectangle yArea;
+ private Rectangle xArea;
+ private Rectangle zArea;
+
+ private Point oldMousePos = new Point();
+
+ float yAngle = 0.0f;
+ float xAngle = 0.0f;
+ float zAngle = 0.0f;
+
+ float yOrigAngle;
+ float xOrigAngle;
+ float zOrigAngle;
+
+ float angleStep = (float)Math.PI/30.0f;
+
+ public WheelControls() {
+ this(0.0f, 0.0f, 0.0f);
+ }
+
+ public WheelControls( float rotX, float rotY, float rotZ ) {
+ size = new Dimension( 200, 200 );
+
+ xAngle = constrainAngle(rotX);
+ yAngle = constrainAngle(rotY);
+ zAngle = constrainAngle(rotZ);
+
+ yOrigAngle = yAngle;
+ xOrigAngle = xAngle;
+ zOrigAngle = zAngle;
+
+ setSizes();
+
+ yPip = new Polygon();
+ yPip.addPoint( 0, 0 );
+ yPip.addPoint( -pipSize/2, pipSize );
+ yPip.addPoint( pipSize/2, pipSize );
+
+ xPip = new Polygon();
+ xPip.addPoint(0,0);
+ xPip.addPoint( pipSize, -pipSize/2 );
+ xPip.addPoint( pipSize, pipSize/2 );
+
+ zPip = new Polygon();
+ zPip.addPoint( diameter/2, pipOffset );
+ zPip.addPoint( diameter/2-pipSize/2, pipOffset-pipSize );
+ zPip.addPoint( diameter/2+pipSize/2, pipOffset-pipSize );
+
+ addMouseListener( this );
+ addMouseMotionListener( this );
+ }
+
+ private void setSizes() {
+ margin = 10;
+ int width = size.width - margin*2;
+ thickness = width * 7 / 100;
+ diameter = width * 70 / 100;
+ space = width * 10 / 100;
+ pipSize = width * 7 / 100;
+
+ pipOffset = thickness/2;
+
+ }
+
+ public void paint( Graphics g ) {
+ Graphics2D g2 = (Graphics2D)g;
+
+ g.drawOval( margin,margin, diameter, diameter );
+ zArea = new Rectangle( margin, margin, diameter, diameter );
+ drawZPip( g2, zAngle );
+
+ g.drawRect( margin, margin+diameter+space,
+ diameter, thickness ); // Y Wheel
+ yArea = new Rectangle( margin, margin+diameter+space, margin+diameter,
+ thickness+pipOffset );
+ yBackClip = new Rectangle( margin-thickness,
+ margin+diameter+space+thickness,
+ margin+diameter+thickness*2, thickness );
+ drawYPip( g2, yAngle );
+
+ g.drawRect( margin+diameter+space, margin,
+ thickness, diameter ); // X Wheel
+ xArea = new Rectangle( margin+diameter+space, margin,
+ thickness+pipOffset, margin+diameter );
+ xBackClip = new Rectangle( margin+diameter+space+thickness,
+ margin-thickness,
+ thickness, margin+diameter+thickness*2 );
+ drawXPip( g2, xAngle );
+
+
+ }
+
+ public float getXAngle() {
+ return xAngle;
+ }
+
+ public float getYAngle() {
+ return yAngle;
+ }
+
+ public float getZAngle() {
+ return zAngle;
+ }
+
+
+ public void reset() {
+ // Overwrite the old pip
+ drawYPip( (Graphics2D)(this.getGraphics()),
+ yAngle );
+ yAngle = yOrigAngle;
+ // Draw the new Pip
+ drawYPip( (Graphics2D)(this.getGraphics()),
+ yAngle );
+
+ // Overwrite the old pip
+ drawXPip( (Graphics2D)(this.getGraphics()),
+ xAngle );
+ xAngle = xOrigAngle;
+ // Draw the new Pip
+ drawXPip( (Graphics2D)(this.getGraphics()),
+ xAngle );
+
+ drawZPip( (Graphics2D)(this.getGraphics()),
+ zAngle );
+
+ zAngle = zOrigAngle;
+
+ drawZPip( (Graphics2D)(this.getGraphics()),
+ zAngle );
+ oldMousePos.setLocation(0,0);
+ }
+
+
+ private void drawXPip( Graphics2D g2, float angle ) {
+ AffineTransform trans = new AffineTransform();
+ int y;
+ int xOrig = margin+diameter+space;
+ int yOrig = margin;
+ Color origColor = g2.getColor();
+
+ if (angle <= Math.PI) {
+ y = yOrig + diameter - (int)((Math.abs( angle-Math.PI/2 )/(Math.PI/2)) * diameter/2);
+ } else
+ y = yOrig + (int)((Math.abs( (angle-Math.PI*1.5) )/(Math.PI/2)) * diameter/2);
+
+ if (angle<Math.PI/2 || angle > Math.PI*1.5)
+ g2.setColor( Color.red ); // Infront of wheel
+ else {
+ g2.setColor( Color.black ); // Behind Wheel
+ g2.setClip( xBackClip );
+ }
+
+ g2.setXORMode( getBackground() );
+ trans.setToTranslation( xOrig+pipOffset, y );
+ g2.setTransform( trans );
+ g2.fillPolygon( xPip );
+
+ // Reset graphics context
+ trans.setToIdentity();
+ g2.setTransform( trans );
+ g2.setColor(origColor);
+ g2.setPaintMode();
+ }
+
+ private void drawYPip( Graphics2D g2, float angle ) {
+ AffineTransform trans = new AffineTransform();
+ int x;
+ int xOrig = margin;
+ int yOrig = margin+diameter+space;
+ Color origColor = g2.getColor();
+
+ if (angle <= Math.PI) {
+ x = xOrig + diameter - (int)((Math.abs( angle-Math.PI/2 )/(Math.PI/2)) * diameter/2);
+ } else
+ x = xOrig + (int)((Math.abs( (angle-Math.PI*1.5) )/(Math.PI/2)) * diameter/2);
+
+ if (angle<Math.PI/2 || angle > Math.PI*1.5)
+ g2.setColor( Color.red ); // Infront on wheel
+ else {
+ g2.setColor( Color.black ); // Behind Wheel
+ g2.setClip( yBackClip );
+ }
+
+ g2.setXORMode( getBackground() );
+ trans.setToTranslation( x, yOrig+pipOffset );
+ g2.setTransform( trans );
+ g2.fillPolygon( yPip );
+
+ // Reset graphics context
+ trans.setToIdentity();
+ g2.setTransform( trans );
+ g2.setColor(origColor);
+ g2.setPaintMode();
+ }
+
+ private void drawZPip( Graphics2D g2, float zAngle ) {
+ AffineTransform trans = new AffineTransform();
+ Color origColor = g2.getColor();
+
+ trans.translate( margin, margin );
+ trans.rotate(zAngle, diameter/2, diameter/2 );
+
+ g2.setXORMode( getBackground() );
+ g2.setTransform(trans);
+ g2.setColor( Color.red );
+ g2.fillPolygon( zPip );
+
+ // Reset graphics context
+ trans.setToIdentity();
+ g2.setTransform( trans );
+ g2.setColor( origColor );
+ g2.setPaintMode();
+ }
+
+ public Dimension getPreferredSize() {
+ return size;
+ }
+
+ public void setSize( Dimension d ) {
+ // Set size to smallest dimension
+ if (d.width<d.height)
+ size.width = size.height = d.width;
+ else
+ size.width = size.height = d.height;
+ setSizes();
+ }
+
+ public void mouseClicked( MouseEvent e ) {
+ }
+
+ public void mouseEntered( MouseEvent e ) {
+ }
+
+ public void mouseExited( MouseEvent e ) {
+ }
+
+ public void mousePressed( MouseEvent e ) {
+ if ( yArea.contains( e.getPoint() )) {
+ mode = SLIDE_Y;
+ oldMousePos = e.getPoint();
+ } else if (xArea.contains( e.getPoint() )) {
+ mode = SLIDE_X;
+ oldMousePos = e.getPoint();
+ } else if (zArea.contains( e.getPoint() )) {
+ mode = SLIDE_Z;
+ oldMousePos = e.getPoint();
+ }
+ }
+
+ public void mouseReleased( MouseEvent e ) {
+ mode = NONE;
+ }
+
+ public void mouseDragged( MouseEvent e ) {
+ Point pos = e.getPoint();
+
+ int diffX = pos.x - oldMousePos.x;
+ int diffY = pos.y - oldMousePos.y;
+
+ switch(mode) {
+ case NONE:
+ break;
+ case SLIDE_Y:
+ // Overwrite the old pip
+ drawYPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ yAngle );
+ if (diffX<0)
+ yAngle -= angleStep;
+ else if (diffX>0)
+ yAngle += angleStep;
+
+ yAngle = constrainAngle(yAngle);
+
+ // Draw the new Pip
+ drawYPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ yAngle );
+ oldMousePos = pos;
+ break;
+ case SLIDE_X:
+ // Overwrite the old pip
+ drawXPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ xAngle );
+ if (diffY<0)
+ xAngle -= angleStep;
+ else if (diffY>0)
+ xAngle += angleStep;
+
+ xAngle = constrainAngle(xAngle);
+
+ // Draw the new Pip
+ drawXPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ xAngle );
+ oldMousePos = pos;
+ break;
+ case SLIDE_Z:
+ drawZPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ zAngle );
+
+ if (diffX<0)
+ zAngle -= angleStep;
+ else if (diffX>0)
+ zAngle += angleStep;
+
+ zAngle = constrainAngle( zAngle );
+ drawZPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
+ zAngle );
+ oldMousePos = pos;
+ break;
+ default:
+ throw( new RuntimeException("Internal Error"));
+ }
+ }
+
+ public void mouseMoved( MouseEvent e ) {
+ }
+
+ /**
+ * Constrain angle to be 0<angle<2PI
+ */
+ private float constrainAngle( float angle ) {
+ if ( angle > (float)Math.PI*2 ) return angle-(float)Math.PI*2;
+ if ( angle < 0.0f) return angle+(float)Math.PI*2;
+ return angle;
+ }
+}