aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/org/jdesktop/j3d/examples
diff options
context:
space:
mode:
authorphil <[email protected]>2016-11-06 17:03:11 +1300
committerphil <[email protected]>2016-11-06 17:03:11 +1300
commitb519162cc27f380d36c5d2f779189628a42b3800 (patch)
tree05da9b1cb5045da85665cee0b0484257552dbe73 /src/main/java/org/jdesktop/j3d/examples
parent7d153738e397b6f9e7b51ea2d127fc55cdff6032 (diff)
move java into maven standard src/main/java and resources into
src/main/resources
Diffstat (limited to 'src/main/java/org/jdesktop/j3d/examples')
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/Resources.java90
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java328
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTestGL2ES2.java314
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java375
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java132
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixed.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java549
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixedGL2ES2.java530
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceTest.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceTest.java419
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/appearance/Tetrahedron.java113
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.form69
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.html26
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.java275
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometry.form37
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometry.java280
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometryGL2ES2.java263
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/collision/Box.java102
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/collision/CollisionDetector.java98
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollision.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollision.java272
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollisionGL2ES2.java254
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java327
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/README.txt142
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior.cfg149
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo.cfg113
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr.cfg212
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window.cfg89
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1.cfg98
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat.cfg134
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30.cfg99
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr.cfg222
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave.cfg171
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45.cfg110
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat.cfg135
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form217
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java359
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTestGL2ES2.java347
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrame.form25
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrame.java309
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrameGL2ES2.java294
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java193
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java254
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTestGL2ES2.java324
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/dot3/Dot3Demo.java548
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/dot3/MyCanvas.java247
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/dot3/TextureControlPanel.java232
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/BigCube.java139
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/Board.java2313
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java96
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/Cube.java132
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/Cylinder.java117
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/FourByFour.html15
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/FourByFour.java893
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/ID.java61
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java234
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/Poles.java80
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/Positions.java319
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/README.txt8
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/instructions.txt98
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/four_by_four/scores.txt20
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java282
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java255
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gears/Gear.java403
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gears/GearBox.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gears/GearBox.java408
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gears/GearTest.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gears/GearTest.java256
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gears/Shaft.java203
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gears/SpurGear.java563
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java185
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java552
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java584
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java331
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java561
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java528
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java367
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java255
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_compression/README.txt23
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_compression/cgview.java214
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java73
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/Cube.java311
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/EnvironmentMappingGLSL.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/EnvironmentMappingGLSL.java239
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ObjLoadGLSL.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ObjLoadGLSL.java424
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/PhongShadingGLSL.form138
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/PhongShadingGLSL.java478
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SamplerTestGLSL.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SamplerTestGLSL.java261
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ShaderTestGLSL.form266
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ShaderTestGLSL.java727
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SimpleShaderAppearance.java474
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SphereGLSL.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SphereGLSL.java388
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/VertexAttrTestGLSL.form203
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/VertexAttrTestGLSL.java435
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.frag56
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.vert64
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.frag68
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.vert75
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.frag61
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.vert46
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/fixed_function_shader.frag108
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/fixed_function_shader.vert142
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.frag54
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.vert158
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.frag67
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.vert68
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/phong.frag154
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/phong.vert89
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.frag49
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.vert75
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/simple.frag68
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/simple.vert189
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/toon.frag34
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/toon.vert19
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.frag52
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.vert70
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/wood.frag67
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/wood.vert43
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/EnvironmentMappingGLSL.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/EnvironmentMappingGLSL.java261
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java404
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form138
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java492
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/SamplerTestGLSL.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/SamplerTestGLSL.java278
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form266
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java707
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java384
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/VertexAttrTestGLSL.form203
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/VertexAttrTestGLSL.java428
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag55
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert42
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/dimple.frag61
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/dimple.vert42
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/envmap.frag61
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/envmap.vert25
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag50
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert100
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/multitex.frag61
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/phong.frag98
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/phong.vert56
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag48
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert58
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/simple.frag65
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/simple.vert131
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/toon.frag34
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/toon.vert19
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/vertexshader.vert61
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/wood.frag66
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/glsl_shader/wood.vert25
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java176
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverseGL2ES2.java161
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExample.form142
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExample.java195
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExampleGL2ES2.java175
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JInternalWorld.java232
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JInternalWorldGL2ES2.java211
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/lightwave/README.txt321
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/lightwave/Viewer.java206
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/lod/LOD.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/lod/LOD.java235
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java190
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java213
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/morphing/ColorCube.java122
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java122
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java124
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/morphing/Morphing.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/morphing/Morphing.java304
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java102
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java250
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/objload/ObjLoad.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/objload/ObjLoad.java325
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java107
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java231
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java79
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form82
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java274
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java200
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java309
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java329
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/overlay2d/Canvas3D2D.java60
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/overlay2d/Overlay2D.java201
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/package_info/PackageInfo.form45
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/package_info/PackageInfo.java139
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/package_info/QueryProperties.form44
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/package_info/QueryProperties.java203
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/BoltCG.java359
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/ColorCube.java122
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java122
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java124
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/Cube.java113
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/CubeIQA.java140
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/CubeQA.java137
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/GullCG.java578
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java182
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java179
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java271
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/IntersectTest.java251
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/MorphingBehavior.java102
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/OctahedronITFA.java117
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/OctahedronTFA.java116
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java102
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/PickTest.java442
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/PickText3DBounds.java254
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java273
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/RandomColorCube.java133
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java103
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/Tetrahedron.java117
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronILA.java108
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java99
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java83
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronITA.java106
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronLA.java106
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java96
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronPA.java73
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronTA.java104
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TickTockPicking.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/picking/TickTockPicking.java488
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java213
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java138
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java115
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java84
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form74
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java402
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java186
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java308
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/read_raster/ReadRaster.java236
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/AudioReverberate.java177
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundBehavior.java85
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundTest.form37
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundTest.java289
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/PointSoundBehavior.java89
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/PointSoundTest.form37
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/PointSoundTest.java318
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/ReverberateSound.java202
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/SimpleSounds.java262
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java187
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.form36
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java365
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGL2ES2.java363
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGL2ES3_Texture.java376
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGLSL_FFP.java361
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.frag66
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.vert19
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.frag96
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.vert31
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.frag105
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.vert35
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java631
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/stencil/StencilOutline.java524
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form82
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java259
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/text2d/MoverBehavior.java151
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/text2d/Text2DTest.java205
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/text3d/Text3DLoad.java308
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/texture/MultiTextureTest.java344
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/texture/TextureImage.java196
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/texture/TextureImageNPOT.java249
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java323
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java181
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java228
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java581
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java214
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java69
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/virtual_input_device/README.txt195
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java71
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java77
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java265
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java144
-rw-r--r--src/main/java/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java410
282 files changed, 54955 insertions, 0 deletions
diff --git a/src/main/java/org/jdesktop/j3d/examples/Resources.java b/src/main/java/org/jdesktop/j3d/examples/Resources.java
new file mode 100644
index 0000000..a50a188
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/Resources.java
@@ -0,0 +1,90 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ *
+ */
+public class Resources
+{
+
+ /**
+ * Do not construct an instance of this class.
+ */
+ private Resources()
+ {
+
+ }
+
+ /**
+ * Return the URL of the filename under the resources directory
+ */
+ public static URL getResource(String filename)
+ {
+ URL url = Resources.class.getClassLoader().getResource(filename);
+
+ if (url == null)
+ {
+ try
+ {
+ File f = new File(System.getProperty("user.dir") + "/src/" + filename);
+ if (!f.exists())
+ f = new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/" + filename);
+
+ url = f.toURL();
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ return url;
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java b/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java
new file mode 100644
index 0000000..7bd3d23
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java
@@ -0,0 +1,328 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.Container;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JApplet;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
+import org.jogamp.java3d.AlternateAppearance;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingLeaf;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.Bounds;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ Frame frame = new MainFrame(new AlternateAppearanceBoundsTest(), 800, 800);
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTestGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTestGL2ES2.java
new file mode 100644
index 0000000..c24b79a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTestGL2ES2.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.alternate_appearance;
+
+import java.awt.Container;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JApplet;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
+import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance;
+import org.jogamp.java3d.AlternateAppearance;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingLeaf;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.Bounds;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class AlternateAppearanceBoundsTestGL2ES2 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 AlternateAppearanceBoundsTestGL2ES2()
+ {
+ }
+
+ @Override
+ public void init()
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ 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);
+ }
+
+ @Override
+ public void destroy()
+ {
+ u.cleanup();
+ }
+
+ BranchGroup createSceneGraph()
+ {
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create an alternate appearance
+ otherApp = new SimpleShaderAppearance(true, false);
+ //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 SimpleShaderAppearance(true, false);
+ //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<Object>(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<Object>(colorVals);
+ altAppMaterialColor.addActionListener(this);
+ altAppMaterialColor.setSelectedIndex(2);
+ panel.add(new JLabel("Alternate Appearance MaterialColor"));
+ panel.add(altAppMaterialColor);
+
+ appMaterialColor = new JComboBox<Object>(colorVals);
+ appMaterialColor.addActionListener(this);
+ appMaterialColor.setSelectedIndex(1);
+ panel.add(new JLabel("Normal Appearance MaterialColor"));
+ panel.add(appMaterialColor);
+
+ return panel;
+
+ }
+
+ @Override
+ 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)
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ System.setProperty("j3d.displaylist", "false");
+ new MainFrame(new AlternateAppearanceBoundsTestGL2ES2(), 800, 800);
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java b/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java
new file mode 100644
index 0000000..bddbee8
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java
@@ -0,0 +1,375 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.Container;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JApplet;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
+import org.jogamp.java3d.AlternateAppearance;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ Frame frame = new MainFrame(new AlternateAppearanceScopeTest(), 800, 800);
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java b/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java
new file mode 100644
index 0000000..22f8553
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java
@@ -0,0 +1,132 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Primitive;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Vector3d;
+
+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/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixed.form b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixed.form
new file mode 100644
index 0000000..2440a43
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixed.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="AppearanceMixed"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java
new file mode 100644
index 0000000..943d387
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java
@@ -0,0 +1,549 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GraphicsContext3D;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.IndexedTriangleArray;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointAttributes;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class AppearanceMixed extends javax.swing.JFrame {
+
+ private java.net.URL texImage = null;
+ private java.net.URL bgImage = null;
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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;
+ }
+
+
+ private Canvas3D createUniverse() {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ // Create a MyCanvas3D using the preferred configuration
+ MyCanvas3D c = new MyCanvas3D(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 AppearanceMixed
+ */
+ public AppearanceMixed() {
+
+ if (bgImage == null) {
+ // the path to the image for an applet
+ bgImage = Resources.getResource("resources/images/bg.jpg");
+ if (bgImage == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+ }
+
+ if (texImage == null) {
+ // the path to the image for an applet
+ texImage = Resources.getResource("resources/images/stone.jpg");
+ if (texImage == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ System.exit(1);
+ }
+ }
+
+ // 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("AppearanceMixed");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new AppearanceMixed().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/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixedGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixedGL2ES2.java
new file mode 100644
index 0000000..e3ec631
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceMixedGL2ES2.java
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.appearance;
+
+import java.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GraphicsContext3D;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.IndexedTriangleArray;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointAttributes;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class AppearanceMixedGL2ES2 extends javax.swing.JFrame {
+
+ private java.net.URL texImage = null;
+ private java.net.URL bgImage = null;
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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 SimpleShaderAppearance(true, false);
+ 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 SimpleShaderAppearance [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 SimpleShaderAppearance(true, false);;
+
+ // 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:
+ {app = new SimpleShaderAppearance(true, true);;
+ // 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;
+ }
+
+
+ private Canvas3D createUniverse() {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ // Create a MyCanvas3D using the preferred configuration
+ MyCanvas3D c = new MyCanvas3D(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 AppearanceMixed
+ */
+ public AppearanceMixedGL2ES2() {
+
+ if (bgImage == null) {
+ // the path to the image for an applet
+ bgImage = Resources.getResource("resources/images/bg.jpg");
+ if (bgImage == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+ }
+
+ if (texImage == null) {
+ // the path to the image for an applet
+ texImage = Resources.getResource("resources/images/stone.jpg");
+ if (texImage == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ System.exit(1);
+ }
+ }
+
+ // 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("AppearanceMixed");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new AppearanceMixedGL2ES2().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/main/java/org/jdesktop/j3d/examples/appearance/AppearanceTest.form b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceTest.form
new file mode 100644
index 0000000..43cd90f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceTest.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="AppearanceTest"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/appearance/AppearanceTest.java b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceTest.java
new file mode 100644
index 0000000..0f0315a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/appearance/AppearanceTest.java
@@ -0,0 +1,419 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointAttributes;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class AppearanceTest extends javax.swing.JFrame {
+
+ private java.net.URL texImage = null;
+ private java.net.URL bgImage = null;
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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;
+ }
+
+ 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 AppearanceTest
+ */
+ public AppearanceTest() {
+
+ if (bgImage == null) {
+ // the path to the image for an applet
+ bgImage = Resources.getResource("resources/images/bg.jpg");
+ if (bgImage == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+ }
+
+ if (texImage == null) {
+ // the path to the image for an applet
+ texImage = Resources.getResource("resources/images/stone.jpg");
+ if (texImage == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ System.exit(1);
+ }
+ }
+
+ // 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("AppearanceTest");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new AppearanceTest().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/main/java/org/jdesktop/j3d/examples/appearance/Tetrahedron.java b/src/main/java/org/jdesktop/j3d/examples/appearance/Tetrahedron.java
new file mode 100644
index 0000000..625e7e4
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/appearance/Tetrahedron.java
@@ -0,0 +1,113 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.TexCoord2f;
+import org.jogamp.vecmath.Vector3f;
+
+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/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.form b/src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.form
new file mode 100644
index 0000000..a70fb22
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.form
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.0" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+ <AuxValues>
+ <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+ <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="pauseButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Pause"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pauseButtonActionPerformed"/>
+ </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="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="4" insetsRight="4" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JButton" name="resumeButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Resume"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="resumeButtonActionPerformed"/>
+ </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="0" 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/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.html b/src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.html
new file mode 100644
index 0000000..037c7c1
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>Simple 3D Applet</title>
+</head>
+<body>
+<applet code="org.jdesktop.applet.util.JNLPAppletLauncher"
+ width=500 height=400
+ archive="../../../../../../../dist/j3d-examples.jar,
+ http://download.java.net/media/applet-launcher/applet-launcher.jar,
+ http://download.java.net/media/java3d/webstart/release/j3d/latest/j3dcore.jar,
+ http://download.java.net/media/java3d/webstart/release/j3d/latest/j3dutils.jar,
+ http://download.java.net/media/java3d/webstart/release/vecmath/latest/vecmath.jar,
+ http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jar,
+ http://download.java.net/media/gluegen/webstart/gluegen-rt.jar">
+ <param name="codebase_lookup" value="false">
+ <param name="subapplet.classname" value="org.jdesktop.j3d.examples.applet3d.Applet3D$MyApplet">
+ <param name="subapplet.displayname" value="Java 3D Simple Applet">
+ <param name="jnlpNumExtensions" value="1">
+ <param name="jnlpExtension1" value="http://download.java.net/media/java3d/webstart/release/java3d-latest.jnlp">
+ <param name="progressbar" value="true">
+ <param name="noddraw.check" value="true">
+</applet>
+<p>Simple Java 3D Applet</p>
+</body>
+</html>
diff --git a/src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.java b/src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.java
new file mode 100644
index 0000000..1822cba
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/applet3d/Applet3D.java
@@ -0,0 +1,275 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+
+import javax.swing.JApplet;
+import javax.swing.JFrame;
+import javax.swing.JPopupMenu;
+import javax.swing.WindowConstants;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+/**
+ * Simple Java 3D program that can be run as an application or as an applet.
+ */
+public class Applet3D extends javax.swing.JPanel {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ private Alpha rotationAlpha1;
+ private Alpha rotationAlpha2;
+
+ public BranchGroup createSceneGraph() {
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+
+ // Create two TransformGroup nodes in series
+ TransformGroup objTrans1 = new TransformGroup();
+ objTrans1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans1);
+
+ // Create two TransformGroup nodes in series
+ TransformGroup objTrans2 = new TransformGroup();
+ objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans1.addChild(objTrans2);
+
+ // Create a simple Shape3D node; add it to the scene graph.
+ objTrans2.addChild(new ColorCube(0.4));
+
+ // Create 2 new Behavior objects that will perform the
+ // desired operations on the specified transforms and add
+ // them into the scene graph.
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ Transform3D yAxis1 = new Transform3D();
+ rotationAlpha1 = new Alpha(-1, 4000);
+
+ RotationInterpolator rotator1 =
+ new RotationInterpolator(rotationAlpha1, objTrans1, yAxis1,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator1.setSchedulingBounds(bounds);
+ objRoot.addChild(rotator1);
+
+ Transform3D yAxis2 = new Transform3D();
+ yAxis2.rotX(Math.PI/4.0);
+ rotationAlpha2 = new Alpha(-1, 13000);
+
+ RotationInterpolator rotator2 =
+ new RotationInterpolator(rotationAlpha2, objTrans2, yAxis2,
+ 0.0f, (float) Math.PI*2.0f);
+ rotator2.setSchedulingBounds(bounds);
+ objRoot.addChild(rotator2);
+
+ return objRoot;
+ }
+
+ private Canvas3D createUniverse(Container container) {
+ GraphicsDevice graphicsDevice;
+ if (container.getGraphicsConfiguration() != null) {
+ graphicsDevice = container.getGraphicsConfiguration().getDevice();
+ } else {
+ graphicsDevice =
+ GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+ }
+ GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
+ GraphicsConfiguration config = graphicsDevice.getBestConfiguration(template);
+
+ 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;
+ }
+
+ private void destroy() {
+ univ.cleanup();
+ }
+
+ /**
+ * Creates new form Applet3D
+ */
+ public Applet3D(Container container) {
+ // Initialize the GUI components
+ JPopupMenu.setDefaultLightWeightPopupEnabled(false);
+ initComponents();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ Canvas3D c = createUniverse(container);
+ drawingPanel.add(c, BorderLayout.CENTER);
+
+ // Create the content branch and add it to the universe
+ scene = createSceneGraph();
+ univ.addBranchGraph(scene);
+ }
+
+ // ----------------------------------------------------------------
+
+ // Applet framework
+
+ public static class MyApplet extends JApplet {
+ Applet3D mainPanel;
+
+ public void init() {System.setProperty("sun.awt.noerasebackground", "true");
+ setLayout(new BorderLayout());
+ mainPanel = new Applet3D(this);
+ add(mainPanel, BorderLayout.CENTER);
+ }
+
+ public void destroy() {
+ mainPanel.destroy();
+ }
+ }
+
+ // Application framework
+
+ private static class MyFrame extends JFrame {
+ MyFrame() {
+ setLayout(new BorderLayout());
+ setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ setTitle("Simple 3D Applet");
+ getContentPane().add(new Applet3D(this), BorderLayout.CENTER);
+ pack();
+ }
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new MyFrame().setVisible(true);
+ }
+ });
+ }
+
+ /** 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();
+ pauseButton = new javax.swing.JButton();
+ resumeButton = new javax.swing.JButton();
+ drawingPanel = new javax.swing.JPanel();
+
+ setLayout(new java.awt.BorderLayout());
+
+ guiPanel.setLayout(new java.awt.GridBagLayout());
+
+ pauseButton.setText("Pause");
+ pauseButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ pauseButtonActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
+ guiPanel.add(pauseButton, gridBagConstraints);
+
+ resumeButton.setText("Resume");
+ resumeButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ resumeButtonActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
+ guiPanel.add(resumeButton, gridBagConstraints);
+
+ add(guiPanel, java.awt.BorderLayout.NORTH);
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(500, 500));
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+ add(drawingPanel, java.awt.BorderLayout.CENTER);
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void resumeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resumeButtonActionPerformed
+ rotationAlpha1.resume();
+ rotationAlpha2.resume();
+ }//GEN-LAST:event_resumeButtonActionPerformed
+
+ private void pauseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pauseButtonActionPerformed
+ rotationAlpha1.pause();
+ rotationAlpha2.pause();
+ }//GEN-LAST:event_pauseButtonActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+ private javax.swing.JPanel guiPanel;
+ private javax.swing.JButton pauseButton;
+ private javax.swing.JButton resumeButton;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometry.form b/src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometry.form
new file mode 100644
index 0000000..9e76404
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometry.form
@@ -0,0 +1,37 @@
+<?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="BackgroundGeometry"/>
+ </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="opaque" type="boolean" value="false"/>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometry.java b/src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometry.java
new file mode 100644
index 0000000..18d2f5f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometry.java
@@ -0,0 +1,280 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseTranslate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseZoom;
+import org.jogamp.java3d.utils.geometry.Box;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class BackgroundGeometry extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+ private java.net.URL bgImage = null;
+ private BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ 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 |
+ Sphere.GENERATE_TEXTURE_COORDS_Y_UP, 45);
+ Appearance backgroundApp = sphereObj.getAppearance();
+ backGeoBranch.addChild(sphereObj);
+ bg.setGeometry(backGeoBranch);
+ objTrans.addChild(bg);
+
+ TextureLoader tex = new TextureLoader(bgImage,
+ new String("RGB"),
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP,
+ 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;
+ }
+
+ 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);
+
+ TransformGroup viewTrans =
+ univ.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);
+
+ return c;
+ }
+
+ /**
+ * Creates new form BackgroundGeometry
+ */
+ public BackgroundGeometry() {
+
+ if (bgImage == null) {
+ // the path to the image for an applet
+ bgImage = Resources.getResource("resources/images/bg.jpg");
+ if (bgImage == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+ }
+
+ // Initialize the GUI components
+ initComponents();
+
+ // Create the content branch and add it to the universe
+ scene = createSceneGraph();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ Canvas3D c = createUniverse();
+ drawingPanel.add(c, java.awt.BorderLayout.CENTER);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ scene.compile();
+
+ 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("BackgroundGeometry");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setOpaque(false);
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new BackgroundGeometry().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/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometryGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometryGL2ES2.java
new file mode 100644
index 0000000..709dd78
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/background/BackgroundGeometryGL2ES2.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.background;
+
+import java.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseTranslate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseZoom;
+import org.jogamp.java3d.utils.geometry.Box;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class BackgroundGeometryGL2ES2 extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+ private java.net.URL bgImage = null;
+ private BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ 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 |
+ Sphere.GENERATE_TEXTURE_COORDS_Y_UP, 45);
+ Appearance backgroundApp = new SimpleShaderAppearance(true, false);//sphereObj.getAppearance();
+ sphereObj.setAppearance(backgroundApp);
+ backGeoBranch.addChild(sphereObj);
+ bg.setGeometry(backGeoBranch);
+ objTrans.addChild(bg);
+
+ TextureLoader tex = new TextureLoader(bgImage,
+ new String("RGB"),
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP,
+ 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 SimpleShaderAppearance(true, false);
+
+ 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;
+ }
+
+ 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);
+
+ TransformGroup viewTrans =
+ univ.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);
+
+ return c;
+ }
+
+ /**
+ * Creates new form BackgroundGeometry
+ */
+ public BackgroundGeometryGL2ES2() {
+
+ if (bgImage == null) {
+ // the path to the image for an applet
+ bgImage = Resources.getResource("resources/images/bg.jpg");
+ if (bgImage == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+ }
+
+ // Initialize the GUI components
+ initComponents();
+
+ // Create the content branch and add it to the universe
+ scene = createSceneGraph();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ Canvas3D c = createUniverse();
+ drawingPanel.add(c, java.awt.BorderLayout.CENTER);
+
+ // Let Java 3D perform optimizations on this scene graph.
+ scene.compile();
+
+ 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("BackgroundGeometry");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setOpaque(false);
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ new BackgroundGeometryGL2ES2().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/main/java/org/jdesktop/j3d/examples/collision/Box.java b/src/main/java/org/jdesktop/j3d/examples/collision/Box.java
new file mode 100644
index 0000000..a472fb3
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/collision/Box.java
@@ -0,0 +1,102 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.vecmath.Point3d;
+
+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/main/java/org/jdesktop/j3d/examples/collision/CollisionDetector.java b/src/main/java/org/jdesktop/j3d/examples/collision/CollisionDetector.java
new file mode 100644
index 0000000..5d25810
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/collision/CollisionDetector.java
@@ -0,0 +1,98 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.WakeupOnCollisionEntry;
+import org.jogamp.java3d.WakeupOnCollisionExit;
+import org.jogamp.vecmath.Color3f;
+
+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/main/java/org/jdesktop/j3d/examples/collision/TickTockCollision.form b/src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollision.form
new file mode 100644
index 0000000..5a555b4
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollision.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="TickTockCollision"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/collision/TickTockCollision.java b/src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollision.java
new file mode 100644
index 0000000..8d1cba2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollision.java
@@ -0,0 +1,272 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+
+/**
+ * Simple Java 3D example program to display how collision work.
+ */
+public class TickTockCollision 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 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;
+ }
+
+ 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 TickTockCollision
+ */
+ public TickTockCollision() {
+ // 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("TickTockCollision");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new TickTockCollision().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/main/java/org/jdesktop/j3d/examples/collision/TickTockCollisionGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollisionGL2ES2.java
new file mode 100644
index 0000000..44db453
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/collision/TickTockCollisionGL2ES2.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+package org.jdesktop.j3d.examples.collision;
+
+import java.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.gl2es2pipeline.Cube;
+import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+
+/**
+ * Simple Java 3D example program to display how collision work.
+ */
+public class TickTockCollisionGL2ES2 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 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 Cube());
+
+ // 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 static 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 Cube(0.5 / 2, 5.0 / 2, 1.0 / 2);
+ objTrans.addChild(shape);
+
+ // Create a new ColoringAttributes object for the shape's
+ // appearance and make it writable at runtime.
+ Appearance app = new SimpleShaderAppearance();
+ shape.setAppearance(app);
+ RenderingAttributes ra = new RenderingAttributes();
+ ra.setIgnoreVertexColors(true);
+ app.setRenderingAttributes(ra);
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(0.6f, 0.3f, 0.0f);
+ app.setCapability(Appearance.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;
+ }
+
+ 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 TickTockCollision
+ */
+ public TickTockCollisionGL2ES2()
+ {
+ // 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("TickTockCollision");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ new TickTockCollisionGL2ES2().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/main/java/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java b/src/main/java/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java
new file mode 100644
index 0000000..9afa414
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java
@@ -0,0 +1,327 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Sensor;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.loaders.IncorrectFormatException;
+import org.jogamp.java3d.loaders.ParsingErrorException;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.objectfile.ObjectFile;
+import org.jogamp.java3d.utils.behaviors.sensor.Mouse6DPointerBehavior;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.universe.ConfiguredUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+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 ConfigObjLoad [-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() {System.setProperty("sun.awt.noerasebackground", "true");
+ if (filename == null) {
+ filename = Resources.getResource("resources/geometry/galleon.obj");
+ if (filename == null) {
+ System.err.println("resources/geometry/galleon.obj not found");
+ 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(null);
+ if(configURL == null) {
+ configURL = Resources.getResource("configured_universe/j3d1x1-window.cfg");
+ }
+
+ // 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new ConfigObjLoad(args);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/configured_universe/README.txt b/src/main/java/org/jdesktop/j3d/examples/configured_universe/README.txt
new file mode 100644
index 0000000..77e5a37
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/README.txt
@@ -0,0 +1,142 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.cfg
+ 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.cfg in the current directory, run
+
+ java -Dj3d.configURL=file:j3d1x2-rot30.cfg 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.cfg: single fullscreen desktop configuration.
+
+ j3d1x1-behavior.cfg: single fullscreen desktop configuration with a
+ configurable view platform behavior.
+
+ j3d1x1-stereo.cfg: single fullscreen desktop configuration with stereo
+ viewing.
+
+ j3d1x1-vr.cfg: single fullscreen desktop configuration with stereo viewing,
+ head tracker, and 6DOF mouse.
+
+ j3d1x1-window.cfg: single screen windowed desktop configuration.
+
+ j3d1x2-flat.cfg: dual-screen flat desktop configuration.
+
+ j3d1x2-rot30.cfg: dual-screen desktop configuration with each screen rotated
+ toward the other by 30 degrees about Y.
+
+ j3d1x3-cave.cfg: 3-projector configuration with screens to the left, front,
+ and right of the user.
+
+ j3d1x3-cave-vr.cfg: 3-projector configuration with screens to the left,
+ front, and right of the user. Includes head tracking and stereo
+ viewing.
+
+ j3d1x3-rot45.cfg: 3-screen desktop configuration with left and right screens
+ angled by 45 degrees from the center screen.
+
+ j3d2x2-flat.cfg: 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior.cfg
new file mode 100644
index 0000000..db56b2c
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior.cfg
@@ -0,0 +1,149 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo.cfg
new file mode 100644
index 0000000..959064c
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo.cfg
@@ -0,0 +1,113 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr.cfg
new file mode 100644
index 0000000..7da054d
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr.cfg
@@ -0,0 +1,212 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window.cfg
new file mode 100644
index 0000000..2496ee4
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window.cfg
@@ -0,0 +1,89 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1.cfg
new file mode 100644
index 0000000..a4977a3
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x1.cfg
@@ -0,0 +1,98 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat.cfg
new file mode 100644
index 0000000..155f1f7
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat.cfg
@@ -0,0 +1,134 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30.cfg
new file mode 100644
index 0000000..eccdb4b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30.cfg
@@ -0,0 +1,99 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr.cfg
new file mode 100644
index 0000000..f87887d
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr.cfg
@@ -0,0 +1,222 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave.cfg
new file mode 100644
index 0000000..88f86d8
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave.cfg
@@ -0,0 +1,171 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45.cfg
new file mode 100644
index 0000000..c84d548
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45.cfg
@@ -0,0 +1,110 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat.cfg b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat.cfg
new file mode 100644
index 0000000..8bc4cb0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat.cfg
@@ -0,0 +1,135 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form b/src/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form
new file mode 100644
index 0000000..b7d1376
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java b/src/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java
new file mode 100644
index 0000000..0095ca9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java
@@ -0,0 +1,359 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.RenderingAttributes;
+
+
+/**
+ *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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTestGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTestGL2ES2.java
new file mode 100644
index 0000000..ed34922
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/depth_func/DepthFuncTestGL2ES2.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.depth_func;
+
+import org.jogamp.java3d.RenderingAttributes;
+
+
+/**
+ *The goal of that example is to show the use of different ZBuffer comparison modes.
+ */
+public class DepthFuncTestGL2ES2 extends javax.swing.JFrame
+{
+
+ RenderFrameGL2ES2 rf;
+
+ /**
+ * Creates new form DepthFuncTest
+ */
+ public DepthFuncTestGL2ES2(){
+ 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()
+ {
+ @Override
+ 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()
+ {
+ @Override
+ 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()
+ {
+ @Override
+ 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()
+ {
+ @Override
+ 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 - Raster Ops are not availible in GL2ES2");
+ 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()
+ {
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ rotatingComboBoxActionPerformed(evt);
+ }
+ });
+
+ //Raster Ops are not availible in GL2ES2
+ //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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ DepthFuncTestGL2ES2 dpt = new DepthFuncTestGL2ES2();
+ dpt.rf = new RenderFrameGL2ES2( 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/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrame.form b/src/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrame.form
new file mode 100644
index 0000000..2edc4bb
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrame.java b/src/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrame.java
new file mode 100644
index 0000000..04d8a58
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrame.java
@@ -0,0 +1,309 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.OrderedGroup;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.ScaleInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.geometry.Box;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+
+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/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrameGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrameGL2ES2.java
new file mode 100644
index 0000000..7eaed6e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/depth_func/RenderFrameGL2ES2.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.depth_func;
+
+import java.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.gl2es2pipeline.Cube;
+import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.OrderedGroup;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.ScaleInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+public class RenderFrameGL2ES2 extends javax.swing.JFrame
+{
+
+ DepthFuncTestGL2ES2 dpt;
+
+ SimpleUniverse su;
+
+ RenderingAttributes staticWFBoxRA;
+ RenderingAttributes staticBoxRA;
+
+ RenderingAttributes rotatingBoxRA;
+
+ /** Creates new form RenderFrame */
+ public RenderFrameGL2ES2(DepthFuncTestGL2ES2 _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 SimpleShaderAppearance(true, false);
+ PolygonAttributes globalSpherePA = new PolygonAttributes();
+ globalSpherePA.setCullFace(PolygonAttributes.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(TransformGroup.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(TransformGroup.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 SimpleShaderAppearance(false, false);
+ Material rotBoxMat = new Material();
+ rotBoxMat.setDiffuseColor(.4f, .4f, .4f);
+ rotBoxApp.setMaterial(rotBoxMat);
+ Cube rotBox = new Cube(1.1f / 2, 1.1f / 2, 1.1f / 2);
+ rotBox.setAppearance(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();
+ //Raster Ops are not availible in GL2ES2
+ // rotatingBoxRA.setRasterOpEnable( true );
+ rotatingBoxRA.setCapability(RenderingAttributes.ALLOW_RASTER_OP_WRITE);
+ // rotatingBoxRA.setRasterOp( rotatingBoxRA.ROP_XOR );
+ rotBoxApp.setRenderingAttributes(rotatingBoxRA);
+
+ rotBox.setAppearance(rotBoxApp);
+ }
+
+ //adding static back face wireframe cube
+ {
+ Cube staticWFBoxBack = new Cube();
+ Appearance staticWFBoxApp = new SimpleShaderAppearance(false, false);
+ 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(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_WRITE);
+ staticWFBoxRA.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_WRITE);
+ staticWFBoxRA.setDepthTestFunction(RenderingAttributes.GREATER);
+ staticWFBoxRA.setDepthBufferWriteEnable(false);
+ staticWFBoxApp.setRenderingAttributes(staticWFBoxRA);
+ staticWFBoxBack.setAppearance(staticWFBoxApp);
+ staticWFBoxBack.setBounds(bounds);
+ staticObjectOG.addChild(staticWFBoxBack);
+ }
+
+ //adding static front face wireframe cube
+ {
+ Cube staticWFBox = new Cube();
+ Appearance staticWFBoxApp = new SimpleShaderAppearance(false, false);
+ 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
+ {
+ Cube staticBox = new Cube();
+ staticBox.setBounds(bounds);
+ Appearance boxApp = new SimpleShaderAppearance(false, false);
+ Material boxMat = new Material();
+ boxMat.setDiffuseColor(.7f, .7f, .7f);
+ boxApp.setMaterial(boxMat);
+ staticBoxRA = new RenderingAttributes();
+ staticBoxRA.setCapability(RenderingAttributes.ALLOW_DEPTH_TEST_FUNCTION_WRITE);
+ staticBoxRA.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_WRITE);
+ staticBoxRA.setDepthTestFunction(RenderingAttributes.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(TransformGroup.ALLOW_TRANSFORM_READ);
+ objectsTGRot.setCapability(TransformGroup.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)
+ {
+ //Raster Ops are not availible in GL2ES2
+ //rotatingBoxRA.setRasterOp( mode );
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java b/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java
new file mode 100644
index 0000000..3ba873f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java
@@ -0,0 +1,193 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.WakeupCondition;
+import org.jogamp.java3d.WakeupCriterion;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+import org.jogamp.java3d.WakeupOnElapsedTime;
+import org.jogamp.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/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.form b/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.form
new file mode 100644
index 0000000..22838dc
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.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="DistortGlyphTest"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java b/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java
new file mode 100644
index 0000000..cf88439
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java
@@ -0,0 +1,254 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.Font;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TexCoordGeneration;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseTranslate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseZoom;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+public class DistortGlyphTest extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ // 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(Resources.getResource("resources/images/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;
+ }
+
+ private Canvas3D createUniverse() {
+
+ // Create a Canvas3D using a nice configuration
+ Canvas3D c = new Canvas3D(getGraphicsConfig());
+
+ // 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 DistortGlyphTest2
+ */
+ public DistortGlyphTest() {
+ // 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("DistortGlyphTest");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new DistortGlyphTest().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/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTestGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTestGL2ES2.java
new file mode 100644
index 0000000..c92725a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTestGL2ES2.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.distort_glyph;
+
+import java.awt.Font;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+
+import org.jdesktop.j3d.examples.Resources;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.TexCoordGeneration;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseTranslate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseZoom;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+public class DistortGlyphTestGL2ES2 extends javax.swing.JFrame
+{
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ // 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 = makeShaderAppearance();
+ 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(Resources.getResource("resources/images/gold.jpg"), this).getTexture();
+ app.setTexture(txtr);
+ // done in shader see makeShaderAppearance() below
+ //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;
+ }
+
+ private Canvas3D createUniverse()
+ {
+
+ // Create a Canvas3D using a nice configuration
+ Canvas3D c = new Canvas3D(getGraphicsConfig());
+
+ // 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 DistortGlyphTest2
+ */
+ public DistortGlyphTestGL2ES2()
+ {
+ // 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("DistortGlyphTest");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run()
+ {
+ new DistortGlyphTestGL2ES2().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+ // End of variables declaration//GEN-END:variables
+
+ public static ShaderAppearance makeShaderAppearance()
+ {
+ ShaderAppearance app = new ShaderAppearance();
+ GLSLShaderProgram litTextureShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance litTextureShaderProgram";
+ }
+ };
+ litTextureShaderProgram.setShaders(makeShaders(vertShader, fragShader));
+ litTextureShaderProgram.setShaderAttrNames(new String[] { "EnvMap" });
+
+ app.setShaderProgram(litTextureShaderProgram);
+
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ shaderAttributeSet.put(new ShaderAttributeValue("EnvMap", new Integer(0)));
+ app.setShaderAttributeSet(shaderAttributeSet);
+ return app;
+ }
+
+ private static Shader[] makeShaders(String vertexProgram, String fragmentProgram)
+ {
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_VERTEX, vertexProgram) {
+ @Override
+ public String toString()
+ {
+ return "vertexProgram";
+ }
+ };
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_FRAGMENT, fragmentProgram) {
+ @Override
+ public String toString()
+ {
+ return "fragmentProgram";
+ }
+ };
+ return shaders;
+ }
+
+ public static String fragShader = "uniform sampler2D EnvMap;\n" + //
+ "varying vec2 texCoord0;\n" + //
+ "void main (void)\n" + //
+ "{\n" + //
+ " vec2 tc0 = texCoord0.xy;\n" + //
+ " vec3 color = vec3(texture2D(EnvMap, tc0));\n" + //
+ " gl_FragColor = vec4(color, 1.0);\n" + //
+ "}\n";
+
+ public static String vertShader = "attribute vec4 glVertex;\n" + //
+ "attribute vec3 glNormal; \n" + //
+ "uniform mat4 glModelViewProjectionMatrix;\n" + //
+ "uniform mat4 glModelViewMatrix;\n" + //
+ "uniform mat3 glNormalMatrix;\n" + //
+ "varying vec3 Normal;\n" + //
+ "varying vec2 texCoord0;\n" + //
+ "vec2 sphere_map(vec3 position, vec3 normal)\n" + //
+ "{\n" + //
+ " vec3 reflection = reflect(position, normal);\n" + //
+ " float m = 2.0 * sqrt(reflection.x * reflection.x + reflection.y * reflection.y + (reflection.z + 1.0) * (reflection.z + 1.0)); \n"
+ + //
+ " return vec2((reflection.x / m + 0.5), (reflection.y / m + 0.5));\n" + //
+ "}\n" + //
+ "void main()\n" + //
+ "{\n" + //
+ " Normal = normalize(vec3(glNormalMatrix * glNormal));\n" + //
+ " gl_Position = glModelViewProjectionMatrix * glVertex; \n" + //
+ " texCoord0 = sphere_map(normalize(vec3(glModelViewMatrix*glVertex)), Normal);\n" + //
+ "}\n"; //
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/dot3/Dot3Demo.java b/src/main/java/org/jdesktop/j3d/examples/dot3/Dot3Demo.java
new file mode 100644
index 0000000..8e5ec84
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/dot3/Dot3Demo.java
@@ -0,0 +1,548 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.dot3;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.image.BufferedImage;
+import java.util.Enumeration;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TexCoordGeneration;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.Texture2D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.TextureUnitState;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.geometry.GeometryInfo;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * This example program is contributed by Alessandro Borges
+ */
+
+/**
+ * <pre>
+ * DOT3 per-pixel lighting demo.
+ * It uses a Normal map and a Light map, both coded as independent textures.
+ * Each pixel color is a vector coded, where color range [0,255] is mapped
+ * as vector in range [-1.0,+1.0].
+ *
+ * A math operation called DOT3 applied to Light vector and Normal vector results
+ * a scalar value, interpreted as light intensity. This operation is made for each
+ * pixel on texture.
+ * Light Intensity = DOT3(light, normal);
+ *
+ * This technique allows complex lighting effects, as bumps, on low polygon count
+ * geometries.
+ * </pre>
+ *
+ */
+
+public class Dot3Demo extends JFrame {
+ // a external control panel for this demo
+ private TextureControlPanel ctrlPanel = null;
+ // default bounds used in this application
+ private BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
+ 100.0);
+ // TextureUnitStates used in this application
+ TextureUnitState tuLightMap;
+ TextureUnitState tuDOT3NormalMap;
+ TextureUnitState tuColor;
+
+ /** Where the TUs are applied **/
+ TextureUnitState[] tusArr;
+ /** appearance will be changed at runtime **/
+ Appearance appearance;
+ /** polygonAttributes will be changed at runtime **/
+ PolygonAttributes polygonAttributes;
+
+ // textures used
+ Texture textureColor;
+ Texture textureDOT3NormalMap;
+ Texture2D textureLightMap;
+ // needs for runtime updates on lightMap
+ ImageComponent2D imageLightMap;
+
+ // default texture names used
+ String textureColorName= "resources/images/wood.jpg";
+ String textureDOT3NormalMapName = "resources/images/Java3Ddot3.jpg";
+
+ /**
+ * Constructor.
+ */
+ public Dot3Demo() {
+ super("Java3D DOT3 demo");
+ try {
+ init();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void init() throws Exception {
+ this.setSize(new Dimension(400, 400));
+ this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JPanel mainPanel = new JPanel();
+ this.getContentPane().add(mainPanel, null);
+ mainPanel.setLayout(new BorderLayout());
+ // get default configuration for 3D
+ GraphicsConfiguration conf = SimpleUniverse.getPreferredConfiguration();
+ Canvas3D canvas = new Canvas3D(conf);
+ // create simpleUniverse
+ SimpleUniverse su = new SimpleUniverse(canvas);
+ // create sceneGraph and add it to universe
+ BranchGroup sceneGraph = createSceneGraph();
+ su.addBranchGraph(sceneGraph);
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ su.getViewingPlatform().setNominalViewingTransform();
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ su.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ // add the behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = su.getViewingPlatform();
+ viewingPlatform.setNominalViewingTransform();
+
+ // add orbit behavior to ViewingPlatform
+ OrbitBehavior orbit = new OrbitBehavior(canvas, OrbitBehavior.REVERSE_ALL |
+ OrbitBehavior.STOP_ZOOM);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+
+ mainPanel.add(canvas, BorderLayout.CENTER);
+ this.setVisible(true);
+ //create a control panel to user interaction
+ ctrlPanel = new TextureControlPanel(this);
+ ctrlPanel.setVisible(true);
+ ctrlPanel.setLocation(410,10);
+ }
+
+ /**
+ * loads all needed textures, and creates light map texture
+ */
+ private void loadTextures() {
+ try {
+ //java.net.URL urlColor = new java.net.URL("file:" + textureColorName);
+ //java.net.URL urlDot3 = new java.net.URL("file:" + textureDOT3NormalMapName);
+ java.net.URL urlColor = Resources.getResource(textureColorName);
+ java.net.URL urlDot3 = Resources.getResource(textureDOT3NormalMapName);
+
+ // loading textures
+ textureColor = new TextureLoader(urlColor,this).getTexture();
+ textureDOT3NormalMap = new TextureLoader(urlDot3,this) .getTexture();
+
+ // create Image for textureLightMap
+ BufferedImage image = new BufferedImage(256,256,BufferedImage.TYPE_INT_RGB);
+ Graphics2D graphics = image.createGraphics();
+ graphics.setPaint(new Color(130,130,250));
+ graphics.fillRect(0,0,image.getWidth(),image.getHeight());
+ graphics.dispose();
+
+ imageLightMap = new ImageComponent2D(ImageComponent2D.FORMAT_RGB,image,false,false);
+ imageLightMap.setCapability(ImageComponent2D.ALLOW_IMAGE_WRITE);
+ imageLightMap.setCapability(ImageComponent2D.ALLOW_IMAGE_READ);
+
+ //create textureLightMap with above imageLightMap
+ textureLightMap = new Texture2D(Texture2D.BASE_LEVEL,Texture2D.RGB,256,256);
+ textureLightMap.setImage(0,imageLightMap);
+ textureLightMap.setMagFilter(Texture2D.NICEST);
+ textureLightMap.setMinFilter(Texture2D.NICEST);
+
+ // application with update textureLightMap at runtime, so lets enable some caps
+ textureLightMap.setCapability(Texture2D.ALLOW_ENABLE_WRITE);
+ textureLightMap.setCapability(Texture2D.ALLOW_ENABLE_READ);
+ textureLightMap.setCapability(Texture2D.ALLOW_IMAGE_WRITE);
+ textureLightMap.setCapability(Texture2D.ALLOW_IMAGE_READ);
+
+ } catch(Exception e) {
+ System.err.println("Failed to load textures");
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * setup TextureUnitStates used in this demo. *
+ * @return
+ */
+ private TextureUnitState[] setupTextureUnitState() {
+ //texture Attributes for DOT3 normal map
+ TextureAttributes textAttDot3 = new TextureAttributes();
+
+
+ // lightMap uses TextureAttributes with default REPLACE mode
+ TextureAttributes textAttLightMap = new TextureAttributes();
+
+ TextureAttributes texAttColor = new TextureAttributes();
+ texAttColor.setTextureMode(TextureAttributes.COMBINE);
+
+ //CombineRgbMode could be also COMBINE_ADD or COMBINE_ADD_SIGNED, with
+ //different results
+ texAttColor.setCombineRgbMode(TextureAttributes.COMBINE_MODULATE);
+ // increase light depth effect
+ texAttColor.setCombineRgbScale(2);
+
+ textAttDot3.setTextureMode(TextureAttributes.COMBINE);
+ textAttDot3.setCombineRgbMode(TextureAttributes.COMBINE_DOT3);
+ textAttDot3.setCombineAlphaMode(TextureAttributes.COMBINE_DOT3);
+ textAttDot3.setTextureBlendColor(1.f,1.0f,1.0f,0.0f);
+ // increase light intesity
+ textAttDot3.setCombineRgbScale(2);
+ // setup functions
+ textAttDot3.setCombineRgbFunction(0,TextureAttributes.COMBINE_SRC_COLOR);
+ textAttDot3.setCombineRgbFunction(1,TextureAttributes.COMBINE_SRC_COLOR);
+ textAttDot3.setCombineRgbFunction(2,TextureAttributes.COMBINE_SRC_COLOR);
+ //combine with previous TUS, lightMap
+ textAttDot3.setCombineRgbSource(0,TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE);
+ textAttDot3.setCombineRgbSource(1,TextureAttributes.COMBINE_TEXTURE_COLOR );
+ textAttDot3.setCombineRgbSource(2,TextureAttributes.COMBINE_OBJECT_COLOR);
+
+ TexCoordGeneration tcg1=null;
+ // SphereMap tcg can add nice dynamic effects for curved surfaces, because it
+ // distributes texture like a light bean over geometry.
+ // It os not used in this demo, but you can try yourself at home
+ // with *complex* lightmaps, i.e., spherical light distributions,
+ // multi light sorces, degradee, waves,etc
+ /*
+ tcg1 = new TexCoordGeneration(TexCoordGeneration.SPHERE_MAP,
+ TexCoordGeneration.TEXTURE_COORDINATE_3);
+ */
+
+ // create TUS
+ tuLightMap = new TextureUnitState(textureLightMap,textAttLightMap,tcg1);
+ tuDOT3NormalMap = new TextureUnitState(textureDOT3NormalMap,textAttDot3,null);
+ tuColor = new TextureUnitState(textureColor,texAttColor,null);
+
+ // this TUS array is used by geometry at runtime
+ TextureUnitState[] tus = new TextureUnitState[3];
+ tus[0] = tuLightMap;
+ tus[1] = tuDOT3NormalMap;
+ tus[2] = tuColor;
+ // enable texture units for read/write at runtime
+ for (int i = 0; i < tus.length; i++) {
+ tus[i].setCapability(TextureUnitState.ALLOW_STATE_WRITE);
+ tus[i].setCapability(TextureUnitState.ALLOW_STATE_READ);
+ }
+
+ return tus;
+ }
+
+ /**
+ * creates a single Quad geometry with 4 TextureCoordinateMaps, for multitexture use.<br>
+ * Dimension is scale*(2m , 1m)
+ * @param scale a scale for this quad
+ * @return quad geometry for multitexture use
+ */
+ private GeometryArray createGeometry(float scale) {
+ // vertex coordinates
+ float[] verts = { 2.0f, -1.0f, 0.0f,
+ 2.0f, 1.0f, 0.0f,
+ -2.0f, 1.0f, 0.0f,
+ -2.0f, -1.0f, 0.0f };
+ // 2D texture Coords - each texture unit will use one set of this
+ float[] texCoords = { 1.0f, 0.0f,
+ 1.0f, 1.0f,
+ 0.0f, 1.0f,
+ 0.0f, 0.0f};
+ // all texture units will use texCoords from unit 0
+ int[] texCoordSetMap = {0,0,0,0};
+ // normals
+ Vector3f normal = new Vector3f( 0.0f, 0.0f, 1.0f);
+ Vector3f[] normals = { normal, normal, normal, normal} ;
+ // resize quad dimension
+ for(int i = 0;i<verts.length;i++) {
+ verts[i] *= scale;
+ }
+ // create geometry using GeometryInfo
+ GeometryInfo gi = new GeometryInfo(GeometryInfo.QUAD_ARRAY);
+
+ gi.setCoordinates(verts);
+ gi.setNormals(normals);
+ // preparing for multitexture
+ // To get up to 4 TUS, it needs 4 sets of 2D texture
+ gi.setTextureCoordinateParams(4, 2);
+ gi.setTexCoordSetMap(texCoordSetMap);
+
+ // this demo needs just 3 TUS, but geometry
+ // is prepared for up to 4 TUS stages
+ gi.setTextureCoordinates(0,texCoords);
+ gi.setTextureCoordinates(1,texCoords);
+ gi.setTextureCoordinates(2,texCoords);
+ gi.setTextureCoordinates(3,texCoords);
+
+ return gi.getGeometryArray();
+ }
+
+ /**
+ * Creates scenegraphs
+ * @return a BranchGroup with all needed objects in scene
+ */
+ private BranchGroup createSceneGraph() {
+ BranchGroup bgRoot = new BranchGroup();
+ CheckNewLightMapBehavior checkNewLightMapBehavior = new CheckNewLightMapBehavior();
+
+ bgRoot.addChild(checkNewLightMapBehavior);
+
+ // a blue background
+ Background background = new Background(0.4f,0.4f,0.8f);
+ background.setApplicationBounds(bounds);
+ bgRoot.addChild(background);
+
+ AmbientLight alit = new AmbientLight(true,new Color3f(0.4f,0.4f,0.4f));
+ bgRoot.addChild(alit);
+
+ // Set up some directional lights
+ // DOT3 doesnot need light, because it is a perpixel lighting technique
+ //but we add this lights to show
+ // geometry when using non-DOT3 lighting, as color texture only and
+ // light map texture mode
+ 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);
+ bgRoot.addChild(light1);
+
+ DirectionalLight light2
+ = new DirectionalLight(light2Color, light2Direction);
+ light2.setInfluencingBounds(bounds);
+ bgRoot.addChild(light2);
+
+ //loading color and DOT3 normal map textures from disk,
+ //and creating light map at runtime
+ loadTextures();
+ //our single Quad geometry, enabled for multitexture
+ GeometryArray geo = createGeometry(0.4f);
+ // a appearance for our geometry
+ appearance = new Appearance();
+ // polygon and texture unit will be updated at runtime
+ // so we must enabled read/write operations for then
+ appearance.setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_READ);
+ appearance.setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_WRITE);
+ appearance.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_READ);
+ appearance.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE);
+
+ //use a default material. It is necessary when running
+ //on non per-pixel lighting mod, i.e., using non DOT3 textures
+ appearance.setMaterial(new Material());
+
+ polygonAttributes = new PolygonAttributes();
+ polygonAttributes.setCapability(PolygonAttributes.ALLOW_MODE_WRITE);
+ polygonAttributes.setCullFace(PolygonAttributes.CULL_NONE);
+
+ appearance.setPolygonAttributes(polygonAttributes);
+
+ // uses a TUS dot3 enabled
+ tusArr = setupTextureUnitState();
+ appearance.setTextureUnitState(tusArr);
+
+ // joining geometry and appearance in a shape3D
+ Shape3D shape3D = new Shape3D(geo,appearance);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
+ shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
+
+ bgRoot.addChild(shape3D);
+
+ bgRoot.compile();
+
+ return bgRoot;
+ }
+
+ /**
+ * Toggles wireframe mode
+ * @param mode true for wireframe, false for fill polygon
+ */
+ public void setWireframeMode(boolean mode) {
+ if(mode)
+ polygonAttributes.setPolygonMode(PolygonAttributes.POLYGON_LINE);
+ else
+ polygonAttributes.setPolygonMode(PolygonAttributes.POLYGON_FILL);
+ }
+
+
+ /**
+ * This method togles on/off textures and updates TextureUnitState in correct Order.
+ * Some video drivers does not accept TextureUnitState arrays with null values among
+ * non-null values
+ * @param showLightMap togles LightMap texture
+ * @param showDot3 togles DOT3 Normal texture
+ * @param showColor togles Color texture
+ */
+ public void showTextures(boolean showLightMap, boolean showDot3, boolean showColor) {
+ int bitSet = 0;
+ bitSet |= showLightMap ? 4 : 0;
+ bitSet |= showDot3 ? 2 : 0;
+ bitSet |= showColor ? 1 : 0;
+
+ tusArr[0] = null;
+ tusArr[1] = null;
+ tusArr[2] = null;
+
+ switch (bitSet) {
+ case 7: { //all bit == all tus
+ tusArr[0] = tuLightMap;
+ tusArr[1] = tuDOT3NormalMap;
+ tusArr[2] = tuColor;
+ }
+ break;
+ case 6: { //no Color
+ tusArr[0] = tuLightMap;
+ tusArr[1] = tuDOT3NormalMap;
+ }
+ break;
+ case 5: { //no Dot3
+ tusArr[0] = tuLightMap;
+ tusArr[1] = tuColor;
+ }
+ break;
+ case 4: { //lightMap only
+ tusArr[0] = tuLightMap;
+ }
+ break;
+ case 3: { //no LightMap
+ tusArr[0] = tuDOT3NormalMap;
+ tusArr[1] = tuColor;
+ }
+ break;
+ case 2: { //Dot3 Only
+ tusArr[0] = tuDOT3NormalMap;
+ }
+ break;
+ case 1: { // Color Only
+ tusArr[0] = tuColor;
+ }
+ break;
+ default: { // case 0, no textures shows at all
+ }
+ break;
+ }
+ appearance.setTextureUnitState(tusArr);
+ }
+
+ /**
+ * updates LightMap texture.
+ * This method is called from checkNewLightMapBehavior
+ * @param image new image to be applied
+ */
+ public void updateLighMap(BufferedImage image) {
+ imageLightMap.setSubImage(image,image.getWidth(),image.getHeight(),0,0,0,0);
+ }
+
+ private BufferedImage tempImage;
+ private boolean lockTempImage = false;
+
+
+ /**
+ * main method
+ * @param args
+ */
+ public static void main(String[] args) {System.setProperty("sun.awt.noerasebackground", "true");
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ new Dot3Demo();
+ }
+ });
+
+ }
+
+ /**
+ * A internal class to check if there is a new Light Map to be applied
+ */
+ class CheckNewLightMapBehavior extends Behavior {
+ WakeupOnElapsedFrames wakeup = new WakeupOnElapsedFrames(0);
+
+ public CheckNewLightMapBehavior() {// auto enable and set schedulling bounds
+ setEnable(true);
+ setSchedulingBounds(bounds);
+ }
+
+ public void initialize() {
+ wakeupOn(wakeup);
+ }
+
+ public void processStimulus(Enumeration e) {
+ // check if there are a new light map ready to use
+ if (ctrlPanel.hasTextureImageReady()) {
+ updateLighMap(ctrlPanel.getTextureImage());
+ }
+ //wake up on next frame
+ wakeupOn(wakeup);
+ }
+ }
+
+}
+
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/dot3/MyCanvas.java b/src/main/java/org/jdesktop/j3d/examples/dot3/MyCanvas.java
new file mode 100644
index 0000000..f5f4cfc
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/dot3/MyCanvas.java
@@ -0,0 +1,247 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.dot3;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+
+import javax.swing.JPanel;
+import javax.swing.event.MouseInputListener;
+
+/**
+ * A mouse interactive canvas for lightMap image
+ */
+public class MyCanvas extends JPanel implements MouseInputListener {
+ BufferedImage lightMask = null;
+ BufferedImage textureImage = null;
+ Graphics2D gr = null;
+ Point location = new Point();
+ // default color light map
+ Color bgColor = new Color(147, 147, 147);
+
+ int x = 0;
+ int y = 0;
+ int z = 142;
+ // texture image size
+ private static final int textureSize = 256;
+ boolean mouseOut = true;
+ //flag about image is ready or not for use
+ boolean imageReady = false;
+ // allows mask be dragged with mouse
+ boolean dragMask = false;
+ boolean updateLightDir = false;
+ boolean updateMaskPosition = false;
+
+ /**
+ * Creates a MyCanvas object with a image lightMask.
+ * Also creates a default ImageLight map
+ * @param mask light lightMask used
+ */
+ public MyCanvas(BufferedImage mask) {
+ super();
+ this.lightMask = mask;
+ // create a light map
+ setTextureImage(new BufferedImage(textureSize, textureSize,
+ BufferedImage.TYPE_INT_RGB));
+ // Graphics used to update lightmap
+ gr = getTextureImage().createGraphics();
+
+ Dimension dimSize = new Dimension(textureSize, textureSize);
+ // lock size
+ this.setSize(dimSize);
+ this.setMaximumSize(dimSize);
+ this.setMinimumSize(dimSize);
+
+ this.setDoubleBuffered(true);
+ this.setOpaque(true);
+ this.addMouseMotionListener(this);
+ this.addMouseListener(this);
+ }
+
+ /**
+ * Handles mouse click event.
+ * Get mouse coords call repaint for proper imageLight update
+ * @param ev mouse event
+ */
+ public void mouseClicked(MouseEvent ev) {
+ x = ev.getX();
+ y = this.getHeight() - ev.getY();
+ updateLightDir = true;
+ repaint();
+ }
+
+ public void mousePressed(MouseEvent e) {
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ }
+
+ /**
+ * Handles mouse drag event.
+ * get current mouse position and calls repaint for proper imageLight update
+ * @param ev
+ */
+ public void mouseDragged(MouseEvent ev) {
+ if (!mouseOut) {
+ x = ev.getX();
+ y = this.getHeight() - ev.getY();
+
+ //changes lightDir
+ if ((ev.getModifiers()& MouseEvent.BUTTON1_MASK) ==
+ MouseEvent.BUTTON1_MASK) {
+ updateLightDir = true;
+ updateMaskPosition = false;
+ }
+ //updates light mask position
+ if ((ev.getModifiers() & ev.BUTTON2_MASK) == ev.BUTTON2_MASK ||
+ (ev.getModifiers() & ev.BUTTON3_MASK) == ev.BUTTON3_MASK) {
+ updateLightDir = false;
+ updateMaskPosition = true;
+ }
+ repaint();
+ }
+ }
+
+ public void mouseMoved(MouseEvent ev) {
+ // disable updates on lightMap
+ updateLightDir = false;
+ updateMaskPosition = false;
+ }
+
+ public void mouseEntered(MouseEvent e) {
+ mouseOut = false;
+ }
+
+ public void mouseExited(MouseEvent e) {
+ mouseOut = true;
+ }
+
+ /**
+ * updates imageLight using current setings
+ * @param g
+ */
+ public void paintComponent(Graphics g) {
+ imageReady = false;
+ Graphics2D g2d = (Graphics2D)g;
+
+ // ligthDir has changed, we must update bgColor li
+ if(updateLightDir) {
+ int blue = bgColor.getBlue();
+ //clamp values to 255
+ y = y>255?255:y;
+ x = x>255?255:x;
+ bgColor = new Color(y,x,blue);
+ }
+ // paint lightMap
+ gr.setColor(bgColor);
+ gr.fillRect(0, 0, textureSize, textureSize);
+
+ // draw mask on mouse position
+ if (dragMask || updateMaskPosition) {
+ int maskWH = lightMask.getWidth()/2;
+ int mx = x - maskWH ;
+ int my = textureSize - y - maskWH ; // y value is inverted
+ // clamp mouse position, to avoid drawing outside imageLigh bounds
+ mx = mx > textureSize ? textureSize : mx;
+ my = my > textureSize ? textureSize : my;
+ // draw light mask
+ gr.drawImage(lightMask, mx, my, this);
+ }
+
+ g2d.drawImage(getTextureImage(), 0, 0, this);
+ imageReady = true;
+ }
+
+ /**
+ *
+ * @return true if exists a new texture image available
+ */
+ public boolean hasTextureImageReady() {
+ return imageReady;
+ }
+
+ /**
+ * Returns a texture image.<br>
+ * You can avoid calling the same image several times
+ * by checking hasTextureImageReady() first.
+ * @return latest texture image available
+ */
+ public BufferedImage getTextureImage() {
+ // sign as texture used for next call;
+ imageReady = false;
+ //return image
+ return textureImage;
+ }
+
+
+ public Image getMask() {
+ return lightMask;
+ }
+
+ public void setLightMask(BufferedImage mask) {
+ this.lightMask = mask;
+ }
+
+ public Color getBgColor() {
+ return bgColor;
+ }
+
+ public void setBgColor(Color bgColor) {
+ this.bgColor = bgColor;
+ }
+
+ public void setTextureImage(BufferedImage textureImage) {
+ this.textureImage = textureImage;
+ }
+
+
+}
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/dot3/TextureControlPanel.java b/src/main/java/org/jdesktop/j3d/examples/dot3/TextureControlPanel.java
new file mode 100644
index 0000000..0aef5f0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/dot3/TextureControlPanel.java
@@ -0,0 +1,232 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.dot3;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.net.URL;
+
+import javax.imageio.ImageIO;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.jdesktop.j3d.examples.Resources;
+
+/**
+ * A control panel for Dot3Demo.
+ * It enables user change LightMap, enables/disables textures units states
+ * and toggles geometry wireframes on/off
+ */
+public class TextureControlPanel extends JDialog implements ChangeListener,
+ ActionListener {
+ /** renderer for lightMap, with support for mouse interaction **/
+ private MyCanvas canvas = null;
+ /** file name for light mask */
+ private String maskFileName = "resources/images/mask.png";
+ /** a slider to change Z light direction, i.e, blue channel */
+ private JSlider sliderZ = new JSlider(JSlider.HORIZONTAL, 1, 255, 142);
+ /** target demo instance to be controled **/
+ private Dot3Demo dot3DemoFrame;
+
+ // some checkboxes for user interaction
+ private JCheckBox cbWireframe = new JCheckBox("Show as Wireframe", false);
+ private JCheckBox cbDot3 = new JCheckBox("Show Dot3 texture", true);
+ private JCheckBox cbShowLightMap = new JCheckBox("Show LightMap texture", true);
+ private JCheckBox cbShowColor = new JCheckBox("Show Color texture", true);
+ private JCheckBox cbDragLightMask = new JCheckBox("Drag light mask");
+
+ private JLabel lbSliderZ = new JLabel();
+ private JLabel lbMessage = new JLabel();
+
+ public TextureControlPanel(Dot3Demo owner) {
+ super(owner);
+ dot3DemoFrame = owner;
+ try {
+ URL url = Resources.getResource(maskFileName);
+ BufferedImage mask = ImageIO.read(url);
+ canvas = new MyCanvas(mask);
+ init();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public TextureControlPanel() {
+ this(null);
+ }
+
+ /**
+ * Creates Graphical User Interface
+ * @throws Exception
+ */
+ private void init() throws Exception {
+ Dimension dim = new Dimension(540, 350);
+ this.setSize(dim);
+ this.setPreferredSize(dim);
+ this.setTitle("DOT3Demo Texture Control Panel");
+ this.setLayout(new BorderLayout());
+
+ JPanel panel = new JPanel();
+ this.getContentPane().add(panel, BorderLayout.CENTER);
+ canvas.setSize(new Dimension(256, 256));
+ canvas.setBounds(new Rectangle(40, 40, 256, 256));
+
+ sliderZ.setBounds(new Rectangle(310, 190, 205, 45));
+ sliderZ.setPaintTicks(true);
+ sliderZ.setMajorTickSpacing(63);
+
+ cbWireframe.setBounds(new Rectangle(310, 50, 200, 20));
+ cbWireframe.setToolTipText("Toggles Wireframe");
+ cbDot3.setBounds(new Rectangle(310, 70, 150, 20));
+ cbShowLightMap.setBounds(new Rectangle(310, 90, 200, 20));
+ cbShowLightMap.setToolTipText("Toggles DOT3 texture");
+ cbShowColor.setBounds(new Rectangle(310, 110, 200, 20));
+ cbShowColor.setToolTipText("Toggles Color texture");
+
+ panel.setLayout(null);
+
+ cbDragLightMask.setBounds(new Rectangle(310, 135, 200, 20));
+ lbMessage.setText("<html>Left-click and drag to change Light Direction." +
+ " Right-click and drag to move spotlight.</html>");
+ lbMessage.setBounds(new Rectangle(305, 245, 210, 60));
+
+ lbSliderZ.setText("Blue Light (Dot3 Z axis)");
+ lbSliderZ.setBounds(new Rectangle(310, 170, 210, 15));
+ lbSliderZ.setToolTipText("changes light intensity from Z axis");
+
+ panel.add(cbDragLightMask, null);
+ panel.add(lbMessage, null);
+ panel.add(lbSliderZ, null);
+ panel.add(sliderZ, null);
+ panel.add(canvas, null);
+ panel.add(cbShowColor, null);
+ panel.add(cbShowLightMap, null);
+ panel.add(cbWireframe, null);
+ panel.add(cbDot3, null);
+
+ sliderZ.addChangeListener(this);
+
+ cbDot3.addActionListener(this);
+ cbShowColor.addActionListener(this);
+ cbShowLightMap.addActionListener(this);
+ cbWireframe.addActionListener(this);
+ cbDragLightMask.addActionListener(this);
+ }
+
+ public void stateChanged(ChangeEvent ev) {
+ JComponent source = (JComponent)ev.getSource();
+ if (sliderZ.equals(source)) {
+ int xVal = canvas.getBgColor().getRed();
+ int yVal = canvas.getBgColor().getGreen();
+ int zVal = sliderZ.getValue();
+ Color ligtDir = new Color(xVal, yVal, zVal);
+ updateLightMap(ligtDir) ;
+ }
+ }
+
+ private void updateLightMap(Color ligtDir) {
+ canvas.setBgColor(ligtDir);
+ canvas.repaint();
+ dot3DemoFrame.updateLighMap(canvas.getTextureImage());
+ }
+
+
+ public void actionPerformed(ActionEvent ev) {
+ JComponent source = (JComponent)ev.getSource();
+ if (cbWireframe.equals(source)) {
+ dot3DemoFrame.setWireframeMode(cbWireframe.isSelected());
+ } else
+ if (cbDot3.equals(source)
+ || cbShowColor.equals(source)
+ || cbShowLightMap.equals(source)) {
+ dot3DemoFrame.showTextures(cbShowLightMap.isSelected(),
+ cbDot3.isSelected(),
+ cbShowColor.isSelected());
+ } else if (cbDragLightMask.equals(source)) {
+ canvas.dragMask = cbDragLightMask.isSelected();
+ }
+
+ }
+
+ /**
+ * Wrapper method call for MyCanvas. hasTextureImageReady()
+ * @return true if exists a new texture image available
+ */
+ public boolean hasTextureImageReady() {
+ return canvas.hasTextureImageReady();
+ }
+
+ /**
+ * Wrapper method call for MyCanvas.getTextureImage()
+ * Returns a texture image.<br>
+ * Avoid calling the same image several times
+ * by cheking hasTextureImageReady() first.
+ * @return latest texture image available
+ */
+ public BufferedImage getTextureImage() {
+ return canvas.getTextureImage();
+ }
+
+ /**
+ * Wrapper method to MyCanvas.setLightMask(mask)
+ * @param mask a new light mask
+ */
+ public void setLightMask(BufferedImage mask) {
+ canvas.setLightMask(mask);
+ }
+}
+
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/four_by_four/BigCube.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/BigCube.java
new file mode 100644
index 0000000..3609c97
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/BigCube.java
@@ -0,0 +1,139 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.java3d.Shape3D;
+
+/**
+ * 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/main/java/org/jdesktop/j3d/examples/four_by_four/Board.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Board.java
new file mode 100644
index 0000000..3ed2f89
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Board.java
@@ -0,0 +1,2313 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Color;
+import java.awt.Graphics;
+
+/**
+ * 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/main/java/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java
new file mode 100644
index 0000000..ea63b4b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java
@@ -0,0 +1,96 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Canvas;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+/**
+ * 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/main/java/org/jdesktop/j3d/examples/four_by_four/Cube.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Cube.java
new file mode 100644
index 0000000..2460881
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Cube.java
@@ -0,0 +1,132 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.java3d.Shape3D;
+
+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/main/java/org/jdesktop/j3d/examples/four_by_four/Cylinder.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Cylinder.java
new file mode 100644
index 0000000..db13a32
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Cylinder.java
@@ -0,0 +1,117 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.java3d.Shape3D;
+
+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/main/java/org/jdesktop/j3d/examples/four_by_four/FourByFour.html b/src/main/java/org/jdesktop/j3d/examples/four_by_four/FourByFour.html
new file mode 100644
index 0000000..db06814
--- /dev/null
+++ b/src/main/java/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 codebase="../../../../.." code="org.jdesktop.j3d.examples.four_by_four.FourByFour" 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/main/java/org/jdesktop/j3d/examples/four_by_four/FourByFour.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/FourByFour.java
new file mode 100644
index 0000000..3f1a3e1
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/FourByFour.java
@@ -0,0 +1,893 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Button;
+import java.awt.Checkbox;
+import java.awt.CheckboxGroup;
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.TextField;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StreamTokenizer;
+import java.net.URL;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingLeaf;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.View;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Class FourByFour
+ *
+ * Description: High level class for the game FourByFour
+ *
+ * Version: 1.2
+ *
+ */
+public class FourByFour extends Applet implements ActionListener {
+
+ // To write scores to scores file
+ private static final boolean writeScoresFile = false;
+
+ 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
+ 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() {System.setProperty("sun.awt.noerasebackground", "true");
+
+ // 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 {
+ URL instrURL = Resources.getResource("four_by_four/instructions.txt");
+ inStream = new BufferedInputStream((instrURL).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 {
+ URL instrURL = Resources.getResource("four_by_four/instructions.txt");
+ inStream = new BufferedInputStream((instrURL).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());
+ }
+ }
+
+ // Read the high-scores file.
+ places = new int[20];
+ scores = new int[20];
+ names = new String[20];
+ if (appletFlag) {
+ try {
+ URL scoreURL = Resources.getResource("four_by_four/scores.txt");
+ inStream = new BufferedInputStream((scoreURL).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 {
+ URL scoreURL = Resources.getResource("four_by_four/scores.txt");
+ inStream = new BufferedInputStream((scoreURL).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());
+ }
+ }
+
+ // 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(writeScoresFile) {
+ if (appletFlag) {
+ 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 {
+ URL scoreURL = Resources.getResource("four_by_four/scores.txt");
+ inStream = new BufferedInputStream(scoreURL.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 {
+ URL scoreURL = Resources.getResource("four_by_four/scores.txt");
+ inStream = new BufferedInputStream(scoreURL.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());
+ }
+ }
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ FourByFour.appletFlag = false;
+ new MainFrame(new FourByFour(), 730, 450);
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/four_by_four/ID.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/ID.java
new file mode 100644
index 0000000..062f69a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/ID.java
@@ -0,0 +1,61 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java
new file mode 100644
index 0000000..697e934
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java
@@ -0,0 +1,234 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.AWTEvent;
+import java.awt.event.MouseEvent;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.CapabilityNotSetException;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Node;
+import org.jogamp.java3d.PickRay;
+import org.jogamp.java3d.SceneGraphPath;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.WakeupCriterion;
+import org.jogamp.java3d.WakeupOnAWTEvent;
+import org.jogamp.java3d.WakeupOr;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+
+/**
+ * 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/main/java/org/jdesktop/j3d/examples/four_by_four/Poles.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Poles.java
new file mode 100644
index 0000000..47ba07e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Poles.java
@@ -0,0 +1,80 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Group;
+
+/**
+ * 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/main/java/org/jdesktop/j3d/examples/four_by_four/Positions.java b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Positions.java
new file mode 100644
index 0000000..4f5d927
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/Positions.java
@@ -0,0 +1,319 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.util.BitSet;
+
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Switch;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * 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/main/java/org/jdesktop/j3d/examples/four_by_four/README.txt b/src/main/java/org/jdesktop/j3d/examples/four_by_four/README.txt
new file mode 100644
index 0000000..40798d0
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/four_by_four/instructions.txt b/src/main/java/org/jdesktop/j3d/examples/four_by_four/instructions.txt
new file mode 100644
index 0000000..3dcc736
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/four_by_four/instructions.txt
@@ -0,0 +1,98 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/four_by_four/scores.txt b/src/main/java/org/jdesktop/j3d/examples/four_by_four/scores.txt
new file mode 100644
index 0000000..0ebc31a
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java b/src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java
new file mode 100644
index 0000000..fa57927
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java
@@ -0,0 +1,282 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.text.NumberFormat;
+
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+
+/** 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/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.form b/src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.form
new file mode 100644
index 0000000..0a6a276
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.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="FPSCounterDemo"/>
+ </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/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java b/src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java
new file mode 100644
index 0000000..d72aa9f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java
@@ -0,0 +1,255 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import javax.swing.JOptionPane;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+/**
+ * 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 FPSCounterDemo1 -h for help on the various arguments.
+ */
+public class FPSCounterDemo extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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;
+ }
+
+ 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();
+
+ return c;
+ }
+
+ /**
+ * Creates new form FPSCounterDemo
+ */
+ public FPSCounterDemo() {
+ // 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);
+
+ 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);
+
+ }
+
+ /** 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.");
+ }
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------
+
+ /** 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("FPSCounterDemo");
+ 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(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ FPSCounterDemo fp = new FPSCounterDemo();
+ fp.parseArgs(args);
+ fp.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/main/java/org/jdesktop/j3d/examples/gears/Gear.java b/src/main/java/org/jdesktop/j3d/examples/gears/Gear.java
new file mode 100644
index 0000000..63ececf
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gears/Gear.java
@@ -0,0 +1,403 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+public class Gear extends 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/main/java/org/jdesktop/j3d/examples/gears/GearBox.form b/src/main/java/org/jdesktop/j3d/examples/gears/GearBox.form
new file mode 100644
index 0000000..840732c
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gears/GearBox.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="GearBox"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/gears/GearBox.java b/src/main/java/org/jdesktop/j3d/examples/gears/GearBox.java
new file mode 100644
index 0000000..9f3bf6f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gears/GearBox.java
@@ -0,0 +1,408 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program to display a spinning cube.
+ */
+public class GearBox extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+ private int toothCount = 48;
+
+ public BranchGroup createSceneGraph() {
+ 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 GearBox1 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;
+ }
+
+ 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);
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+
+ // 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);
+
+ // 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 GearBox
+ */
+ public GearBox(String args[]) {
+ int value;
+
+ if (args.length > 1) {
+ System.out.println("Usage: java GearBox #teeth (LCD 4)");
+ System.exit(0);
+ } else if (args.length == 1) {
+ {
+ 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);
+ }
+ toothCount = value;
+ }
+ }
+
+ // 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("GearBox");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ GearBox gb = new GearBox(args);
+ gb.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/main/java/org/jdesktop/j3d/examples/gears/GearTest.form b/src/main/java/org/jdesktop/j3d/examples/gears/GearTest.form
new file mode 100644
index 0000000..0ba2e64
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gears/GearTest.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="GearTest"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/gears/GearTest.java b/src/main/java/org/jdesktop/j3d/examples/gears/GearTest.java
new file mode 100644
index 0000000..d50d7d3
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gears/GearTest.java
@@ -0,0 +1,256 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program to display a spinning cube.
+ */
+public class GearTest extends javax.swing.JFrame {
+
+ private int toothCount = 24;
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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 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;
+ }
+
+ 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 GearTest
+ */
+ public GearTest(String args[]) {
+ int value;
+
+ if (args.length > 1) {
+ System.out.println("Usage: java GearTest [#teeth]");
+ System.exit(0);
+ } else if (args.length == 1) {
+ 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);
+ }
+ toothCount = value;
+
+ }
+
+ // 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("GearTest");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ GearTest gt = new GearTest(args);
+ gt.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/main/java/org/jdesktop/j3d/examples/gears/Shaft.java b/src/main/java/org/jdesktop/j3d/examples/gears/Shaft.java
new file mode 100644
index 0000000..18f1c1a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gears/Shaft.java
@@ -0,0 +1,203 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TriangleFanArray;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+public class Shaft extends 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/main/java/org/jdesktop/j3d/examples/gears/SpurGear.java b/src/main/java/org/jdesktop/j3d/examples/gears/SpurGear.java
new file mode 100644
index 0000000..0649e96
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gears/SpurGear.java
@@ -0,0 +1,563 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+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/main/java/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java b/src/main/java/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java
new file mode 100644
index 0000000..39a7b20
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java
@@ -0,0 +1,185 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+
+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/main/java/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java
new file mode 100644
index 0000000..ec58e4c
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java
@@ -0,0 +1,552 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Container;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.swing.BoxLayout;
+import javax.swing.JApplet;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Geometry;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.GeometryUpdater;
+import org.jogamp.java3d.IndexedGeometryArray;
+import org.jogamp.java3d.IndexedTriangleArray;
+import org.jogamp.java3d.IndexedTriangleStripArray;
+import org.jogamp.java3d.J3DBuffer;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java
new file mode 100644
index 0000000..55be4a5
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java
@@ -0,0 +1,584 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Container;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JApplet;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Geometry;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.GeometryUpdater;
+import org.jogamp.java3d.IndexedGeometryArray;
+import org.jogamp.java3d.IndexedTriangleArray;
+import org.jogamp.java3d.IndexedTriangleStripArray;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java
new file mode 100644
index 0000000..6829952
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java
@@ -0,0 +1,331 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Container;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+
+import javax.swing.BoxLayout;
+import javax.swing.JApplet;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.ImageComponent;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Raster;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.Texture2D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.Box;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+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;
+ 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() {System.setProperty("sun.awt.noerasebackground", "true");
+
+ texImage = Resources.getResource("resources/images/one.jpg");
+ if (texImage == null) {
+ System.err.println("resources/images/one.jpg not found");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.net.URL url = null;
+ // the path to the image file for an application
+ url = Resources.getResource("resources/images/one.jpg");
+ if (url == null) {
+ System.err.println("resources/images/one.jpg not found");
+ 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 Raster( );
+ raster.setCapability(Raster.ALLOW_IMAGE_WRITE);
+ raster.setCapability(Raster.ALLOW_SIZE_WRITE);
+ raster.setPosition( new Point3f( -0.9f, 0.75f, 0.0f ) );
+ raster.setType( 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/main/java/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java
new file mode 100644
index 0000000..2d642f2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java
@@ -0,0 +1,561 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Container;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.swing.BoxLayout;
+import javax.swing.JApplet;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedTriangleArray;
+import org.jogamp.java3d.IndexedTriangleStripArray;
+import org.jogamp.java3d.J3DBuffer;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.TextureUnitState;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point2f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+
+ // create textures
+ texImage1 = Resources.getResource("resources/images/bg.jpg");
+ if (texImage1 == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+
+ texImage2 = Resources.getResource("resources/images/one.jpg");
+ if (texImage2 == null) {
+ System.err.println("resources/images/one.jpg not found");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.net.URL texURL1 = null;
+ java.net.URL texURL2 = null;
+ // the path to the image for an application
+ texURL1 = Resources.getResource("resources/images/bg.jpg");
+ if (texURL1 == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+
+ texURL2 = Resources.getResource("resources/images/one.jpg");
+ if (texURL2 == null) {
+ System.err.println("resources/images/one.jpg not found");
+ 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/main/java/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java
new file mode 100644
index 0000000..0fd0217
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java
@@ -0,0 +1,528 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Container;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JApplet;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedTriangleArray;
+import org.jogamp.java3d.IndexedTriangleStripArray;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.TextureUnitState;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point2f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+
+ // create textures
+ texImage1 = Resources.getResource("resources/images/bg.jpg");
+ if (texImage1 == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+
+ texImage2 = Resources.getResource("resources/images/one.jpg");
+ if (texImage2 == null) {
+ System.err.println("resources/images/one.jpg not found");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.net.URL texURL1 = null;
+ java.net.URL texURL2 = null;
+ // the path to the image for an application
+ texURL1 = Resources.getResource("resources/images/bg.jpg");
+ if (texURL1 == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+
+ texURL2 = Resources.getResource("resources/images/one.jpg");
+ if (texURL2 == null) {
+ System.err.println("resources/images/one.jpg not found");
+ 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/main/java/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java
new file mode 100644
index 0000000..0e06f0e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java
@@ -0,0 +1,367 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.util.Vector;
+
+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/main/java/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java b/src/main/java/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java
new file mode 100644
index 0000000..15db111
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java
@@ -0,0 +1,255 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Reader;
+import java.net.URL;
+import java.util.Hashtable;
+
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.loaders.IncorrectFormatException;
+import org.jogamp.java3d.loaders.ParsingErrorException;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.objectfile.ObjectFile;
+import org.jogamp.java3d.utils.geometry.compression.CompressedGeometryData;
+import org.jogamp.java3d.utils.geometry.compression.CompressedGeometryFile;
+import org.jogamp.java3d.utils.geometry.compression.CompressionStream;
+import org.jogamp.java3d.utils.geometry.compression.GeometryCompressor;
+
+/**
+ * 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 CompressedGeometryData node
+ * component.
+ * @param objFileName String object representing the path to a .obj file
+ * @return a CompressedGeometryData node component
+ */
+ public CompressedGeometryData 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 CompressedGeometryData node
+ * component.
+ * @param reader an open .obj file
+ * @return a CompressedGeometryData node component
+ */
+ public CompressedGeometryData 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 CompressedGeometryData node
+ * component.
+ * @param url Uniform Resource Locator for the .obj file
+ * @return a CompressedGeometryData node component
+ */
+ public CompressedGeometryData 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 CompressedGeometryData 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/main/java/org/jdesktop/j3d/examples/geometry_compression/README.txt b/src/main/java/org/jdesktop/j3d/examples/geometry_compression/README.txt
new file mode 100644
index 0000000..345766b
--- /dev/null
+++ b/src/main/java/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.geometry.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/main/java/org/jdesktop/j3d/examples/geometry_compression/cgview.java b/src/main/java/org/jdesktop/j3d/examples/geometry_compression/cgview.java
new file mode 100644
index 0000000..e3eae64
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_compression/cgview.java
@@ -0,0 +1,214 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.applet.Applet;
+import java.awt.BorderLayout;
+import java.io.IOException;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.geometry.compression.CompressedGeometryData;
+import org.jogamp.java3d.utils.geometry.compression.CompressedGeometryFile;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class cgview extends Applet {
+
+ private SimpleUniverse u = null;
+
+ public BranchGroup createSceneGraph(CompressedGeometryData 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.
+ CompressedGeometryData.Header hdr = new CompressedGeometryData.Header() ;
+ cg.getCompressedGeometryHeader(hdr) ;
+
+ Shape3D[] shapes = cg.decompress();
+ if (shapes != null) {
+ for (int i = 0; i < shapes.length; i++) {
+ objTrans.addChild(shapes[i]);
+ }
+ }
+
+ // 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.
+ CompressedGeometryData 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new cgview(args), 700, 700) ;
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java b/src/main/java/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java
new file mode 100644
index 0000000..c0fea26
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java
@@ -0,0 +1,73 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.io.IOException;
+
+import org.jogamp.java3d.utils.geometry.compression.CompressedGeometryFile;
+
+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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/Cube.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/Cube.java
new file mode 100644
index 0000000..86f02ea
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/Cube.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.J3DBuffer;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TriangleArray;
+
+/**
+ * @author Administrator
+ *
+ */
+public class Cube extends Shape3D
+{
+
+ private static final float[] verts = {
+ // front face
+ 1.0f, -1.0f, 1.0f, //1
+ 1.0f, 1.0f, 1.0f, //2
+ -1.0f, 1.0f, 1.0f, //3
+ 1.0f, -1.0f, 1.0f, //1
+ -1.0f, 1.0f, 1.0f, //3
+ -1.0f, -1.0f, 1.0f, //4
+ // back face
+ -1.0f, -1.0f, -1.0f, //1
+ -1.0f, 1.0f, -1.0f, //2
+ 1.0f, 1.0f, -1.0f, //3
+ -1.0f, -1.0f, -1.0f, //1
+ 1.0f, 1.0f, -1.0f, //3
+ 1.0f, -1.0f, -1.0f, //4
+ // right face
+ 1.0f, -1.0f, -1.0f, //1
+ 1.0f, 1.0f, -1.0f, //2
+ 1.0f, 1.0f, 1.0f, //3
+ 1.0f, -1.0f, -1.0f, //1
+ 1.0f, 1.0f, 1.0f, //3
+ 1.0f, -1.0f, 1.0f, //4
+ // left face
+ -1.0f, -1.0f, 1.0f, //1
+ -1.0f, 1.0f, 1.0f, //2
+ -1.0f, 1.0f, -1.0f, //3
+ -1.0f, -1.0f, 1.0f, //1
+ -1.0f, 1.0f, -1.0f, //3
+ -1.0f, -1.0f, -1.0f, //4
+ // top face
+ 1.0f, 1.0f, 1.0f, //1
+ 1.0f, 1.0f, -1.0f, //2
+ -1.0f, 1.0f, -1.0f, //3
+ 1.0f, 1.0f, 1.0f, //1
+ -1.0f, 1.0f, -1.0f, //3
+ -1.0f, 1.0f, 1.0f, //4
+ // bottom face
+ -1.0f, -1.0f, 1.0f, //1
+ -1.0f, -1.0f, -1.0f, //2
+ 1.0f, -1.0f, -1.0f, //3
+ -1.0f, -1.0f, 1.0f, //1
+ 1.0f, -1.0f, -1.0f, //3
+ 1.0f, -1.0f, 1.0f, };//4
+
+ private static final float[] colors = {
+ // front face (red)
+ 1.0f, 0.0f, 0.0f, //1
+ 1.0f, 0.0f, 0.0f, //2
+ 1.0f, 0.0f, 0.0f, //3
+ 1.0f, 0.0f, 0.0f, //1
+ 1.0f, 0.0f, 0.0f, //3
+ 1.0f, 0.0f, 0.0f, //4
+ // back face (green)
+ 0.0f, 1.0f, 0.0f, //1
+ 0.0f, 1.0f, 0.0f, //2
+ 0.0f, 1.0f, 0.0f, //3
+ 0.0f, 1.0f, 0.0f, //1
+ 0.0f, 1.0f, 0.0f, //3
+ 0.0f, 1.0f, 0.0f, //4
+ // right face (blue)
+ 0.0f, 0.0f, 1.0f, //1
+ 0.0f, 0.0f, 1.0f, //2
+ 0.0f, 0.0f, 1.0f, //3
+ 0.0f, 0.0f, 1.0f, //1
+ 0.0f, 0.0f, 1.0f, //3
+ 0.0f, 0.0f, 1.0f, //4
+ // left face (yellow)
+ 1.0f, 1.0f, 0.0f, //1
+ 1.0f, 1.0f, 0.0f, //2
+ 1.0f, 1.0f, 0.0f, //3
+ 1.0f, 1.0f, 0.0f, //1
+ 1.0f, 1.0f, 0.0f, //3
+ 1.0f, 1.0f, 0.0f, //4
+ // top face (magenta)
+ 1.0f, 0.0f, 1.0f, //1
+ 1.0f, 0.0f, 1.0f, //2
+ 1.0f, 0.0f, 1.0f, //3
+ 1.0f, 0.0f, 1.0f, //1
+ 1.0f, 0.0f, 1.0f, //3
+ 1.0f, 0.0f, 1.0f, //4
+ // bottom face (cyan)
+ 0.0f, 1.0f, 1.0f, //1
+ 0.0f, 1.0f, 1.0f, //2
+ 0.0f, 1.0f, 1.0f, //3
+ 0.0f, 1.0f, 1.0f, //1
+ 0.0f, 1.0f, 1.0f, //3
+ 0.0f, 1.0f, 1.0f, };//4
+
+ /**
+ * Constructs a color cube with unit scale. The corners of the
+ * color cube are [-1,-1,-1] and [1,1,1].
+ */
+ public Cube()
+ {
+ TriangleArray cube = new TriangleArray(36,
+ GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.USE_NIO_BUFFER | GeometryArray.BY_REFERENCE);
+
+ cube.setCoordRefBuffer(new J3DBuffer(makeFloatBuffer(verts)));
+ cube.setColorRefBuffer(new J3DBuffer(makeFloatBuffer(colors)));
+
+ this.setGeometry(cube);
+ this.setAppearance(new SimpleShaderAppearance());
+ }
+
+ /**
+ * Constructs a color cube with the specified scale. The corners of the
+ * color cube are [-scale,-scale,-scale] and [scale,scale,scale].
+ * @param scale the scale of the cube
+ */
+ public Cube(double scale)
+ {
+ TriangleArray cube = new TriangleArray(36,
+ GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.USE_NIO_BUFFER | GeometryArray.BY_REFERENCE);
+
+ float scaledVerts[] = new float[verts.length];
+ for (int i = 0; i < verts.length; i++)
+ scaledVerts[i] = verts[i] * (float) scale;
+
+ cube.setCoordRefBuffer(new J3DBuffer(makeFloatBuffer(scaledVerts)));
+ cube.setColorRefBuffer(new J3DBuffer(makeFloatBuffer(colors)));
+
+ this.setGeometry(cube);
+
+ this.setAppearance(new SimpleShaderAppearance());
+ }
+
+ public Cube(double scale, float r, float g, float b)
+ {
+ TriangleArray cube = new TriangleArray(36,
+ GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.USE_NIO_BUFFER | GeometryArray.BY_REFERENCE);
+
+ float scaledVerts[] = new float[verts.length];
+ for (int i = 0; i < verts.length; i++)
+ scaledVerts[i] = verts[i] * (float) scale;
+
+ cube.setCoordRefBuffer(new J3DBuffer(makeFloatBuffer(scaledVerts)));
+
+ float colorsSet[] = new float[36 * 3];
+ for (int i = 0; i < 36; i++)
+ {
+ colorsSet[i * 3 + 0] = r;
+ colorsSet[i * 3 + 1] = g;
+ colorsSet[i * 3 + 2] = b;
+ }
+
+ cube.setColorRefBuffer(new J3DBuffer(makeFloatBuffer(colorsSet)));
+
+ this.setGeometry(cube);
+ this.setAppearance(new SimpleShaderAppearance());
+ }
+
+ /**
+ * Constructs a color cube with the specified scale. The corners of the
+ * color cube are [-scale,-scale,-scale] and [scale,scale,scale].
+ * @param scale the scale of the cube
+ */
+ public Cube(double xScale, double yScale, double zScale)
+ {
+ TriangleArray cube = new TriangleArray(36,
+ GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.USE_NIO_BUFFER | GeometryArray.BY_REFERENCE);
+
+ float scaledVerts[] = new float[verts.length];
+ for (int i = 0; i < verts.length; i += 3)
+ {
+ scaledVerts[i + 0] = verts[i + 0] * (float) xScale;
+ scaledVerts[i + 1] = verts[i + 1] * (float) yScale;
+ scaledVerts[i + 2] = verts[i + 2] * (float) zScale;
+ }
+
+ cube.setCoordRefBuffer(new J3DBuffer(makeFloatBuffer(scaledVerts)));
+ cube.setColorRefBuffer(new J3DBuffer(makeFloatBuffer(colors)));
+
+ this.setGeometry(cube);
+ this.setAppearance(new SimpleShaderAppearance());
+ }
+
+ public Cube(double xScale, double yScale, double zScale, float r, float g, float b)
+ {
+ TriangleArray cube = new TriangleArray(36,
+ GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.USE_NIO_BUFFER | GeometryArray.BY_REFERENCE);
+
+ float scaledVerts[] = new float[verts.length];
+ for (int i = 0; i < verts.length; i += 3)
+ {
+ scaledVerts[i + 0] = verts[i + 0] * (float) xScale;
+ scaledVerts[i + 1] = verts[i + 1] * (float) yScale;
+ scaledVerts[i + 2] = verts[i + 2] * (float) zScale;
+ }
+
+ cube.setCoordRefBuffer(new J3DBuffer(makeFloatBuffer(scaledVerts)));
+
+ float colorsSet[] = new float[36 * 3];
+ for (int i = 0; i < 36; i++)
+ {
+ colorsSet[i * 3 + 0] = r;
+ colorsSet[i * 3 + 1] = g;
+ colorsSet[i * 3 + 2] = b;
+ }
+
+ cube.setColorRefBuffer(new J3DBuffer(makeFloatBuffer(colorsSet)));
+
+ this.setGeometry(cube);
+ this.setAppearance(new SimpleShaderAppearance());
+ }
+
+ public Cube(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax)
+ {
+ TriangleArray cube = new TriangleArray(36,
+ GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.USE_NIO_BUFFER | GeometryArray.BY_REFERENCE);
+
+ float scaledVerts[] = new float[] {
+ // front face
+ xMax, yMin, zMax, //1
+ xMax, yMax, zMax, //2
+ xMin, yMax, zMax, //3
+ xMax, yMin, zMax, //1
+ xMin, yMax, zMax, //3
+ xMin, yMin, zMax, //4
+ // back face
+ xMin, yMin, zMin, //1
+ xMin, yMax, zMin, //2
+ xMax, yMax, zMin, //3
+ xMin, yMin, zMin, //1
+ xMax, yMax, zMin, //3
+ xMax, yMin, zMin, //4
+ // right face
+ xMax, yMin, zMin, //1
+ xMax, yMax, zMin, //2
+ xMax, yMax, zMax, //3
+ xMax, yMin, zMin, //1
+ xMax, yMax, zMax, //3
+ xMax, yMin, zMax, //4
+ // left face
+ xMin, yMin, zMax, //1
+ xMin, yMax, zMax, //2
+ xMin, yMax, zMin, //3
+ xMin, yMin, zMax, //1
+ xMin, yMax, zMin, //3
+ xMin, yMin, zMin, //4
+ // top face
+ xMax, yMax, zMax, //1
+ xMax, yMax, zMin, //2
+ xMin, yMax, zMin, //3
+ xMax, yMax, zMax, //1
+ xMin, yMax, zMin, //3
+ xMin, yMax, zMax, //4
+ // bottom face
+ xMin, yMin, zMax, //1
+ xMin, yMin, zMin, //2
+ xMax, yMin, zMin, //3
+ xMin, yMin, zMax, //1
+ xMax, yMin, zMin, //3
+ xMax, yMin, zMax, };//4
+
+ cube.setCoordRefBuffer(new J3DBuffer(makeFloatBuffer(scaledVerts)));
+ cube.setColorRefBuffer(new J3DBuffer(makeFloatBuffer(colors)));
+
+ this.setGeometry(cube);
+ this.setAppearance(new SimpleShaderAppearance());
+ }
+
+ public static FloatBuffer makeFloatBuffer(float[] arr)
+ {
+ ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
+ bb.order(ByteOrder.nativeOrder());
+ FloatBuffer fb = bb.asFloatBuffer();
+ fb.put(arr);
+ fb.position(0);
+ return fb;
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/EnvironmentMappingGLSL.form b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/EnvironmentMappingGLSL.form
new file mode 100644
index 0000000..b6a3e94
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/EnvironmentMappingGLSL.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="EnvironmentMappingGLSL"/>
+ </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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/EnvironmentMappingGLSL.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/EnvironmentMappingGLSL.java
new file mode 100644
index 0000000..700df00
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/EnvironmentMappingGLSL.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttribute;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureUnitState;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+
+public class EnvironmentMappingGLSL extends javax.swing.JFrame
+{
+
+ private URL textureURL = null;
+ private static final int NUM_TEX_UNITS = 1;
+ private static final int TEX_UNIT = 0;
+
+ SimpleUniverse univ = 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 texture object
+ textureURL = Resources.getResource("resources/images/duke-gears.jpg");
+ Texture tex = new TextureLoader(textureURL, this).getTexture();
+ // Create the shader program
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try
+ {
+ vertexProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.frag"));
+ }
+ catch (IOException e)
+ {
+ System.err.println(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);
+ final String[] shaderAttrNames = { "LightPos", "BaseColor", "MixRatio", "EnvMap", };
+ final Object[] shaderAttrValues = { new Point3f(1.0f, -1.0f, 2.0f), new Color3f(0.2f, 0.9f, 0.5f), new Float(0.4f),
+ new Integer(TEX_UNIT), };
+ ShaderProgram shaderProgram = new GLSLShaderProgram();
+ shaderProgram.setShaders(shaders);
+ shaderProgram.setShaderAttrNames(shaderAttrNames);
+
+ // Create the shader attribute set
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ for (int i = 0; i < shaderAttrNames.length; i++)
+ {
+ ShaderAttribute shaderAttribute = new ShaderAttributeValue(shaderAttrNames[i], shaderAttrValues[i]);
+ shaderAttributeSet.put(shaderAttribute);
+ }
+
+ // Create shader appearance to hold the shader program and
+ // shader attributes
+ ShaderAppearance app = new ShaderAppearance();
+ app.setShaderProgram(shaderProgram);
+ app.setShaderAttributeSet(shaderAttributeSet);
+
+ // Put the texture in specified texture unit
+ TextureUnitState[] tus = new TextureUnitState[NUM_TEX_UNITS];
+ tus[TEX_UNIT] = new TextureUnitState();
+ tus[TEX_UNIT].setTexture(tex);
+ app.setTextureUnitState(tus);
+
+ // Create a Sphere object using the shader appearance,
+ // and add it into the scene graph.
+ Sphere sph = new Sphere(0.4f, Sphere.GENERATE_NORMALS, 20, app);
+ SphereGLSL.makeNIO(sph);
+ 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();
+ 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 initScene()
+ {
+ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ BranchGroup scene = createSceneGraph();
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ @Override
+ public void errorOccurred(ShaderError error)
+ {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(EnvironmentMappingGLSL.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ univ.addBranchGraph(scene);
+
+ return c;
+ }
+
+ /**
+ * Creates new form EnvironmentMappingGLSL
+ */
+ public EnvironmentMappingGLSL()
+ {
+ // 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()
+ {
+ drawingPanel = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("EnvironmentMappingGLSL");
+ 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[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ new EnvironmentMappingGLSL().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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ObjLoadGLSL.form b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ObjLoadGLSL.form
new file mode 100644
index 0000000..343b6d5
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ObjLoadGLSL.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="ObjLoadGLSL"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ObjLoadGLSL.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ObjLoadGLSL.java
new file mode 100644
index 0000000..2708e58
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ObjLoadGLSL.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Node;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.loaders.IncorrectFormatException;
+import org.jogamp.java3d.loaders.ParsingErrorException;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.objectfile.ObjectFile;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.PlatformGeometry;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program to display an .obj object with shader programs.
+ */
+public class ObjLoadGLSL extends javax.swing.JFrame
+{
+
+ 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 univ = null;
+ private BranchGroup scene = 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.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);
+ }
+
+ // Set vertex and fragment shader program for all Shape3D nodes in scene
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try
+ {
+ vertexProgram = StringIO.readFully(new File(
+ System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/" + shaderName + ".vert"));
+ fragmentProgram = StringIO.readFully(new File(
+ System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/" + 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());
+
+ 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);
+
+ 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 canvas3d = new Canvas3D(config);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(canvas3d);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ @Override
+ public void errorOccurred(ShaderError error)
+ {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(ObjLoadGLSL.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = univ.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(canvas3d, OrbitBehavior.REVERSE_ALL);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+ }
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return canvas3d;
+ }
+
+ private static 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
+
+ // 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);
+ }
+ }
+ }
+
+ /**
+ * Creates new form ObjLoadGLSL
+ */
+ 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)
+ {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+ if (filename == null)
+ {
+ filename = Resources.getResource("resources/geometry/galleon.obj");
+ if (filename == null)
+ {
+ System.err.println("resources/geometry/galleon.obj not found");
+ System.exit(1);
+ }
+ }
+
+ // 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("ObjLoadGLSL");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend","jogl2es2");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ ObjLoadGLSL objLoadGLSL = new ObjLoadGLSL(args);
+ objLoadGLSL.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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/PhongShadingGLSL.form b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/PhongShadingGLSL.form
new file mode 100644
index 0000000..dcccf73
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/PhongShadingGLSL.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/PhongShadingGLSL.java
new file mode 100644
index 0000000..fa5ba7a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/PhongShadingGLSL.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.SpotLight;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ *
+ * @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 univ = 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(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/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(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/phong.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/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);
+ SphereGLSL.makeNIO(sph);
+ 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);
+
+ Sphere sph2 = new Sphere(0.05f, appL1);
+ SphereGLSL.makeNIO(sph2);
+ l1Trans.addChild(sph2);
+ // 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);
+
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ @Override
+ public void errorOccurred(ShaderError error)
+ {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(PhongShadingGLSL.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ univ.getViewingPlatform().setNominalViewingTransform();
+
+ BranchGroup scene = createSceneGraph();
+ univ.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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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 static 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[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ 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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SamplerTestGLSL.form b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SamplerTestGLSL.form
new file mode 100644
index 0000000..6a1a031
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SamplerTestGLSL.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="SamplerTestGLSL"/>
+ </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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SamplerTestGLSL.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SamplerTestGLSL.java
new file mode 100644
index 0000000..1cb2904
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SamplerTestGLSL.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttribute;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureUnitState;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Point3d;
+
+public class SamplerTestGLSL extends javax.swing.JFrame
+{
+
+ private static String cloudTexName = "resources/images/bg.jpg";
+ private static String earthTexName = "resources/images/earth.jpg";
+
+ private URL cloudURL = null;
+ private URL earthURL = null;
+ private static final int CLOUD = 0;
+ private static final int EARTH = 1;
+
+ SimpleUniverse univ = 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 texture objects
+ cloudURL = Resources.getResource(cloudTexName);
+ Texture cloudTex = new TextureLoader(cloudURL, this).getTexture();
+ earthURL = Resources.getResource(earthTexName);
+ Texture earthTex = new TextureLoader(earthURL, this).getTexture();
+
+ // Create the shader program
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try
+ {
+ vertexProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.frag"));
+ }
+ catch (IOException e)
+ {
+ System.err.println(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);
+ final String[] shaderAttrNames = { "cloudFactor", "cloudTex", "earthTex", };
+ final Object[] shaderAttrValues = { new Float(0.6f), new Integer(0), new Integer(1), };
+ ShaderProgram shaderProgram = new GLSLShaderProgram();
+ shaderProgram.setShaders(shaders);
+ shaderProgram.setShaderAttrNames(shaderAttrNames);
+
+ // Create the shader attribute set
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ for (int i = 0; i < shaderAttrNames.length; i++)
+ {
+ ShaderAttribute shaderAttribute = new ShaderAttributeValue(shaderAttrNames[i], shaderAttrValues[i]);
+ shaderAttributeSet.put(shaderAttribute);
+ }
+
+ // Create shader appearance to hold the shader program and
+ // shader attributes
+ ShaderAppearance app = new ShaderAppearance();
+ app.setShaderProgram(shaderProgram);
+ app.setShaderAttributeSet(shaderAttributeSet);
+
+ // GL2ES2: Tex coord gen done in shader now
+ //Vector4f plane0S = new Vector4f(3.0f, 1.5f, 0.3f, 0.0f);
+ //Vector4f plane0T = new Vector4f(1.0f, 2.5f, 0.24f, 0.0f);
+ //TexCoordGeneration tcg0 = new TexCoordGeneration(TexCoordGeneration.OBJECT_LINEAR, TexCoordGeneration.TEXTURE_COORDINATE_2, plane0S,
+ // plane0T);
+ //TexCoordGeneration tcg1 = new TexCoordGeneration(TexCoordGeneration.SPHERE_MAP, TexCoordGeneration.TEXTURE_COORDINATE_2);
+
+ // Put the textures in unit 0,1
+ TextureUnitState[] tus = new TextureUnitState[2];
+ tus[CLOUD] = new TextureUnitState();
+ tus[CLOUD].setTexture(cloudTex);
+
+ // GL2ES2: Tex coord gen done in shader now
+ //tus[CLOUD].setTexCoordGeneration(tcg0);
+
+ tus[EARTH] = new TextureUnitState();
+ tus[EARTH].setTexture(earthTex);
+
+ // GL2ES2: Tex coord gen done in shader now
+ //tus[EARTH].setTexCoordGeneration(tcg1);
+
+ app.setTextureUnitState(tus);
+
+ // Create a Sphere object using the shader appearance,
+ // and add it into the scene graph.
+ Sphere sph = new Sphere(0.4f, Sphere.GENERATE_NORMALS, 30, app);
+
+ SphereGLSL.makeNIO(sph);
+ 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();
+ 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 initScene()
+ {
+ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ BranchGroup scene = createSceneGraph();
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ @Override
+ public void errorOccurred(ShaderError error)
+ {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(SamplerTestGLSL.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ univ.addBranchGraph(scene);
+
+ return c;
+ }
+
+ /**
+ * Creates new form SamplerTestGLSL
+ */
+ public SamplerTestGLSL()
+ {
+ // 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()
+ {
+ drawingPanel = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("SamplerTestGLSL");
+ 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[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend","jogl2es2");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ new SamplerTestGLSL().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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ShaderTestGLSL.form b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ShaderTestGLSL.form
new file mode 100644
index 0000000..714273d
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ShaderTestGLSL.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ShaderTestGLSL.java
new file mode 100644
index 0000000..ac0282e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/ShaderTestGLSL.java
@@ -0,0 +1,727 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PositionInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttributeObject;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+
+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 univ = 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 static ShaderProgram createGLSLShaderProgram(int index)
+ {
+ String vertexProgram = null;
+ String fragmentProgram = null;
+
+ try
+ {
+ switch (index)
+ {
+ case DIMPLE_SHADER:
+ vertexProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.frag"));
+ break;
+ case BRICK_SHADER:
+ vertexProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.frag"));
+ break;
+ case WOOD_SHADER:
+ vertexProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/wood.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/wood.frag"));
+ break;
+ case POLKADOT3D_SHADER:
+ vertexProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/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);
+ SphereGLSL.makeNIO(sphere);
+ s3d = 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 = univ.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);
+
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ @Override
+ public void errorOccurred(ShaderError error)
+ {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(ShaderTestGLSL.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ //view = univ.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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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() {
+ @Override
+ 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);
+ univ.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 static void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt)
+ {//GEN-FIRST:event_exitMenuItemActionPerformed
+ System.exit(0);
+ }//GEN-LAST:event_exitMenuItemActionPerformed
+
+ /** Exit the Application */
+ private static 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[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend","jogl2es2");
+ 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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SimpleShaderAppearance.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SimpleShaderAppearance.java
new file mode 100644
index 0000000..5b7be75
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SimpleShaderAppearance.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.LineAttributes;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.vecmath.Color3f;
+
+/**
+ * @author phil
+ *
+ */
+public class SimpleShaderAppearance extends ShaderAppearance
+{
+ private static GLSLShaderProgram flatShaderProgram;
+ private static GLSLShaderProgram textureShaderProgram;
+ private static GLSLShaderProgram colorLineShaderProgram;
+ private static GLSLShaderProgram litFlatShaderProgram;
+ private static GLSLShaderProgram litTextureShaderProgram;
+
+ public static String alphaTestUniforms = "uniform int alphaTestEnabled;\n" + //
+ "uniform int alphaTestFunction;\n" + //
+ "uniform float alphaTestValue;\n";
+
+ public static String alphaTestMethod = "if(alphaTestEnabled != 0)\n" + //
+ "{ \n" + //
+ " if(alphaTestFunction==516)//>\n" + //
+ " if(baseMap.a<=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==518)//>=\n" + //
+ " if(baseMap.a<alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==514)//==\n" + //
+ " if(baseMap.a!=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==517)//!=\n" + //
+ " if(baseMap.a==alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==513)//<\n" + //
+ " if(baseMap.a>=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==515)//<=\n" + //
+ " if(baseMap.a>alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==512)//never \n" + //
+ " discard; \n" + //
+ "}\n";
+
+ /**
+ * Polygons no texture, no single color, must have color vertex attribute
+ */
+ public SimpleShaderAppearance()
+ {
+ this(null, false, false);
+ }
+
+ /**
+ * Lines with a single color no texture, ignores vertex attribute of color
+ * @param color
+ */
+ public SimpleShaderAppearance(Color3f color)
+ {
+ this(color, false, false);
+ }
+
+ /**
+ * Polygons if hasTexture is true a texture otherwise vertex attribute colors for face color
+ */
+ public SimpleShaderAppearance(boolean hasTexture)
+ {
+ this(null, false, hasTexture);
+ }
+
+ public SimpleShaderAppearance(boolean lit, boolean hasTexture)
+ {
+ this(null, lit, hasTexture);
+ }
+
+ /** if color is not null then a line appearance
+ * otherwise simple poly appearance
+ * @param color
+ */
+ private SimpleShaderAppearance(Color3f color, boolean lit, boolean hasTexture)
+ {
+ if (lit)
+ {
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec4 glColor;\n";
+ vertexProgram += "attribute vec3 glNormal; \n";
+ if (hasTexture)
+ {
+ vertexProgram += "attribute vec2 glMultiTexCoord0;\n";
+ }
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "uniform mat4 glModelViewMatrix;\n";
+ vertexProgram += "uniform mat3 glNormalMatrix;\n";
+ vertexProgram += "uniform int ignoreVertexColors;\n";
+ vertexProgram += "uniform vec4 glLightModelambient;\n";
+ vertexProgram += "struct material\n";
+ vertexProgram += "{\n";
+ vertexProgram += " int lightEnabled;\n";
+ vertexProgram += " vec4 ambient;\n";
+ vertexProgram += " vec4 diffuse;\n";
+ vertexProgram += " vec4 emission; \n";
+ vertexProgram += " vec3 specular;\n";
+ vertexProgram += " float shininess;\n";
+ vertexProgram += "};\n";
+ vertexProgram += "uniform material glFrontMaterial;\n";
+ vertexProgram += "struct lightSource\n";
+ vertexProgram += " {\n";
+ vertexProgram += " int enabled;\n";
+ vertexProgram += " vec4 position;\n";
+ vertexProgram += " vec4 diffuse;\n";
+ vertexProgram += " vec4 specular;\n";
+ vertexProgram += " float constantAttenuation, linearAttenuation, quadraticAttenuation;\n";
+ vertexProgram += " float spotCutoff, spotExponent;\n";
+ vertexProgram += " vec3 spotDirection;\n";
+ vertexProgram += " };\n";
+ vertexProgram += "\n";
+ vertexProgram += " uniform int numberOfLights;\n";
+ vertexProgram += " const int maxLights = 1;\n";
+ vertexProgram += " uniform lightSource glLightSource[maxLights];\n";
+ if (hasTexture)
+ {
+ vertexProgram += "varying vec2 glTexCoord0;\n";
+ }
+ vertexProgram += "varying vec3 LightDir;\n";
+ vertexProgram += "varying vec3 ViewDir;\n";
+ vertexProgram += "varying vec3 N;\n";
+ vertexProgram += "varying vec4 A;\n";
+ vertexProgram += "varying vec4 C;\n";
+ vertexProgram += "varying vec4 D;\n";
+ vertexProgram += "varying vec3 emissive;\n";
+ vertexProgram += "varying vec3 specular;\n";
+ vertexProgram += "varying float shininess;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ if (hasTexture)
+ {
+ vertexProgram += "glTexCoord0 = glMultiTexCoord0.st;\n";
+ }
+
+ vertexProgram += "N = normalize(glNormalMatrix * glNormal);\n";
+
+ vertexProgram += "vec3 v = vec3(glModelViewMatrix * glVertex);\n";
+
+ vertexProgram += "ViewDir = -v.xyz;\n";
+ vertexProgram += "LightDir = glLightSource[0].position.xyz;\n";
+
+ vertexProgram += "A = glLightModelambient * glFrontMaterial.ambient;\n";
+ vertexProgram += "if( ignoreVertexColors != 0) \n";
+ // objectColor should be used if it is no lighting, and reusing material diffuse appears wrong
+ vertexProgram += " C = vec4(1,1,1,1);//glFrontMaterial.diffuse; \n";
+ vertexProgram += "else \n";
+ vertexProgram += " C = glColor; \n";
+
+ vertexProgram += "D = glLightSource[0].diffuse * glFrontMaterial.diffuse;\n";
+
+ vertexProgram += "emissive = glFrontMaterial.emission.rgb;\n";
+ vertexProgram += "specular = glFrontMaterial.specular;\n";
+ vertexProgram += "shininess = glFrontMaterial.shininess;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ if (hasTexture)
+ {
+ fragmentProgram += alphaTestUniforms;
+
+ fragmentProgram += "varying vec2 glTexCoord0;\n";
+ fragmentProgram += "uniform sampler2D BaseMap;\n";
+ }
+
+ fragmentProgram += "in vec3 LightDir;\n";
+ fragmentProgram += "in vec3 ViewDir;\n";
+
+ fragmentProgram += "in vec3 N;\n";
+
+ fragmentProgram += "in vec4 A;\n";
+ fragmentProgram += "in vec4 C;\n";
+ fragmentProgram += "in vec4 D;\n";
+
+ fragmentProgram += "in vec3 emissive;\n";
+ fragmentProgram += "in vec3 specular;\n";
+ fragmentProgram += "in float shininess;\n";
+ fragmentProgram += "void main( void ){\n ";
+ if (hasTexture)
+ {
+ fragmentProgram += "vec4 baseMap = texture2D( BaseMap, glTexCoord0.st );\n";
+ }
+ if (hasTexture)
+ {
+ fragmentProgram += alphaTestMethod;
+ }
+ fragmentProgram += "vec3 normal = N;\n";
+
+ fragmentProgram += "vec3 L = normalize(LightDir);\n";
+ fragmentProgram += "vec3 E = normalize(ViewDir);\n";
+ fragmentProgram += "vec3 R = reflect(-L, normal);\n";
+ fragmentProgram += "vec3 H = normalize( L + E );\n";
+
+ fragmentProgram += "float NdotL = max( dot(normal, L), 0.0 );\n";
+ fragmentProgram += "float NdotH = max( dot(normal, H), 0.0 );\n";
+ fragmentProgram += "float EdotN = max( dot(normal, E), 0.0 );\n";
+ fragmentProgram += "float NdotNegL = max( dot(normal, -L), 0.0 );\n";
+
+ fragmentProgram += "vec4 color;\n";
+ if (hasTexture)
+ {
+ fragmentProgram += "vec3 albedo = baseMap.rgb * C.rgb;\n";
+ }
+ else
+ {
+ fragmentProgram += "vec3 albedo = C.rgb;\n";
+ }
+ fragmentProgram += "vec3 diffuse = A.rgb + (D.rgb * NdotL);\n";
+
+ // 0.3 is just what the calc is
+ fragmentProgram += "vec3 spec = specular * pow(NdotH, 0.3*shininess);\n";
+ // D is not right it should be the light source spec color, probably just 1,1,1 but java3d has no spec on lights
+ //fragmentProgram += "spec *= D.rgb;\n";
+
+ fragmentProgram += "color.rgb = albedo * (diffuse + emissive) + spec;\n";
+ if (hasTexture)
+ {
+ fragmentProgram += "color.a = C.a * baseMap.a;\n";
+ }
+ else
+ {
+ fragmentProgram += "color.a = C.a;\n";
+ }
+
+ fragmentProgram += "gl_FragColor = color;\n";
+
+ fragmentProgram += "}";
+ if (hasTexture)
+ {
+ if (litTextureShaderProgram == null)
+ {
+ litTextureShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance litTextureShaderProgram";
+ }
+ };
+ litTextureShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+ litTextureShaderProgram.setShaderAttrNames(new String[] { "BaseMap" });
+
+ }
+
+ setShaderProgram(litTextureShaderProgram);
+
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ shaderAttributeSet.put(new ShaderAttributeValue("BaseMap", new Integer(0)));
+ setShaderAttributeSet(shaderAttributeSet);
+ }
+ else
+ {
+ if (litFlatShaderProgram == null)
+ {
+ litFlatShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance litFlatShaderProgram";
+ }
+ };
+ litFlatShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+
+ //System.out.println("vertexProgram " + vertexProgram);
+ //System.out.println("fragmentProgram " + fragmentProgram);
+
+ }
+
+ setShaderProgram(litFlatShaderProgram);
+
+ }
+ }
+ else
+ {
+ if (hasTexture)
+ {
+ if (textureShaderProgram == null)
+ {
+ textureShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance textureShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec2 glMultiTexCoord0;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec2 glTexCoord0;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "glTexCoord0 = glMultiTexCoord0.st;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += alphaTestUniforms;
+ fragmentProgram += "varying vec2 glTexCoord0;\n";
+ fragmentProgram += "uniform sampler2D BaseMap;\n";
+ fragmentProgram += "void main( void ){\n ";
+ fragmentProgram += "vec4 baseMap = texture2D( BaseMap, glTexCoord0.st );\n";
+ fragmentProgram += alphaTestMethod;
+ fragmentProgram += "gl_FragColor = baseMap;\n";
+ fragmentProgram += "}";
+
+ textureShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+ textureShaderProgram.setShaderAttrNames(new String[] { "BaseMap" });
+ }
+
+ setShaderProgram(textureShaderProgram);
+
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ shaderAttributeSet.put(new ShaderAttributeValue("BaseMap", new Integer(0)));
+ setShaderAttributeSet(shaderAttributeSet);
+
+ }
+ else
+
+ {
+ if (color != null)
+ {
+ PolygonAttributes polyAtt = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_NONE, 0.0f);
+ polyAtt.setPolygonOffset(0.1f);
+ setPolygonAttributes(polyAtt);
+ LineAttributes lineAtt = new LineAttributes(1, LineAttributes.PATTERN_SOLID, false);
+ setLineAttributes(lineAtt);
+
+ ColoringAttributes colorAtt = new ColoringAttributes(color, ColoringAttributes.FASTEST);
+ setColoringAttributes(colorAtt);
+
+ RenderingAttributes ra = new RenderingAttributes();
+ ra.setIgnoreVertexColors(true);
+ setRenderingAttributes(ra);
+
+ Material mat = new Material();
+ setMaterial(mat);
+
+ if (colorLineShaderProgram == null)
+ {
+ colorLineShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance colorLineShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec4 glColor;\n";
+ vertexProgram += "uniform int ignoreVertexColors;\n";
+ vertexProgram += "uniform vec4 objectColor;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec4 glFrontColor;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "if( ignoreVertexColors != 0 )\n";
+ vertexProgram += " glFrontColor = objectColor;\n";
+ vertexProgram += "else\n";
+ vertexProgram += " glFrontColor = glColor;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += "varying vec4 glFrontColor;\n";
+ fragmentProgram += "void main( void ){\n";
+ fragmentProgram += "gl_FragColor = glFrontColor;\n";
+ fragmentProgram += "}";
+
+ colorLineShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+ }
+
+ setShaderProgram(colorLineShaderProgram);
+
+ }
+ else
+ {
+ RenderingAttributes ra = new RenderingAttributes();
+ setRenderingAttributes(ra);
+
+ if (flatShaderProgram == null)
+ {
+ flatShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance flatShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec4 glColor;\n";
+ vertexProgram += "uniform int ignoreVertexColors;\n";
+ vertexProgram += "uniform vec4 objectColor;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec4 glFrontColor;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "if( ignoreVertexColors != 0 )\n";
+ vertexProgram += " glFrontColor = objectColor;\n";
+ vertexProgram += "else\n";
+ vertexProgram += " glFrontColor = glColor;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += "varying vec4 glFrontColor;\n";
+ fragmentProgram += "void main( void ){\n";
+ fragmentProgram += "gl_FragColor = glFrontColor;\n";
+ fragmentProgram += "}";
+
+ flatShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+
+ }
+
+ setShaderProgram(flatShaderProgram);
+
+ }
+ }
+
+ }
+
+ }
+
+ private static Shader[] makeShaders(String vertexProgram, String fragmentProgram)
+ {
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_VERTEX, vertexProgram) {
+ @Override
+ public String toString()
+ {
+ return "vertexProgram";
+ }
+ };
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_FRAGMENT, fragmentProgram) {
+ @Override
+ public String toString()
+ {
+ return "fragmentProgram";
+ }
+ };
+ return shaders;
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SphereGLSL.form b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SphereGLSL.form
new file mode 100644
index 0000000..26e9b32
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SphereGLSL.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="SphereGLSL"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SphereGLSL.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SphereGLSL.java
new file mode 100644
index 0000000..8a59c5f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/SphereGLSL.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.swing.JOptionPane;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.J3DBuffer;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.PositionInterpolator;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.SpotLight;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program with programmable shader.
+ */
+public class SphereGLSL 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. This flag is set based on command line argument
+ private static int lightType = POINT_LIGHT;//DIRECTIONAL_LIGHT;
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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 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(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/simple.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/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);
+ makeNIO(sph);
+ 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 SimpleShaderAppearance(false, false);
+ Appearance appL2 = new SimpleShaderAppearance(false, false);
+ appL1.setColoringAttributes(caL1);
+ appL2.setColoringAttributes(caL2);
+
+ Sphere sph2 = new Sphere(0.05f, appL1);
+ makeNIO(sph2);
+
+ l1Trans.addChild(sph2);
+ Sphere sph3 = new Sphere(0.05f, appL2);
+ makeNIO(sph3);
+
+ l2Trans.addChild(sph3);
+
+ // 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 = univ.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 createUniverse()
+ {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+
+ // Create a Canvas3D using the preferred configuration
+ Canvas3D canvas3d = new Canvas3D(config);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(canvas3d);
+ //BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ @Override
+ public void errorOccurred(ShaderError error)
+ {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(SphereGLSL.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ // 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 canvas3d;
+ }
+
+ /**
+ * Creates new form SphereGLSL
+ */
+ public SphereGLSL()
+ {
+
+ // 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("SphereGLSL");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ SphereGLSL sphereGLSL = new SphereGLSL();
+ sphereGLSL.setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel drawingPanel;
+
+ // End of variables declaration//GEN-END:variables
+ public static void makeNIO(Sphere sph)
+ {
+ //Make it NIO
+ TriangleStripArray geo = (TriangleStripArray) sph.getShape().getGeometry();
+ int[] stripVertexCounts = new int[geo.getNumStrips()];
+ geo.getStripVertexCounts(stripVertexCounts);
+ TriangleStripArray newGeo = new TriangleStripArray(geo.getVertexCount(), GeometryArray.COORDINATES | GeometryArray.NORMALS
+ //| GeometryArray.TEXTURE_COORDINATE_2
+ | GeometryArray.USE_NIO_BUFFER | GeometryArray.BY_REFERENCE, stripVertexCounts);
+
+ float[] coords = new float[geo.getValidVertexCount() * 3];
+ geo.getCoordinates(0, coords);
+ newGeo.setCoordRefBuffer(new J3DBuffer(makeFloatBuffer(coords)));
+ float[] norms = new float[geo.getValidVertexCount() * 3];
+ geo.getNormals(0, norms);
+ newGeo.setNormalRefBuffer(new J3DBuffer(makeFloatBuffer(norms)));
+ sph.getShape().setGeometry(newGeo);
+
+ }
+
+ private static FloatBuffer makeFloatBuffer(float[] arr)
+ {
+ ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
+ bb.order(ByteOrder.nativeOrder());
+ FloatBuffer fb = bb.asFloatBuffer();
+ fb.put(arr);
+ fb.position(0);
+ return fb;
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/VertexAttrTestGLSL.form b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/VertexAttrTestGLSL.form
new file mode 100644
index 0000000..6e31a8f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/VertexAttrTestGLSL.form
@@ -0,0 +1,203 @@
+<?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="title" type="java.lang.String" value="VertexAttrTestGLSL"/>
+ </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,44,0,0,1,-112"/>
+ </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.DesignGridBagLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="vertexCheckBoxPanel">
+ <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="vertexFormat">
+ <Font PropertyName="font" name="Lucida Sans" size="10" style="0"/>
+ </TitledBorder>
+ </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="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="2" insetsBottom="2" insetsRight="2" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="jPanel1">
+ <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="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="11" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JSeparator" name="jSeparator1">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[0, 4]"/>
+ </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="0" 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.JSeparator" name="jSeparator2">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[0, 4]"/>
+ </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="3" gridWidth="1" gridHeight="1" fill="0" 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="jPanel2">
+ <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="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="11" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JCheckBox" name="vertexAttrsBox">
+ <Properties>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String" value="VertexAttrs"/>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="4" 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="geometryPanel">
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="2" insetsBottom="2" insetsRight="2" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JButton" name="createButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Create Geometry"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createButtonActionPerformed"/>
+ </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.JButton" name="destroyButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Destroy Geometry"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="destroyButtonActionPerformed"/>
+ </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="2" 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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/VertexAttrTestGLSL.java b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/VertexAttrTestGLSL.java
new file mode 100644
index 0000000..f80ac11
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/VertexAttrTestGLSL.java
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.gl2es2pipeline;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.J3DBuffer;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+
+public class VertexAttrTestGLSL extends javax.swing.JFrame
+{
+
+ SimpleUniverse univ = null;
+ BranchGroup scene = null;
+
+ public BranchGroup createSceneGraph(boolean hasVertexAttrs)
+ {
+
+ // Bounds for BG and behavior
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+ objRoot.setCapability(BranchGroup.ALLOW_DETACH);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.1f, 0.1f, 0.1f);
+ 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);
+ objRoot.addChild(objTrans);
+
+ // Create a simple Shape3D node; add it to the scene graph.
+ objTrans.addChild(new MyShape(this, hasVertexAttrs));
+
+ return objRoot;
+ }
+
+ private Canvas3D initScene()
+ {
+ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ @Override
+ public void errorOccurred(ShaderError error)
+ {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(VertexAttrTestGLSL.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ return c;
+ }
+
+ /**
+ * Creates new form VertexAttrTestGLSL
+ */
+ public VertexAttrTestGLSL()
+ {
+ // 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);
+ }
+
+ static class MyShape extends Shape3D
+ {
+
+ // Coordinate data
+ private static final float[] coords = { 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, };
+
+ private static final int[] sizes = { 1, 3 };
+ private static final float[] weights = { 0.45f, 0.15f, 0.95f, };
+ private static final float[] temps = { 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, };
+
+ private static final String[] vaNames = { "weight", "temperature" };
+
+ J3DBuffer createDirectFloatBuffer(float[] arr)
+ {
+ ByteOrder order = ByteOrder.nativeOrder();
+
+ FloatBuffer nioBuf = ByteBuffer.allocateDirect(arr.length * 4).order(order).asFloatBuffer();
+ nioBuf.put(arr);
+ return new J3DBuffer(nioBuf);
+ }
+
+ MyShape(JFrame frame, boolean hasVertexAttrs)
+ {
+
+ int vertexFormat = GeometryArray.COORDINATES;
+ int vertexAttrCount = 0;
+ int[] vertexAttrSizes = null;
+ String[] vertexAttrNames = null;
+ String[] shaderAttrNames = null;
+
+ if (hasVertexAttrs)
+ {
+ vertexFormat |= GeometryArray.VERTEX_ATTRIBUTES;
+ vertexAttrCount = vaNames.length;
+ vertexAttrSizes = sizes;
+ vertexAttrNames = vaNames;
+ }
+
+ //GL2ES2: requires by reference
+ vertexFormat |= GeometryArray.BY_REFERENCE;
+
+ TriangleArray tri = new TriangleArray(6, vertexFormat, 0, null, vertexAttrCount, vertexAttrSizes);
+ tri.setValidVertexCount(3);
+ //tri.setCoordinates(0, coords);
+ tri.setCoordRefFloat(coords);
+
+ if (hasVertexAttrs)
+ {
+ //tri.setVertexAttrs(0, 0, weights);
+ //tri.setVertexAttrs(1, 0, temps);
+
+ tri.setVertexAttrRefFloat(0, weights);
+ tri.setVertexAttrRefFloat(1, temps);
+
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try
+ {
+ vertexProgram = StringIO.readFully(new File(
+ System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.vert"));
+ fragmentProgram = StringIO.readFully(new File(
+ System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.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);
+ shaderProgram.setVertexAttrNames(vertexAttrNames);
+ shaderProgram.setShaderAttrNames(shaderAttrNames);
+
+ ShaderAppearance app = new ShaderAppearance();
+ app.setShaderProgram(shaderProgram);
+
+ this.setGeometry(tri);
+
+ this.setAppearance(app);
+ }
+ else
+ {
+ this.setGeometry(tri);
+ this.setAppearance(new Appearance());
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------
+
+ /** 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;
+
+ mainPanel = new javax.swing.JPanel();
+ guiPanel = new javax.swing.JPanel();
+ vertexCheckBoxPanel = new javax.swing.JPanel();
+ jPanel1 = new javax.swing.JPanel();
+ jSeparator1 = new javax.swing.JSeparator();
+ jSeparator2 = new javax.swing.JSeparator();
+ jPanel2 = new javax.swing.JPanel();
+ vertexAttrsBox = new javax.swing.JCheckBox();
+ geometryPanel = new javax.swing.JPanel();
+ createButton = new javax.swing.JButton();
+ destroyButton = 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("VertexAttrTestGLSL");
+ addWindowListener(new java.awt.event.WindowAdapter() {
+ @Override
+ public void windowClosing(java.awt.event.WindowEvent evt)
+ {
+ exitForm(evt);
+ }
+ });
+
+ mainPanel.setLayout(new java.awt.BorderLayout());
+
+ guiPanel.setLayout(new java.awt.GridBagLayout());
+
+ guiPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
+ vertexCheckBoxPanel.setLayout(new java.awt.GridBagLayout());
+
+ vertexCheckBoxPanel.setBorder(
+ javax.swing.BorderFactory.createTitledBorder(null, "vertexFormat", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
+ javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Lucida Sans", 0, 10)));
+ jPanel1.setLayout(new java.awt.GridBagLayout());
+
+ jSeparator1.setPreferredSize(new java.awt.Dimension(0, 4));
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ jPanel1.add(jSeparator1, gridBagConstraints);
+
+ jSeparator2.setPreferredSize(new java.awt.Dimension(0, 4));
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ jPanel1.add(jSeparator2, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
+ vertexCheckBoxPanel.add(jPanel1, gridBagConstraints);
+
+ jPanel2.setLayout(new java.awt.GridBagLayout());
+
+ vertexAttrsBox.setSelected(true);
+ vertexAttrsBox.setText("VertexAttrs");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ jPanel2.add(vertexAttrsBox, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
+ vertexCheckBoxPanel.add(jPanel2, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
+ guiPanel.add(vertexCheckBoxPanel, gridBagConstraints);
+
+ geometryPanel.setLayout(new java.awt.GridBagLayout());
+
+ createButton.setText("Create Geometry");
+ createButton.addActionListener(new java.awt.event.ActionListener() {
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ createButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ geometryPanel.add(createButton, gridBagConstraints);
+
+ destroyButton.setText("Destroy Geometry");
+ destroyButton.addActionListener(new java.awt.event.ActionListener() {
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt)
+ {
+ destroyButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
+ geometryPanel.add(destroyButton, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
+ guiPanel.add(geometryPanel, gridBagConstraints);
+
+ 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() {
+ @Override
+ 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 destroyButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {//GEN-FIRST:event_destroyButtonActionPerformed
+ if (scene != null)
+ {
+ univ.getLocale().removeBranchGraph(scene);
+ scene = null;
+ }
+ }//GEN-LAST:event_destroyButtonActionPerformed
+
+ private void createButtonActionPerformed(java.awt.event.ActionEvent evt)
+ {//GEN-FIRST:event_createButtonActionPerformed
+ if (scene == null)
+ {
+ boolean hasVertexAttrs = vertexAttrsBox.isSelected();
+ scene = createSceneGraph(hasVertexAttrs);
+ univ.addBranchGraph(scene);
+ }
+ }//GEN-LAST:event_createButtonActionPerformed
+
+ private static void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt)
+ {//GEN-FIRST:event_exitMenuItemActionPerformed
+ System.exit(0);
+ }//GEN-LAST:event_exitMenuItemActionPerformed
+
+ /** Exit the Application */
+ private static 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[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend","jogl2es2");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ new VertexAttrTestGLSL().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton createButton;
+ private javax.swing.JButton destroyButton;
+ private javax.swing.JPanel drawingPanel;
+ private javax.swing.JMenuItem exitMenuItem;
+ private javax.swing.JMenu fileMenu;
+ private javax.swing.JPanel geometryPanel;
+ private javax.swing.JPanel guiPanel;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JSeparator jSeparator1;
+ private javax.swing.JSeparator jSeparator2;
+ private javax.swing.JPanel mainPanel;
+ private javax.swing.JCheckBox vertexAttrsBox;
+ private javax.swing.JPanel vertexCheckBoxPanel;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.frag
new file mode 100644
index 0000000..030b811
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.frag
@@ -0,0 +1,56 @@
+//
+// 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;
+
+ // GL2ES2: gl_FragColor is unchanged
+ gl_FragColor = vec4 (color, 1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.vert
new file mode 100644
index 0000000..9b96195
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/aabrick.vert
@@ -0,0 +1,64 @@
+//
+// 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
+//
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewMatrix;
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat3 glNormalMatrix;
+
+
+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)
+{
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec3 ecPosition = vec3 (gl_ModelViewMatrix * gl_Vertex);
+ vec3 ecPosition = vec3 (glModelViewMatrix * glVertex);
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec3 tnorm = normalize(gl_NormalMatrix * glNormal);
+ vec3 tnorm = normalize(glNormalMatrix * glNormal);
+
+
+ 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;
+
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //MCposition = gl_Vertex.xy;
+ MCposition = glVertex.xy;
+
+ // GL2ES2: ftransform() no longer exists, but it is simple (note use of Java3D built-in uniforms and attributes)
+ // GL2ES2: gl_Position is unchanged
+ //gl_Position = ftransform();
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.frag
new file mode 100644
index 0000000..b2a2ef7
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.frag
@@ -0,0 +1,68 @@
+
+//
+// dimple.frag: Fragment shader for bump mapping dimples (bumps)
+//
+// author: John Kessenich
+//
+// Copyright (c) 2002: 3Dlabs, Inc.
+//
+//
+
+// GL2ES2: non buit-in varyings
+varying vec2 glTexCoord0;
+varying vec4 C;
+
+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;
+
+ // GL2ES2: non buit-in varying
+ vec2 c = Density * (glTexCoord0.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));
+ // GL2ES2: gl_FragColor is unchanged, C is a non built-in varying
+ gl_FragColor = vec4(litColor, C.a);
+// gl_FragColor = vec4(litColor, 1.0);
+// gl_FragColor = vec4(Scale);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.vert
new file mode 100644
index 0000000..ebbfdc9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/dimple.vert
@@ -0,0 +1,75 @@
+#version 120
+//
+// dimple.vert: Vertex shader for bump mapping dimples (bumps)
+//
+// author: John Kessenich
+//
+// Copyright (c) 2002: 3Dlabs, Inc.
+//
+
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+attribute vec4 glColor;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewMatrix;
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat3 glNormalMatrix;
+
+uniform int ignoreVertexColors;
+
+// GL2ES2: new output varyings, these replace gl_TexCoord[] and gl_FrontColor (along with A and D)
+varying vec2 glTexCoord0;
+varying vec4 C;
+
+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)
+{
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ vec4 pos = glModelViewMatrix * glVertex;
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+ vec3 eyeDir = vec3(pos);
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ // GL2ES2: swap built-in varying for declared varying
+ //gl_TexCoord[0] = gl_MultiTexCoord0;
+ glTexCoord0 = glVertex.xy;
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ // GL2ES2: swap built-in varying for declared varying
+ //gl_FrontColor = gl_Color;
+
+ if( ignoreVertexColors != 0)
+ C = vec4(1,1,1,1);
+ else
+ C = glColor;
+
+ vec3 n = normalize(glNormalMatrix * glNormal);
+ 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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.frag
new file mode 100644
index 0000000..3e298f8
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.frag
@@ -0,0 +1,61 @@
+//
+// Fragment shader for environment mapping with an
+// equirectangular 2D texture
+//
+// Authors: John Kessenich, Randi Rost
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+const vec3 Xunitvec = vec3 (1.0, 0.0, 0.0);
+const vec3 Yunitvec = vec3 (0.0, 1.0, 0.0);
+
+uniform vec3 BaseColor;
+uniform float MixRatio;
+
+uniform sampler2D EnvMap;
+
+varying vec3 Normal;
+varying vec3 EyeDir;
+varying float LightIntensity;
+
+void main (void)
+{
+ // Compute reflection vector
+ vec3 reflectDir = reflect(EyeDir, Normal);
+
+ // Compute altitude and azimuth angles
+
+ vec2 index;
+
+ index.y = dot(normalize(reflectDir), Yunitvec);
+ reflectDir.y = 0.0;
+ index.x = dot(normalize(reflectDir), Xunitvec) * 0.5;
+
+ // Translate index values into proper range
+
+ if (reflectDir.z >= 0.0)
+ index = (index + 1.0) * 0.5;
+ else
+ {
+ index.t = (index.t + 1.0) * 0.5;
+ index.s = (-index.s) * 0.5 + 1.0;
+ }
+
+ // if reflectDir.z >= 0.0, s will go from 0.25 to 0.75
+ // if reflectDir.z < 0.0, s will go from 0.75 to 1.25, and
+ // that's OK, because we've set the texture to wrap.
+
+ // Do a lookup into the environment map.
+
+ vec3 envColor = vec3 (texture2D(EnvMap, index));
+
+ // Add lighting to base color and mix
+
+ vec3 base = LightIntensity * BaseColor;
+ envColor = mix(envColor, base, MixRatio);
+
+ gl_FragColor = vec4 (envColor, 1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.vert
new file mode 100644
index 0000000..2296c83
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/envmap.vert
@@ -0,0 +1,46 @@
+//
+// Vertex shader for environment mapping with an
+// equirectangular 2D texture
+//
+// Authors: John Kessenich, Randi Rost
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewMatrix;
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat3 glNormalMatrix;
+
+
+varying vec3 Normal;
+varying vec3 EyeDir;
+varying float LightIntensity;
+
+uniform vec3 LightPos;
+
+void main(void)
+{
+ // GL2ES2: ftransform() no longer exists, but it is simple (note use of Java3D built-in uniforms and attributes)
+ // GL2ES2: gl_Position is unchanged
+ //gl_Position = ftransform();
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+
+ // compute the transformed normal
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec3 Normal = normalize(gl_NormalMatrix * gl_Normal);
+ Normal = normalize(glNormalMatrix * glNormal);
+
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec4 pos = gl_ModelViewMatrix * gl_Vertex;
+ vec4 pos = glModelViewMatrix * glVertex;
+
+ EyeDir = pos.xyz;
+ LightIntensity = max(dot(normalize(LightPos - EyeDir), Normal), 0.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/fixed_function_shader.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/fixed_function_shader.frag
new file mode 100644
index 0000000..3da3ef6
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/fixed_function_shader.frag
@@ -0,0 +1,108 @@
+#version 140
+
+precision mediump float;
+
+
+uniform int alphaTestEnabled;
+uniform int alphaTestFunction;
+uniform float alphaTestValue;
+
+struct fogData
+{
+ int fogEnabled;
+ vec4 expColor;
+ float expDensity;
+ vec4 linearColor;
+ float linearStart;
+ float linearEnd;
+};
+uniform fogData fogData;
+
+in vec2 glTexCoord0;
+
+uniform sampler2D BaseMap;
+
+in vec3 LightDir;
+in vec3 ViewDir;
+
+in vec3 N;
+
+in vec4 A;
+in vec4 C;
+in vec4 D;
+in vec3 S;
+in vec3 emissive;
+
+in float shininess;
+
+out vec4 glFragColor;
+
+void main( void )
+{
+ vec4 baseMap = texture( BaseMap, glTexCoord0.st );
+
+ //web says the keyword discard in a shader is bad
+ //I could just gl_FragColor=vec(0,0,0,0); return;
+ if(alphaTestEnabled != 0)
+ {
+ if(alphaTestFunction==516)//>
+ if(baseMap.a<=alphaTestValue)discard;
+ else if(alphaTestFunction==518)//>=
+ if(baseMap.a<alphaTestValue)discard;
+ else if(alphaTestFunction==514)//==
+ if(baseMap.a!=alphaTestValue)discard;
+ else if(alphaTestFunction==517)//!=
+ if(baseMap.a==alphaTestValue)discard;
+ else if(alphaTestFunction==513)//<
+ if(baseMap.a>=alphaTestValue)discard;
+ else if(alphaTestFunction==515)//<=
+ if(baseMap.a>alphaTestValue)discard;
+ else if(alphaTestFunction==512)//never
+ discard;
+ }
+
+ vec3 normal = N;
+
+ vec3 L = normalize(LightDir);
+ vec3 E = normalize(ViewDir);
+ vec3 R = reflect(-L, normal);
+ vec3 H = normalize( L + E );
+
+ float NdotL = max( dot(normal, L), 0.0 );
+ float NdotH = max( dot(normal, H), 0.0 );
+ float EdotN = max( dot(normal, E), 0.0 );
+ float NdotNegL = max( dot(normal, -L), 0.0 );
+
+ vec4 color;
+ vec3 albedo = baseMap.rgb * C.rgb;
+ vec3 diffuse = A.rgb + (D.rgb * NdotL);
+
+ // Specular
+ vec3 spec = S * pow(NdotH, 0.3*shininess);
+
+ color.rgb = albedo * (diffuse + emissive) + spec;
+ color.a = C.a * baseMap.a;
+
+ if(fogData.fogEnabled == 1)
+ {
+ //compute distance used in fog equations
+ float dist = length(ViewVec);
+ float fogFactor = 0.0;
+
+ if(fogData.linearEnd > 0.0)//linear fog
+ {
+ fogFactor = 1.0-((fogData.linearEnd - dist)/(fogData.linearEnd - fogData.linearStart));
+ fogFactor = clamp( fogFactor, 0.0, 1.0 );
+ color = mix(color, fogData.linearColor, fogFactor);
+ }
+ else if( fogData.expDensity > 0.0)// exponential fog
+ {
+ fogFactor = 1.0-(1.0 /exp(dist * fogData.expDensity));
+ fogFactor = clamp( fogFactor, 0.0, 1.0 );
+ color = mix(color, fogData.expColor, fogFactor);
+ }
+ color.a = color.a + fogFactor;
+ }
+
+ glFragColor = color;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/fixed_function_shader.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/fixed_function_shader.vert
new file mode 100644
index 0000000..354c004
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/fixed_function_shader.vert
@@ -0,0 +1,142 @@
+#version 150
+
+in vec4 glVertex;
+in vec4 glColor;
+in vec3 glNormal;
+in vec2 glMultiTexCoord0;
+
+uniform mat4 glProjectionMatrix;
+//uniform mat4 glProjectionMatrixInverse;
+uniform mat4 glViewMatrix;
+uniform mat4 glModelMatrix;
+//uniform mat4 glModelViewMatrix;
+//uniform mat4 glModelViewMatrixInverse;
+//uniform mat4 glModelViewProjectionMatrix;
+
+//uniform mat3 glNormalMatrix;
+
+uniform int ignoreVertexColors;
+
+uniform vec4 glLightModelambient;
+
+struct material
+{
+ int lightEnabled;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 emission;
+ vec3 specular;
+ float shininess;
+};
+uniform material glFrontMaterial;
+
+struct lightSource
+{
+ int enabled;
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ float constantAttenuation, linearAttenuation, quadraticAttenuation;
+ float spotCutoff, spotExponent;
+ vec3 spotDirection;
+};
+
+uniform int numberOfLights;// numberOfLights will be set to how many the pipeline can send
+const int maxLights = 1;// this is for the shader, it will process no more than this, must be a const
+uniform lightSource glLightSource[maxLights];
+
+uniform mat4 textureTransform;
+
+// alpha testing is normally done in frag versus the texture alpha
+//uniform int alphaTestEnabled;
+//uniform int alphaTestFunction;
+//uniform float alphaTestValue;
+
+
+// struct fogData
+// {
+// int fogEnabled = -1;
+// vec4 expColor;
+// float expDensity;
+// vec4 linearColor;
+// float linearStart;
+// float linearEnd;
+// };
+// uniform fogData fogData;
+
+
+// Fixed function pipeline pre-calculated values not available:
+// Note:
+// A,D,S = Ambient,Diffuse,Specular
+// cm, cli = glFrontMaterial, glLightSource
+
+
+// gl_LightSource[i].halfVector
+// http://stackoverflow.com/questions/3744038/what-is-half-vector-in-modern-glsl
+// vec3 ecPos = vec3(glModelViewMatrix * glVertex);
+// vec3 ecL;
+// if( glLightSource[i].position.w == 0.0)
+// ecL = vec3(glLightSource0position.xyz);// no -ecPos in case of dir lights?
+// else
+// ecL = vec3(glLightSource0position.xyz - ecPos);
+// vec3 L = normalize(ecL.xyz);
+// vec3 V = -ecPos.xyz;
+// vec3 halfVector = normalize(L + V);
+
+//gl_LightSource[i].ambient
+//use glLightModelambient
+
+// gl_FrontLightModelProduct.sceneColor
+// Derived. Ecm + Acm * Acs (Acs is normal glLightModelambient)
+// use vec4 sceneColor = glFrontMaterial.emission + glFrontMaterial.ambient * glLightModelambient;
+
+
+//gl_FrontLightProduct[i]
+//vec4 ambient; // Acm * Acli (Acli does not exist use glLightModelambient)
+//vec4 diffuse; // Dcm * Dcli
+//vec4 specular; // Scm * Scli
+// calculate yourself
+
+
+out vec2 glTexCoord0;
+
+out vec3 LightDir;
+out vec3 ViewVec;
+
+out vec3 N;
+
+out vec4 A;
+out vec4 C;
+out vec4 D;
+out vec3 S;
+out vec3 E;
+
+out float shininess;
+
+void main( void )
+{
+ mat4 glModelViewMatrix = glViewMatrix * glModelMatrix;
+ gl_Position = glProjectionMatrix * glModelViewMatrix * glVertex;//glModelViewProjectionMatrix * glVertex;
+
+ glTexCoord0 = (textureTransform * vec4(glMultiTexCoord0,0,1)).st;
+
+ mat3 glNormalMatrix = mat3(transpose(inverse(glModelViewMatrix)));
+ N = normalize(glNormalMatrix * glNormal);
+
+ vec3 v = vec3(glModelViewMatrix * glVertex);
+
+ ViewVec = -v.xyz;
+ LightDir = glLightSource[0].position.xyz;
+
+ A = glLightModelambient;
+ if( ignoreVertexColors != 0)
+ C = vec4(1,1,1,1);//glFrontMaterialdiffuse; // objectColor should be used if it is no lighting
+ else
+ C = glColor;
+ D = glLightSource[0].diffuse * glFrontMaterial.diffuse;
+ S = glLightSource[0].specular.rgb * glFrontMaterial.specular;
+ E = glFrontMaterial.emission.rgb;
+
+ shininess = glFrontMaterial.shininess;
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.frag
new file mode 100644
index 0000000..c02a268
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.frag
@@ -0,0 +1,54 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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
+
+//GL2ES2: varying color data needs to be defined
+varying vec4 glFrontColor;
+varying vec4 glFrontSecondaryColor;
+
+void main()
+{
+ gl_FragColor = glFrontColor + glFrontSecondaryColor;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.vert
new file mode 100644
index 0000000..771afce
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/gouraud.vert
@@ -0,0 +1,158 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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).
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewMatrix;
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat3 glNormalMatrix;
+
+
+
+uniform vec4 glLightModelambient;
+
+struct material
+{
+ int lightEnabled;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 emission;// note vec4 extra 1.0 sent through for ease
+ vec3 specular;
+ float shininess;
+};
+uniform material glFrontMaterial;
+
+struct lightSource
+{
+ int enabled;
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ float constantAttenuation, linearAttenuation, quadraticAttenuation;
+ float spotCutoff, spotExponent;
+ vec3 spotDirection;
+};
+
+uniform int numberOfLights;
+const int maxLights = 1;
+uniform lightSource glLightSource[maxLights];
+
+//GL2ES2: varying color data needs to be defined
+varying vec4 glFrontColor;
+varying vec4 glFrontSecondaryColor;
+
+void directionalLight0(
+ in vec3 normal,
+ inout vec4 ambient,
+ inout vec4 diffuse,
+ inout vec3 specular)
+{
+ // Normalized light direction and half vector
+ vec3 lightDirection = normalize(vec3(glLightSource[0].position));
+
+ //GL2ES2: half vector must be calculated
+ //vec3 halfVector = normalize(vec3(gl_LightSource[0].halfVector));
+ //http://stackoverflow.com/questions/3744038/what-is-half-vector-in-modern-glsl
+ vec3 ecPos = vec3(glModelViewMatrix * glVertex);
+ vec3 ecL;
+ if( glLightSource[0].position.w == 0.0)
+ ecL = vec3(glLightSource[0].position.xyz);// no -ecPos in case of dir lights?
+ else
+ ecL = vec3(glLightSource[0].position.xyz - ecPos);
+ vec3 L = normalize(ecL.xyz);
+ vec3 V = -ecPos.xyz;
+ vec3 halfVector = normalize(L + V);
+
+ 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, glFrontMaterial.shininess);
+ }
+
+ ambient += glLightModelambient;
+ diffuse += glLightSource[0].diffuse * nDotVP;
+ specular += glFrontMaterial.specular * pf;
+}
+
+
+void main()
+{
+ vec3 tnorm = normalize(vec3(glNormalMatrix * glNormal));
+ vec4 amb = vec4(0.0);
+ vec4 diff = vec4(0.0);
+ vec3 spec = vec3(0.0);
+ int i;
+
+ // Transform the vertex
+ vec4 outPosition = glModelViewProjectionMatrix * glVertex;
+
+ directionalLight0(tnorm, amb, diff, spec);
+
+ //GL2ES2: sceneColor Derived. Ecm + Acm * Acs (Acs is normal glLightModelambient)
+ vec4 sceneColor = glFrontMaterial.emission + glFrontMaterial.ambient * glLightModelambient;
+
+ // Apply the result of the lighting equation
+ vec4 outSecondaryColor = vec4(vec3(spec * glFrontMaterial.specular), 1.0);
+ vec4 outColor = vec4(vec3( sceneColor +
+ amb * glFrontMaterial.ambient +
+ diff * glFrontMaterial.diffuse), 1.0);
+
+ glFrontColor = outColor;
+ glFrontSecondaryColor = outSecondaryColor;
+ gl_Position = outPosition;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.frag
new file mode 100644
index 0000000..db24f68
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.frag
@@ -0,0 +1,67 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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$
+ */
+
+uniform float cloudFactor;
+uniform sampler2D earthTex;
+uniform sampler2D cloudTex;
+
+uniform sampler2D EnvMap;
+
+varying vec2 texCoord0;
+varying vec2 texCoord1;
+
+void main (void)
+{
+ vec2 tc0 = texCoord0.xy;
+ vec2 tc1 = texCoord1.xy;
+
+ vec3 color0 = vec3(texture2D(cloudTex, tc0));
+ vec3 color1 = vec3(texture2D(earthTex, tc1));
+ vec3 finalColor = color0*cloudFactor + color1;
+
+ gl_FragColor = vec4(finalColor, 1.0);
+
+ // if(tc1.x > 0.0)
+ // gl_FragColor = vec4(tc1.y,0.0,0.0,1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.vert
new file mode 100644
index 0000000..5c25c11
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/multitex.vert
@@ -0,0 +1,68 @@
+// tex coord gen sample from http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59737
+
+
+
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat4 glModelViewMatrix;
+uniform mat3 glNormalMatrix;
+
+// Per-pixel normal (output to fragment shader)
+varying vec3 Normal;
+
+varying vec2 texCoord0;
+varying vec2 texCoord1;
+
+ //Example 8-4 Sphere Map Texture Coordinate Generation
+ // position is the normalized position coordinate in eye space
+ // normal is the normalized normal coordinate in eye space
+ // returns a vec2 texture coordinate
+vec2 sphere_map(vec3 position, vec3 normal)
+{
+ vec3 reflection = reflect(position, normal);
+ float m = 2.0 * sqrt(reflection.x * reflection.x + reflection.y * reflection.y + (reflection.z + 1.0) * (reflection.z + 1.0));
+ return vec2((reflection.x / m + 0.5), (reflection.y / m + 0.5));
+}
+
+ //Example 8-5 Cube Map Texture Coordinate Generation
+
+ // position is the normalized position coordinate in eye space
+ // normal is the normalized normal coordinate in eye space
+ // returns the reflection vector as a vec3 texture coordinate
+vec3 cube_map(vec3 position, vec3 normal)
+{
+ return reflect(position, normal);
+}
+
+//Object Linear Mapping
+//When the texture generation mode is set to GL_OBJECT_LINEAR, texture coordinates are generated using the following function:
+//coord = P1*X + P2*Y + P3*Z + P4*W
+// The X, Y, Z, and W values are the vertex coordinates from the object being textured, and the P1–P4 values are the coefficients for a plane equation.
+
+//For this shader in my code I have:
+//Vector4f plane0S = new Vector4f(3.0f, 1.5f, 0.3f, 0.0f); //to calc coord S
+//Vector4f plane0T = new Vector4f(1.0f, 2.5f, 0.24f, 0.0f); //to calc coord T
+//I could hand them is as uniforms, but I choose to hard code them
+
+
+vec2 object_linear(vec4 pos, vec4 planeOS, vec4 planeOT)
+{
+ return vec2(pos.x*planeOS.x+pos.y*planeOS.y+pos.z*planeOS.z+ pos.w*planeOS.w,pos.x*planeOT.x+pos.y*planeOT.y+pos.z*planeOT.z+pos.w*planeOT.w);
+}
+
+
+void main()
+{
+ Normal = normalize(vec3(glNormalMatrix * glNormal));
+
+ // Transform the vertex
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+
+ texCoord0 = object_linear(glVertex, vec4(3.0, 1.5, 0.3, 0.0),vec4(1.0, 2.5, 0.24, 0.0));
+ texCoord1 = sphere_map(normalize(vec3(glModelViewMatrix*glVertex)), Normal);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/phong.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/phong.frag
new file mode 100644
index 0000000..7cb6388
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/phong.frag
@@ -0,0 +1,154 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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)
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewMatrix;
+
+
+
+uniform vec4 glLightModelambient;
+
+struct material
+{
+ int lightEnabled;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 emission;
+ vec3 specular;
+ float shininess;
+};
+uniform material glFrontMaterial;
+
+struct lightSource
+{
+ int enabled;
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ float constantAttenuation, linearAttenuation, quadraticAttenuation;
+ float spotCutoff, spotExponent;
+ vec3 spotDirection;
+};
+
+uniform int numberOfLights;
+const int maxLights = 1;
+uniform lightSource glLightSource[maxLights];
+
+varying vec3 worldPos;
+
+varying vec4 sceneColor;
+
+void directionalLight0(in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec3 specular)
+{
+ // Normalized light direction and half vector
+ vec3 lightDirection = normalize(vec3(glLightSource[0].position));
+
+
+ //GL2ES2: half vector must be calculated
+ //vec3 halfVector = normalize(vec3(gl_LightSource[0].halfVector));
+ //http://stackoverflow.com/questions/3744038/what-is-half-vector-in-modern-glsl
+ vec3 ecPos = vec3(glModelViewMatrix * vec4(worldPos,1.0));
+ vec3 ecL;
+ if( glLightSource[0].position.w == 0.0)
+ ecL = vec3(glLightSource[0].position.xyz);// no -ecPos in case of dir lights?
+ else
+ ecL = vec3(glLightSource[0].position.xyz - ecPos);
+ vec3 L = normalize(ecL.xyz);
+ vec3 V = -ecPos.xyz;
+ vec3 halfVector = normalize(L + V);
+
+
+ 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, glFrontMaterial.shininess);
+ }
+
+ // GL2ES2: ambient is part of light model
+ //ambient += gl_LightSource[0].ambient;
+ ambient += glLightModelambient;
+ diffuse += glLightSource[0].diffuse * nDotVP;
+
+ // GL2ES2: specular is part of material
+ //specular += gl_LightSource[0].specular * pf;
+ specular += glFrontMaterial.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);
+ vec3 spec = vec3(0.0);
+ int i;
+
+
+ directionalLight0(unitNorm, amb, diff, spec);
+
+
+ // Apply the result of the lighting equation
+ vec4 secondaryColor = vec4(spec * glFrontMaterial.specular, 1.0);
+ // GL2ES2: change to calc'ed sceneColor
+ //vec4 color = vec4(vec3(gl_FrontLightModelProduct.sceneColor +
+ vec4 color = vec4(vec3(sceneColor +
+ amb * glLightModelambient +
+ diff * glFrontMaterial.diffuse), 1.0);
+
+ gl_FragColor = color + secondaryColor;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/phong.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/phong.vert
new file mode 100644
index 0000000..780c2bd
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/phong.vert
@@ -0,0 +1,89 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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)
+
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat4 glModelViewMatrix;
+uniform mat3 glNormalMatrix;
+
+uniform vec4 glLightModelambient;
+
+struct material
+{
+ int lightEnabled;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 emission;
+ vec3 specular;
+ float shininess;
+};
+uniform material glFrontMaterial;
+
+// Per-pixel normal (output to fragment shader)
+varying vec3 Normal;
+varying vec3 worldPos;
+
+varying vec4 sceneColor;
+
+
+void main()
+{
+
+ //GL2ES2: sceneColor Derived. Ecm + Acm * Acs (Acs is normal glLightModelambient)
+ sceneColor = glFrontMaterial.emission + glFrontMaterial.ambient * glLightModelambient;
+
+ Normal = normalize(vec3(glNormalMatrix * glNormal));
+
+ worldPos = vec3(glModelViewMatrix * glVertex);
+
+ // Transform the vertex
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.frag
new file mode 100644
index 0000000..605cb5f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.frag
@@ -0,0 +1,49 @@
+//
+// 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
+ // GL2ES2: gl_FragColor is unchanged
+ gl_FragColor = clamp((vec4( finalcolor, 1.0 ) * LightIntensity), vec4(0.0), vec4(1.0));
+}
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.vert
new file mode 100644
index 0000000..0422670
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/polkadot3d.vert
@@ -0,0 +1,75 @@
+// This is the Vertex Shader for three dimensional polka dots.
+//
+// author(s): Joshua Doss
+//
+// Copyright (C) 2002-2004 3Dlabs Inc. Ltd.
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewMatrix;
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat3 glNormalMatrix;
+
+//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
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
+ vec3 ecPosition = vec3(glModelViewMatrix * glVertex);
+
+ // compute the transformed normal
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
+ vec3 tnorm = normalize(glNormalMatrix * glNormal);
+
+ // 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
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //MCPosition = vec3 (gl_Vertex);
+ MCPosition = vec3 (glVertex);
+
+ // send vertex information
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+}
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/simple.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/simple.frag
new file mode 100644
index 0000000..092a110
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/simple.frag
@@ -0,0 +1,68 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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
+
+//GL2ES2: varying color data needs to be defined
+varying vec4 glFrontColor;
+varying vec4 glFrontSecondaryColor;
+
+//GL2ES2: see particle system point size for mechanism
+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]
+ //GL2ES2: gl_FragCoord still exists
+ 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 = (glFrontColor + glFrontSecondaryColor) * atten;
+
+ gl_FragColor = outcolor;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/simple.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/simple.vert
new file mode 100644
index 0000000..4c5f3c9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/simple.vert
@@ -0,0 +1,189 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+attribute vec4 glColor;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewMatrix;
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat3 glNormalMatrix;
+
+uniform vec4 glLightModelambient;
+
+
+struct material
+{
+ int lightEnabled;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 emission;
+ vec3 specular;
+ float shininess;
+};
+uniform material glFrontMaterial;
+
+struct lightSource
+{
+ int enabled;
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ float constantAttenuation, linearAttenuation, quadraticAttenuation;
+ float spotCutoff, spotExponent;
+ vec3 spotDirection;
+};
+
+uniform int numberOfLights;
+const int maxLights = 1;
+uniform lightSource glLightSource[maxLights];
+
+//GL2ES2: varying color data needs to be defined
+varying vec4 glFrontColor;
+varying vec4 glFrontSecondaryColor;
+
+void directionalLight(
+ in int i,
+ in vec3 normal,
+ inout vec4 ambient,
+ inout vec4 diffuse,
+ inout vec3 specular)
+{
+ // Normalized light direction and half vector
+ // (shouldn't they be pre-normalized?!)
+
+ //GL2ES2 notice not using the i parameter but hard coded to 0
+ vec3 lightDirection = normalize(vec3(glLightSource[0].position));
+
+ //GL2ES2: half vector must be calculated
+ //vec3 halfVector = normalize(vec3(gl_LightSource[0].halfVector));
+ vec3 worldPos = vec3(glModelViewMatrix * glVertex);
+ vec3 L = normalize(glLightSource[0].position.xyz - worldPos);
+ vec3 V = vec3(0,0,1);//eye position
+ vec3 halfVector = (L + V);
+
+
+
+ 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, glFrontMaterial.shininess);
+ }
+
+ ambient += glLightModelambient;
+ diffuse += glLightSource[0].diffuse * nDotVP;
+ specular += glFrontMaterial.specular * pf;
+}
+
+//GL2ES2: only a single light for now
+const int numEnabledLights = 1; // TODO: this should be a built-in parameter!
+
+void main()
+{
+ //vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
+ //vec3 ecPosition3 = ecPosition.xyz / ecPosition.w;
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec3 tnorm = normalize(vec3(gl_NormalMatrix * gl_Normal));
+ vec3 tnorm = normalize(vec3(glNormalMatrix * glNormal));
+ vec4 amb = vec4(0.0);
+ vec4 diff = vec4(0.0);
+ vec3 spec = vec3(0.0);
+ int i;
+
+ // Transform the vertex
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec4 outPosition = gl_ModelViewProjectionMatrix * gl_Vertex;
+ vec4 outPosition = glModelViewProjectionMatrix * glVertex;
+
+ for (i = 0; i < numEnabledLights; i++) {
+ directionalLight(i, tnorm, amb, diff, spec);
+ }
+
+ //GL2ES2: sceneColor Derived. Ecm + Acm * Acs (Acs is normal glLightModelambient)
+ vec4 sceneColor = glFrontMaterial.emission + glFrontMaterial.ambient * glLightModelambient;
+
+ // Apply the result of the lighting equation
+ vec4 outSecondaryColor = vec4(vec3(spec * glFrontMaterial.specular), 1.0);
+ vec3 color0 = vec3(sceneColor +
+ amb * glLightModelambient +
+ diff * glFrontMaterial.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);
+
+ glFrontColor = outColor;
+ glFrontSecondaryColor = outSecondaryColor;
+ gl_Position = outPosition;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/toon.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/toon.frag
new file mode 100644
index 0000000..fa50453
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/toon.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/toon.vert
new file mode 100644
index 0000000..d044af7
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/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/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.frag
new file mode 100644
index 0000000..029b044
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.frag
@@ -0,0 +1,52 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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$
+ */
+
+
+//GL2ES2: varying color data needs to be defined
+varying vec4 glFrontColor;
+
+void main()
+{
+ gl_FragColor = glFrontColor;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.vert
new file mode 100644
index 0000000..12f3662
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/vertexshader.vert
@@ -0,0 +1,70 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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$
+ */
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewProjectionMatrix;
+
+// A simple GLSL vertex program for demo. vertex attributes
+
+attribute float weight;
+attribute vec3 temperature;
+
+//GL2ES2: varying color data needs to be defined
+varying vec4 glFrontColor;
+
+void main()
+{
+ // Transform the vertex
+ vec4 outPosition = glModelViewProjectionMatrix * glVertex;
+
+ // Compute color from temperature
+ vec4 outColor;
+ outColor = vec4(temperature * weight, 1);
+ // Assign output parameters
+ glFrontColor = outColor;
+ gl_Position = outPosition;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/wood.frag b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/wood.frag
new file mode 100644
index 0000000..6686190
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/wood.frag
@@ -0,0 +1,67 @@
+//
+// 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);
+
+ // GL2ES2: gl_FragColor is unchanged
+ gl_FragColor = vec4(color, 1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/wood.vert b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/wood.vert
new file mode 100644
index 0000000..e04ba6d
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/gl2es2pipeline/wood.vert
@@ -0,0 +1,43 @@
+//
+// Simple vertex shader for wood
+//
+// Author: John Kessenich
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewMatrix;
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat3 glNormalMatrix;
+
+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)
+{
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec4 pos = glModelViewMatrix * glVertex;
+ vec4 pos = glModelViewMatrix * glVertex;
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //Position = vec3(glVertex) * Scale;
+ Position = vec3(glVertex) * Scale;
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
+ vec3 tnorm = normalize(glNormalMatrix * glNormal);
+ lightIntensity = max(dot(normalize(LightPosition - vec3(pos)), tnorm), 0.0) * 1.5;
+
+ // GL2ES2: swap built-in variable for Java3d built-in uniforms and attributes gl_* = gl* + declaration (at top)
+ //gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/glsl_shader/EnvironmentMappingGLSL.form b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/EnvironmentMappingGLSL.form
new file mode 100644
index 0000000..b6a3e94
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/EnvironmentMappingGLSL.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="EnvironmentMappingGLSL"/>
+ </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/main/java/org/jdesktop/j3d/examples/glsl_shader/EnvironmentMappingGLSL.java b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/EnvironmentMappingGLSL.java
new file mode 100644
index 0000000..ff5e9cd
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/EnvironmentMappingGLSL.java
@@ -0,0 +1,261 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttribute;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureUnitState;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+
+public class EnvironmentMappingGLSL extends javax.swing.JFrame {
+
+ private URL textureURL = null;
+ private static final int NUM_TEX_UNITS = 1;
+ private static final int TEX_UNIT = 0;
+
+ SimpleUniverse univ = 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 texture object
+ textureURL = Resources.getResource("resources/images/duke-gears.jpg");
+ Texture tex = new TextureLoader(textureURL, this).getTexture();
+ // Create the shader program
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try {
+ vertexProgram = StringIO.readFully(Resources.getResource("glsl_shader/envmap.vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/envmap.frag"));
+ }
+ catch (IOException e) {
+ System.err.println(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);
+ final String[] shaderAttrNames = {
+ "LightPos",
+ "BaseColor",
+ "MixRatio",
+ "EnvMap",
+ };
+ final Object[] shaderAttrValues = {
+ new Point3f(1.0f, -1.0f, 2.0f),
+ new Color3f(0.2f, 0.9f, 0.5f),
+ new Float(0.4f),
+ new Integer(TEX_UNIT),
+ };
+ ShaderProgram shaderProgram = new GLSLShaderProgram();
+ shaderProgram.setShaders(shaders);
+ shaderProgram.setShaderAttrNames(shaderAttrNames);
+
+ // Create the shader attribute set
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ for (int i = 0; i < shaderAttrNames.length; i++) {
+ ShaderAttribute shaderAttribute =
+ new ShaderAttributeValue(shaderAttrNames[i], shaderAttrValues[i]);
+ shaderAttributeSet.put(shaderAttribute);
+ }
+
+ // Create shader appearance to hold the shader program and
+ // shader attributes
+ ShaderAppearance app = new ShaderAppearance();
+ app.setShaderProgram(shaderProgram);
+ app.setShaderAttributeSet(shaderAttributeSet);
+
+ // Put the texture in specified texture unit
+ TextureUnitState[] tus = new TextureUnitState[NUM_TEX_UNITS];
+ tus[TEX_UNIT] = new TextureUnitState();
+ tus[TEX_UNIT].setTexture(tex);
+ app.setTextureUnitState(tus);
+
+ // Create a Sphere object using the shader appearance,
+ // and add it into the scene graph.
+ Sphere sph = new Sphere(0.4f, Sphere.GENERATE_NORMALS, 20, app);
+ 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();
+ 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 initScene() {
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ BranchGroup scene = createSceneGraph();
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ public void errorOccurred(ShaderError error) {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(EnvironmentMappingGLSL.this,
+ error.toString(),
+ "ShaderError",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ univ.addBranchGraph(scene);
+
+ return c;
+ }
+
+ /**
+ * Creates new form EnvironmentMappingGLSL
+ */
+ public EnvironmentMappingGLSL() {
+ // 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() {
+ drawingPanel = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("EnvironmentMappingGLSL");
+ 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 EnvironmentMappingGLSL().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/main/java/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.form b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.form
new file mode 100644
index 0000000..343b6d5
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.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="ObjLoadGLSL"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java
new file mode 100644
index 0000000..2feb50a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java
@@ -0,0 +1,404 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Node;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.loaders.IncorrectFormatException;
+import org.jogamp.java3d.loaders.ParsingErrorException;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.objectfile.ObjectFile;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.PlatformGeometry;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program to display an .obj object with shader programs.
+ */
+public class ObjLoadGLSL extends javax.swing.JFrame {
+
+ 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 univ = null;
+ private BranchGroup scene = 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.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);
+ }
+
+ // Set vertex and fragment shader program for all Shape3D nodes in scene
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try {
+ vertexProgram = StringIO.readFully(Resources.getResource("glsl_shader/" + shaderName + ".vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/" + 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());
+
+ 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);
+
+ 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 canvas3d = new Canvas3D(config);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(canvas3d);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ public void errorOccurred(ShaderError error) {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(ObjLoadGLSL.this,
+ error.toString(),
+ "ShaderError",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = univ.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(canvas3d,
+ OrbitBehavior.REVERSE_ALL);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+ }
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return canvas3d;
+ }
+
+ 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
+
+ // 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);
+ }
+ }
+ }
+
+ /**
+ * Creates new form ObjLoadGLSL
+ */
+ 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) {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+ if (filename == null) {
+ filename = Resources.getResource("resources/geometry/galleon.obj");
+ if (filename == null) {
+ System.err.println("resources/geometry/galleon.obj not found");
+ System.exit(1);
+ }
+ }
+
+ // 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("ObjLoadGLSL");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ ObjLoadGLSL objLoadGLSL = new ObjLoadGLSL(args);
+ objLoadGLSL.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/main/java/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form
new file mode 100644
index 0000000..dcccf73
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java
new file mode 100644
index 0000000..45b4b94
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java
@@ -0,0 +1,492 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.SpotLight;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ *
+ * @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 univ = 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(Resources.getResource("glsl_shader/gouraud.vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/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(Resources.getResource("glsl_shader/phong.vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/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);
+
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ public void errorOccurred(ShaderError error) {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(PhongShadingGLSL.this,
+ error.toString(),
+ "ShaderError",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ univ.getViewingPlatform().setNominalViewingTransform();
+
+ BranchGroup scene = createSceneGraph();
+ univ.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/main/java/org/jdesktop/j3d/examples/glsl_shader/SamplerTestGLSL.form b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/SamplerTestGLSL.form
new file mode 100644
index 0000000..6a1a031
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/SamplerTestGLSL.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="SamplerTestGLSL"/>
+ </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/main/java/org/jdesktop/j3d/examples/glsl_shader/SamplerTestGLSL.java b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/SamplerTestGLSL.java
new file mode 100644
index 0000000..d2c3265
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/SamplerTestGLSL.java
@@ -0,0 +1,278 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttribute;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.TexCoordGeneration;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureUnitState;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector4f;
+
+public class SamplerTestGLSL extends javax.swing.JFrame {
+
+ private static String cloudTexName = "resources/images/bg.jpg";
+ private static String earthTexName = "resources/images/earth.jpg";
+ private static String fragmentProgName = "glsl_shader/multitex.frag";
+ private URL cloudURL = null;
+ private URL earthURL = null;
+ private static final int CLOUD = 0;
+ private static final int EARTH = 1;
+
+ SimpleUniverse univ = 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 texture objects
+ cloudURL = Resources.getResource(cloudTexName);
+ Texture cloudTex = new TextureLoader(cloudURL, this).getTexture();
+ earthURL = Resources.getResource(earthTexName);
+ Texture earthTex = new TextureLoader(earthURL, this).getTexture();
+
+ // Create the shader program
+ String vertexProgram = null;
+ String fragmentProgram = null;
+ try {
+ fragmentProgram = StringIO.readFully(Resources.getResource(fragmentProgName));
+ }
+ catch (IOException e) {
+ System.err.println(e);
+ }
+ Shader[] shaders = new Shader[1];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_FRAGMENT,
+ fragmentProgram);
+ final String[] shaderAttrNames = {
+ "cloudFactor",
+ "cloudTex",
+ "earthTex",
+ };
+ final Object[] shaderAttrValues = {
+ new Float(0.6f),
+ new Integer(0),
+ new Integer(1),
+ };
+ ShaderProgram shaderProgram = new GLSLShaderProgram();
+ shaderProgram.setShaders(shaders);
+ shaderProgram.setShaderAttrNames(shaderAttrNames);
+
+ // Create the shader attribute set
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ for (int i = 0; i < shaderAttrNames.length; i++) {
+ ShaderAttribute shaderAttribute =
+ new ShaderAttributeValue(shaderAttrNames[i], shaderAttrValues[i]);
+ shaderAttributeSet.put(shaderAttribute);
+ }
+
+ // Create shader appearance to hold the shader program and
+ // shader attributes
+ ShaderAppearance app = new ShaderAppearance();
+ app.setShaderProgram(shaderProgram);
+ app.setShaderAttributeSet(shaderAttributeSet);
+
+ // Setup texture coordinate generation
+ Vector4f plane0S = new Vector4f(3.0f, 1.5f, 0.3f, 0.0f);
+ Vector4f plane0T = new Vector4f(1.0f, 2.5f, 0.24f, 0.0f);
+ TexCoordGeneration tcg0 =
+ new TexCoordGeneration(TexCoordGeneration.OBJECT_LINEAR,
+ TexCoordGeneration.TEXTURE_COORDINATE_2, plane0S, plane0T);
+
+ // Setup texture coordinate generation
+ TexCoordGeneration tcg1 =
+ new TexCoordGeneration(TexCoordGeneration.SPHERE_MAP,
+ TexCoordGeneration.TEXTURE_COORDINATE_2);
+
+ // Put the textures in unit 0,1
+ TextureUnitState[] tus = new TextureUnitState[2];
+ tus[CLOUD] = new TextureUnitState();
+ tus[CLOUD].setTexture(cloudTex);
+ tus[CLOUD].setTexCoordGeneration(tcg0);
+ tus[EARTH] = new TextureUnitState();
+ tus[EARTH].setTexture(earthTex);
+ tus[EARTH].setTexCoordGeneration(tcg1);
+ app.setTextureUnitState(tus);
+
+ // Create a Sphere object using the shader appearance,
+ // and add it into the scene graph.
+ Sphere sph = new Sphere(0.4f, Sphere.GENERATE_NORMALS, 30, app);
+ 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();
+ 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 initScene() {
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ BranchGroup scene = createSceneGraph();
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ public void errorOccurred(ShaderError error) {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(SamplerTestGLSL.this,
+ error.toString(),
+ "ShaderError",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ univ.addBranchGraph(scene);
+
+ return c;
+ }
+
+ /**
+ * Creates new form SamplerTestGLSL
+ */
+ public SamplerTestGLSL() {
+ // 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() {
+ drawingPanel = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("SamplerTestGLSL");
+ 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 SamplerTestGLSL().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/main/java/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form
new file mode 100644
index 0000000..714273d
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java
new file mode 100644
index 0000000..f7f82e9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java
@@ -0,0 +1,707 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PositionInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttributeObject;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.View;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+
+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 univ = 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(Resources.getResource("glsl_shader/dimple.vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/dimple.frag"));
+ break;
+ case BRICK_SHADER:
+ vertexProgram = StringIO.readFully(Resources.getResource("glsl_shader/aabrick.vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/aabrick.frag"));
+ break;
+ case WOOD_SHADER:
+ vertexProgram = StringIO.readFully(Resources.getResource("glsl_shader/wood.vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/wood.frag"));
+ break;
+ case POLKADOT3D_SHADER:
+ vertexProgram = StringIO.readFully(Resources.getResource("glsl_shader/polkadot3d.vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/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 =
+ univ.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);
+
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ public void errorOccurred(ShaderError error) {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(ShaderTestGLSL.this,
+ error.toString(),
+ "ShaderError",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ view = univ.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);
+ univ.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/main/java/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.form b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.form
new file mode 100644
index 0000000..26e9b32
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.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="SphereGLSL"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java
new file mode 100644
index 0000000..03a514e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java
@@ -0,0 +1,384 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.PositionInterpolator;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.SpotLight;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program with programmable shader.
+ */
+public class SphereGLSL 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. This flag is set based on command line argument
+ private static int lightType = POINT_LIGHT;//DIRECTIONAL_LIGHT;
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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 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(Resources.getResource("glsl_shader/simple.vert"));
+ fragmentProgram = StringIO.readFully(Resources.getResource("glsl_shader/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.5, 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 =
+ univ.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 createUniverse() {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ // Create a Canvas3D using the preferred configuration
+ Canvas3D canvas3d = new Canvas3D(config);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(canvas3d);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ public void errorOccurred(ShaderError error) {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(SphereGLSL.this,
+ error.toString(),
+ "ShaderError",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ // 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 canvas3d;
+ }
+
+
+ /**
+ * Creates new form SphereGLSL
+ */
+ public SphereGLSL() {
+
+ // 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("SphereGLSL");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ SphereGLSL sphereGLSL = new SphereGLSL();
+ sphereGLSL.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/main/java/org/jdesktop/j3d/examples/glsl_shader/VertexAttrTestGLSL.form b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/VertexAttrTestGLSL.form
new file mode 100644
index 0000000..6e31a8f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/VertexAttrTestGLSL.form
@@ -0,0 +1,203 @@
+<?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="title" type="java.lang.String" value="VertexAttrTestGLSL"/>
+ </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,44,0,0,1,-112"/>
+ </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.DesignGridBagLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="vertexCheckBoxPanel">
+ <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="vertexFormat">
+ <Font PropertyName="font" name="Lucida Sans" size="10" style="0"/>
+ </TitledBorder>
+ </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="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="2" insetsBottom="2" insetsRight="2" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="jPanel1">
+ <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="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="11" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JSeparator" name="jSeparator1">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[0, 4]"/>
+ </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="0" 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.JSeparator" name="jSeparator2">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[0, 4]"/>
+ </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="3" gridWidth="1" gridHeight="1" fill="0" 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="jPanel2">
+ <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="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="11" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JCheckBox" name="vertexAttrsBox">
+ <Properties>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String" value="VertexAttrs"/>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="4" 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="geometryPanel">
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="-1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="2" insetsBottom="2" insetsRight="2" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JButton" name="createButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Create Geometry"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createButtonActionPerformed"/>
+ </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.JButton" name="destroyButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Destroy Geometry"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="destroyButtonActionPerformed"/>
+ </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="2" 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/main/java/org/jdesktop/j3d/examples/glsl_shader/VertexAttrTestGLSL.java b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/VertexAttrTestGLSL.java
new file mode 100644
index 0000000..014c0e9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/VertexAttrTestGLSL.java
@@ -0,0 +1,428 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.J3DBuffer;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+
+public class VertexAttrTestGLSL extends javax.swing.JFrame {
+
+ SimpleUniverse univ = null;
+ BranchGroup scene = null;
+
+ public BranchGroup createSceneGraph( boolean hasVertexAttrs ) {
+
+ // Bounds for BG and behavior
+ BoundingSphere bounds =
+ new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // Create the root of the branch graph
+ BranchGroup objRoot = new BranchGroup();
+ objRoot.setCapability(BranchGroup.ALLOW_DETACH);
+
+ // Set up the background
+ Color3f bgColor = new Color3f(0.1f, 0.1f, 0.1f);
+ 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);
+ objRoot.addChild(objTrans);
+
+ // Create a simple Shape3D node; add it to the scene graph.
+ objTrans.addChild(new MyShape(this, hasVertexAttrs));
+
+ return objRoot;
+ }
+
+ private Canvas3D initScene() {
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ univ = new SimpleUniverse(c);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ public void errorOccurred(ShaderError error) {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(VertexAttrTestGLSL.this,
+ error.toString(),
+ "ShaderError",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ return c;
+ }
+
+ /**
+ * Creates new form VertexAttrTestGLSL
+ */
+ public VertexAttrTestGLSL() {
+ // 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);
+ }
+
+ static class MyShape extends Shape3D {
+ private static String vertexProgName = "glsl_shader/vertexshader.vert";
+
+ // Coordinate data
+ private static final float[] coords = {
+ 0.0f, 0.0f, 0.0f,
+ 0.5f, 0.0f, 0.0f,
+ 0.0f, 0.5f, 0.0f,
+ };
+
+ private static final int[] sizes = { 1, 3 };
+ private static final float[] weights = {
+ 0.45f,
+ 0.15f,
+ 0.95f,
+ };
+ private static final float[] temps = {
+ 1.0f, 0.5f, 0.5f,
+ 0.5f, 1.0f, 0.5f,
+ 0.5f, 0.5f, 1.0f,
+ };
+
+ private static final String[] vaNames = { "weight", "temperature" };
+
+ J3DBuffer createDirectFloatBuffer(float[] arr) {
+ ByteOrder order = ByteOrder.nativeOrder();
+
+ FloatBuffer nioBuf = ByteBuffer.allocateDirect(arr.length * 4).order(order).asFloatBuffer();
+ nioBuf.put(arr);
+ return new J3DBuffer(nioBuf);
+ }
+
+
+ MyShape(JFrame frame, boolean hasVertexAttrs) {
+
+ int vertexFormat = GeometryArray.COORDINATES;
+ int vertexAttrCount = 0;
+ int[] vertexAttrSizes = null;
+ String[] vertexAttrNames = null;
+ String[] shaderAttrNames = null;
+
+ if (hasVertexAttrs) {
+ vertexFormat |= GeometryArray.VERTEX_ATTRIBUTES;
+ vertexAttrCount = vaNames.length;
+ vertexAttrSizes = sizes;
+ vertexAttrNames = vaNames;
+ }
+
+ TriangleArray tri = new TriangleArray(6, vertexFormat, 0, null, vertexAttrCount, vertexAttrSizes);
+ tri.setValidVertexCount(3);
+ tri.setCoordinates(0, coords);
+
+ if (hasVertexAttrs) {
+ tri.setVertexAttrs(0, 0, weights);
+ tri.setVertexAttrs(1, 0, temps);
+
+ String vertexProgram = null;
+ try {
+ vertexProgram = StringIO.readFully(Resources.getResource(vertexProgName));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ Shader[] shaders = new Shader[1];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL,
+ Shader.SHADER_TYPE_VERTEX,
+ vertexProgram);
+
+ ShaderProgram shaderProgram = new GLSLShaderProgram();
+ shaderProgram.setShaders(shaders);
+ shaderProgram.setVertexAttrNames(vertexAttrNames);
+ shaderProgram.setShaderAttrNames(shaderAttrNames);
+
+ ShaderAppearance app = new ShaderAppearance();
+ app.setShaderProgram(shaderProgram);
+
+ this.setGeometry(tri);
+
+ this.setAppearance(app);
+ } else {
+ this.setGeometry(tri);
+ this.setAppearance(new Appearance());
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------
+
+ /** 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;
+
+ mainPanel = new javax.swing.JPanel();
+ guiPanel = new javax.swing.JPanel();
+ vertexCheckBoxPanel = new javax.swing.JPanel();
+ jPanel1 = new javax.swing.JPanel();
+ jSeparator1 = new javax.swing.JSeparator();
+ jSeparator2 = new javax.swing.JSeparator();
+ jPanel2 = new javax.swing.JPanel();
+ vertexAttrsBox = new javax.swing.JCheckBox();
+ geometryPanel = new javax.swing.JPanel();
+ createButton = new javax.swing.JButton();
+ destroyButton = 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("VertexAttrTestGLSL");
+ 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 java.awt.GridBagLayout());
+
+ guiPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
+ vertexCheckBoxPanel.setLayout(new java.awt.GridBagLayout());
+
+ vertexCheckBoxPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "vertexFormat", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Lucida Sans", 0, 10)));
+ jPanel1.setLayout(new java.awt.GridBagLayout());
+
+ jSeparator1.setPreferredSize(new java.awt.Dimension(0, 4));
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ jPanel1.add(jSeparator1, gridBagConstraints);
+
+ jSeparator2.setPreferredSize(new java.awt.Dimension(0, 4));
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ jPanel1.add(jSeparator2, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
+ vertexCheckBoxPanel.add(jPanel1, gridBagConstraints);
+
+ jPanel2.setLayout(new java.awt.GridBagLayout());
+
+ vertexAttrsBox.setSelected(true);
+ vertexAttrsBox.setText("VertexAttrs");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ jPanel2.add(vertexAttrsBox, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
+ vertexCheckBoxPanel.add(jPanel2, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
+ guiPanel.add(vertexCheckBoxPanel, gridBagConstraints);
+
+ geometryPanel.setLayout(new java.awt.GridBagLayout());
+
+ createButton.setText("Create Geometry");
+ createButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ createButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ geometryPanel.add(createButton, gridBagConstraints);
+
+ destroyButton.setText("Destroy Geometry");
+ destroyButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ destroyButtonActionPerformed(evt);
+ }
+ });
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
+ geometryPanel.add(destroyButton, gridBagConstraints);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
+ guiPanel.add(geometryPanel, gridBagConstraints);
+
+ 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 destroyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_destroyButtonActionPerformed
+ if (scene != null) {
+ univ.getLocale().removeBranchGraph(scene);
+ scene = null;
+ }
+ }//GEN-LAST:event_destroyButtonActionPerformed
+
+ private void createButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createButtonActionPerformed
+ if (scene == null) {
+ boolean hasVertexAttrs = vertexAttrsBox.isSelected();
+ scene = createSceneGraph(hasVertexAttrs);
+ univ.addBranchGraph(scene);
+ }
+ }//GEN-LAST:event_createButtonActionPerformed
+
+ 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[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new VertexAttrTestGLSL().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton createButton;
+ private javax.swing.JButton destroyButton;
+ private javax.swing.JPanel drawingPanel;
+ private javax.swing.JMenuItem exitMenuItem;
+ private javax.swing.JMenu fileMenu;
+ private javax.swing.JPanel geometryPanel;
+ private javax.swing.JPanel guiPanel;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JSeparator jSeparator1;
+ private javax.swing.JSeparator jSeparator2;
+ private javax.swing.JPanel mainPanel;
+ private javax.swing.JCheckBox vertexAttrsBox;
+ private javax.swing.JPanel vertexCheckBoxPanel;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag
new file mode 100644
index 0000000..7c9aab8
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert
new file mode 100644
index 0000000..226dbe4
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/dimple.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/dimple.frag
new file mode 100644
index 0000000..282add7
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/dimple.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/dimple.vert
new file mode 100644
index 0000000..e45796b
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/envmap.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/envmap.frag
new file mode 100644
index 0000000..3e298f8
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/envmap.frag
@@ -0,0 +1,61 @@
+//
+// Fragment shader for environment mapping with an
+// equirectangular 2D texture
+//
+// Authors: John Kessenich, Randi Rost
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+const vec3 Xunitvec = vec3 (1.0, 0.0, 0.0);
+const vec3 Yunitvec = vec3 (0.0, 1.0, 0.0);
+
+uniform vec3 BaseColor;
+uniform float MixRatio;
+
+uniform sampler2D EnvMap;
+
+varying vec3 Normal;
+varying vec3 EyeDir;
+varying float LightIntensity;
+
+void main (void)
+{
+ // Compute reflection vector
+ vec3 reflectDir = reflect(EyeDir, Normal);
+
+ // Compute altitude and azimuth angles
+
+ vec2 index;
+
+ index.y = dot(normalize(reflectDir), Yunitvec);
+ reflectDir.y = 0.0;
+ index.x = dot(normalize(reflectDir), Xunitvec) * 0.5;
+
+ // Translate index values into proper range
+
+ if (reflectDir.z >= 0.0)
+ index = (index + 1.0) * 0.5;
+ else
+ {
+ index.t = (index.t + 1.0) * 0.5;
+ index.s = (-index.s) * 0.5 + 1.0;
+ }
+
+ // if reflectDir.z >= 0.0, s will go from 0.25 to 0.75
+ // if reflectDir.z < 0.0, s will go from 0.75 to 1.25, and
+ // that's OK, because we've set the texture to wrap.
+
+ // Do a lookup into the environment map.
+
+ vec3 envColor = vec3 (texture2D(EnvMap, index));
+
+ // Add lighting to base color and mix
+
+ vec3 base = LightIntensity * BaseColor;
+ envColor = mix(envColor, base, MixRatio);
+
+ gl_FragColor = vec4 (envColor, 1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/glsl_shader/envmap.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/envmap.vert
new file mode 100644
index 0000000..d4e8b44
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/envmap.vert
@@ -0,0 +1,25 @@
+//
+// Vertex shader for environment mapping with an
+// equirectangular 2D texture
+//
+// Authors: John Kessenich, Randi Rost
+//
+// Copyright (c) 2002-2004 3Dlabs Inc. Ltd.
+//
+// See 3Dlabs-License.txt for license information
+//
+
+varying vec3 Normal;
+varying vec3 EyeDir;
+varying float LightIntensity;
+
+uniform vec3 LightPos;
+
+void main(void)
+{
+ gl_Position = ftransform();
+ Normal = normalize(gl_NormalMatrix * gl_Normal);
+ vec4 pos = gl_ModelViewMatrix * gl_Vertex;
+ EyeDir = pos.xyz;
+ LightIntensity = max(dot(normalize(LightPos - EyeDir), Normal), 0.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag
new file mode 100644
index 0000000..9169661
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag
@@ -0,0 +1,50 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert
new file mode 100644
index 0000000..8503e6f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert
@@ -0,0 +1,100 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/glsl_shader/multitex.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/multitex.frag
new file mode 100644
index 0000000..b79f85a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/multitex.frag
@@ -0,0 +1,61 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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$
+ */
+
+uniform float cloudFactor;
+uniform sampler2D earthTex;
+uniform sampler2D cloudTex;
+
+uniform sampler2D EnvMap;
+
+void main (void)
+{
+ vec2 tc0 = gl_TexCoord[0].xy;
+ vec2 tc1 = gl_TexCoord[1].xy;
+
+ vec3 color0 = vec3(texture2D(cloudTex, tc0));
+ vec3 color1 = vec3(texture2D(earthTex, tc1));
+ vec3 finalColor = color0*cloudFactor + color1;
+
+ gl_FragColor = vec4(finalColor, 1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/glsl_shader/phong.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/phong.frag
new file mode 100644
index 0000000..90bab19
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/phong.frag
@@ -0,0 +1,98 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/glsl_shader/phong.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/phong.vert
new file mode 100644
index 0000000..ab27603
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/phong.vert
@@ -0,0 +1,56 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag
new file mode 100644
index 0000000..b341454
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert
new file mode 100644
index 0000000..86f432f
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/simple.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/simple.frag
new file mode 100644
index 0000000..51eaaf6
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/simple.frag
@@ -0,0 +1,65 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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$
+ */
+
+
+varying vec4 glFrontColor;
+
+// 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/main/java/org/jdesktop/j3d/examples/glsl_shader/simple.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/simple.vert
new file mode 100644
index 0000000..f90ef79
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/simple.vert
@@ -0,0 +1,131 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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
+
+varying vec4 glFrontColor;
+
+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/main/java/org/jdesktop/j3d/examples/glsl_shader/toon.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/toon.frag
new file mode 100644
index 0000000..fa50453
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/toon.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/toon.vert
new file mode 100644
index 0000000..d044af7
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/vertexshader.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/vertexshader.vert
new file mode 100644
index 0000000..43b4a05
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/vertexshader.vert
@@ -0,0 +1,61 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 demo. vertex attributes
+
+attribute float weight;
+attribute vec3 temperature;
+
+void main()
+{
+ // Transform the vertex
+ vec4 outPosition = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+ // Compute color from temperature
+ vec4 outColor;
+ outColor = vec4(temperature * weight, 1);
+ // Assign output parameters
+ gl_FrontColor = outColor;
+ gl_Position = outPosition;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/glsl_shader/wood.frag b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/wood.frag
new file mode 100644
index 0000000..eecf91f
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/glsl_shader/wood.vert b/src/main/java/org/jdesktop/j3d/examples/glsl_shader/wood.vert
new file mode 100644
index 0000000..84651aa
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form b/src/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form
new file mode 100644
index 0000000..48fadea
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java b/src/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java
new file mode 100644
index 0000000..a085405
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java
@@ -0,0 +1,176 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+/**
+ * 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverseGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverseGL2ES2.java
new file mode 100644
index 0000000..b62906b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/hello_universe/HelloUniverseGL2ES2.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.hello_universe;
+
+import java.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.gl2es2pipeline.Cube;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+/**
+ * Simple Java 3D example program to display a spinning cube.
+ */
+public class HelloUniverseGL2ES2 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 Cube(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 HelloUniverseGL2ES2()
+ {
+ // 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 GL2ES2");
+ 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[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ new HelloUniverseGL2ES2().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/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExample.form b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExample.form
new file mode 100644
index 0000000..5efa763
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExample.form
@@ -0,0 +1,142 @@
+<?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"/>
+ </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,2,-35,0,0,3,-13"/>
+ <SyntheticProperty name="formSizePolicy" type="int" value="0"/>
+ <SyntheticProperty name="generateSize" type="boolean" value="true"/>
+ <SyntheticProperty name="generateCenter" type="boolean" value="true"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="2"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JSplitPane" name="splitPane">
+ <Properties>
+ <Property name="dividerLocation" type="int" value="300"/>
+ <Property name="dividerSize" type="int" value="8"/>
+ <Property name="continuousLayout" type="boolean" value="true"/>
+ <Property name="oneTouchExpandable" type="boolean" value="true"/>
+ </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.support.JSplitPaneSupportLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JScrollPane" name="scrollPane">
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
+ <JSplitPaneConstraints position="left"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JPanel" name="panel">
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JButton" name="addButton">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Create New Frame"/>
+ <Property name="toolTipText" type="java.lang.String" value="Adds a new frame containing an universe into the desktop pane"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addButtonActionPerformed"/>
+ </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="0" 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.JCheckBox" name="delayCheckBox">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Resize Delayed"/>
+ <Property name="toolTipText" type="java.lang.String" value="Shows the effect of using a delayed resizing to the internal frames."/>
+ </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="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.JCheckBox" name="interactiveCheckBox">
+ <Properties>
+ <Property name="selected" type="boolean" value="true"/>
+ <Property name="text" type="java.lang.String" value="Interactive Cube"/>
+ <Property name="toolTipText" type="java.lang.String" value="Tests the use of AWT behaviors on the displayed component."/>
+ <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="interactiveCheckBoxActionPerformed"/>
+ </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>
+ <Component class="javax.swing.JCheckBox" name="randomCheckBox">
+ <Properties>
+ <Property name="text" type="java.lang.String" value="Random start angle"/>
+ <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="enabled" type="boolean" value="false"/>
+ <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
+ <Insets value="[0, 0, 0, 0]"/>
+ </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="3" 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.JDesktopPane" name="desktopPane">
+ <Properties>
+ <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+ <Color blue="c9" green="99" red="99" type="rgb"/>
+ </Property>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[300, 300]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
+ <JSplitPaneConstraints position="right"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.support.JLayeredPaneSupportLayout"/>
+ </Container>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExample.java b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExample.java
new file mode 100644
index 0000000..1a83fdd
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExample.java
@@ -0,0 +1,195 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.jcanvas3d;
+
+
+/**
+ * Simple Java 3D example program that displays universes within lightweight swing components, layed in JInternalFrame objects.
+ */
+import java.awt.Toolkit;
+
+public class JCanvas3DExample extends javax.swing.JFrame implements java.awt.event.ActionListener
+{
+
+ /**
+ * Creates new form JCanvas3DExample
+ */
+ public JCanvas3DExample()
+ {
+ initComponents();
+ Toolkit.getDefaultToolkit().setDynamicLayout( true );
+ setDefaultCloseOperation( EXIT_ON_CLOSE );
+ }
+
+ /** 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;
+
+ splitPane = new javax.swing.JSplitPane();
+ scrollPane = new javax.swing.JScrollPane();
+ panel = new javax.swing.JPanel();
+ addButton = new javax.swing.JButton();
+ delayCheckBox = new javax.swing.JCheckBox();
+ interactiveCheckBox = new javax.swing.JCheckBox();
+ randomCheckBox = new javax.swing.JCheckBox();
+ desktopPane = new javax.swing.JDesktopPane();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ splitPane.setDividerLocation(300);
+ splitPane.setDividerSize(8);
+ splitPane.setContinuousLayout(true);
+ splitPane.setOneTouchExpandable(true);
+ panel.setLayout(new java.awt.GridBagLayout());
+
+ addButton.setText("Create New Frame");
+ addButton.setToolTipText("Adds a new frame containing an universe into the desktop pane");
+ addButton.addActionListener(this);
+
+ panel.add(addButton, new java.awt.GridBagConstraints());
+
+ delayCheckBox.setText("Resize Delayed");
+ delayCheckBox.setToolTipText("Shows the effect of using a delayed resizing to the internal frames.");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ panel.add(delayCheckBox, gridBagConstraints);
+
+ interactiveCheckBox.setSelected(true);
+ interactiveCheckBox.setText("Interactive Cube");
+ interactiveCheckBox.setToolTipText("Tests the use of AWT behaviors on the displayed component.");
+ interactiveCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ interactiveCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
+ interactiveCheckBox.addActionListener(this);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ panel.add(interactiveCheckBox, gridBagConstraints);
+
+ randomCheckBox.setText("Random start angle");
+ randomCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ randomCheckBox.setEnabled(false);
+ randomCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ panel.add(randomCheckBox, gridBagConstraints);
+
+ scrollPane.setViewportView(panel);
+
+ splitPane.setLeftComponent(scrollPane);
+
+ desktopPane.setBackground(new java.awt.Color(153, 153, 201));
+ desktopPane.setPreferredSize(new java.awt.Dimension(300, 300));
+ splitPane.setRightComponent(desktopPane);
+
+ getContentPane().add(splitPane, java.awt.BorderLayout.CENTER);
+
+ java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+ setBounds((screenSize.width-1011)/2, (screenSize.height-733)/2, 1011, 733);
+ }
+
+ // Code for dispatching events from components to event handlers.
+
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ if (evt.getSource() == addButton) {
+ JCanvas3DExample.this.addButtonActionPerformed(evt);
+ }
+ else if (evt.getSource() == interactiveCheckBox) {
+ JCanvas3DExample.this.interactiveCheckBoxActionPerformed(evt);
+ }
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void interactiveCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interactiveCheckBoxActionPerformed
+ randomCheckBox.setEnabled( interactiveCheckBox.isSelected() ? false:true );
+ }//GEN-LAST:event_interactiveCheckBoxActionPerformed
+
+ private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
+ JInternalWorld iWorld;
+ // we create an internal world to be added within the JDesktop.
+ iWorld = new JInternalWorld( interactiveCheckBox.isSelected(),
+ delayCheckBox.isSelected(),
+ randomCheckBox.isSelected() );
+ iWorld.setSize( 256, 256 );
+ iWorld.setLocation( 50, 50 );
+ iWorld.setResizable( true );
+ desktopPane.add( iWorld );
+ iWorld.setVisible(true);
+ }//GEN-LAST:event_addButtonActionPerformed
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[])
+ {
+ java.awt.EventQueue.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ new JCanvas3DExample().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton addButton;
+ private javax.swing.JCheckBox delayCheckBox;
+ private javax.swing.JDesktopPane desktopPane;
+ private javax.swing.JCheckBox interactiveCheckBox;
+ private javax.swing.JPanel panel;
+ private javax.swing.JCheckBox randomCheckBox;
+ private javax.swing.JScrollPane scrollPane;
+ private javax.swing.JSplitPane splitPane;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExampleGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExampleGL2ES2.java
new file mode 100644
index 0000000..45dccc0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JCanvas3DExampleGL2ES2.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.jcanvas3d;
+
+
+/**
+ * Simple Java 3D example program that displays universes within lightweight swing components, layed in JInternalFrame objects.
+ */
+import java.awt.Toolkit;
+
+public class JCanvas3DExampleGL2ES2 extends javax.swing.JFrame implements java.awt.event.ActionListener
+{
+
+ /**
+ * Creates new form JCanvas3DExample
+ */
+ public JCanvas3DExampleGL2ES2()
+ {
+ initComponents();
+ Toolkit.getDefaultToolkit().setDynamicLayout( true );
+ setDefaultCloseOperation( EXIT_ON_CLOSE );
+ }
+
+ /** 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;
+
+ splitPane = new javax.swing.JSplitPane();
+ scrollPane = new javax.swing.JScrollPane();
+ panel = new javax.swing.JPanel();
+ addButton = new javax.swing.JButton();
+ delayCheckBox = new javax.swing.JCheckBox();
+ interactiveCheckBox = new javax.swing.JCheckBox();
+ randomCheckBox = new javax.swing.JCheckBox();
+ desktopPane = new javax.swing.JDesktopPane();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ splitPane.setDividerLocation(300);
+ splitPane.setDividerSize(8);
+ splitPane.setContinuousLayout(true);
+ splitPane.setOneTouchExpandable(true);
+ panel.setLayout(new java.awt.GridBagLayout());
+
+ addButton.setText("Create New Frame");
+ addButton.setToolTipText("Adds a new frame containing an universe into the desktop pane");
+ addButton.addActionListener(this);
+
+ panel.add(addButton, new java.awt.GridBagConstraints());
+
+ delayCheckBox.setText("Resize Delayed");
+ delayCheckBox.setToolTipText("Shows the effect of using a delayed resizing to the internal frames.");
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ panel.add(delayCheckBox, gridBagConstraints);
+
+ interactiveCheckBox.setSelected(true);
+ interactiveCheckBox.setText("Interactive Cube");
+ interactiveCheckBox.setToolTipText("Tests the use of AWT behaviors on the displayed component.");
+ interactiveCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ interactiveCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
+ interactiveCheckBox.addActionListener(this);
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ panel.add(interactiveCheckBox, gridBagConstraints);
+
+ randomCheckBox.setText("Random start angle");
+ randomCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ randomCheckBox.setEnabled(false);
+ randomCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ panel.add(randomCheckBox, gridBagConstraints);
+
+ scrollPane.setViewportView(panel);
+
+ splitPane.setLeftComponent(scrollPane);
+
+ desktopPane.setBackground(new java.awt.Color(153, 153, 201));
+ desktopPane.setPreferredSize(new java.awt.Dimension(300, 300));
+ splitPane.setRightComponent(desktopPane);
+
+ getContentPane().add(splitPane, java.awt.BorderLayout.CENTER);
+
+ java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
+ setBounds((screenSize.width-1011)/2, (screenSize.height-733)/2, 1011, 733);
+ }
+
+ // Code for dispatching events from components to event handlers.
+
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ if (evt.getSource() == addButton) {
+ JCanvas3DExampleGL2ES2.this.addButtonActionPerformed(evt);
+ }
+ else if (evt.getSource() == interactiveCheckBox) {
+ JCanvas3DExampleGL2ES2.this.interactiveCheckBoxActionPerformed(evt);
+ }
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void interactiveCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_interactiveCheckBoxActionPerformed
+ randomCheckBox.setEnabled( interactiveCheckBox.isSelected() ? false:true );
+ }//GEN-LAST:event_interactiveCheckBoxActionPerformed
+
+ private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
+ JInternalWorldGL2ES2 iWorld;
+ // we create an internal world to be added within the JDesktop.
+ iWorld = new JInternalWorldGL2ES2( interactiveCheckBox.isSelected(),
+ delayCheckBox.isSelected(),
+ randomCheckBox.isSelected() );
+ iWorld.setSize( 256, 256 );
+ iWorld.setLocation( 50, 50 );
+ iWorld.setResizable( true );
+ desktopPane.add( iWorld );
+ iWorld.setVisible(true);
+ }//GEN-LAST:event_addButtonActionPerformed
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[])
+ {System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ new JCanvas3DExampleGL2ES2().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton addButton;
+ private javax.swing.JCheckBox delayCheckBox;
+ private javax.swing.JDesktopPane desktopPane;
+ private javax.swing.JCheckBox interactiveCheckBox;
+ private javax.swing.JPanel panel;
+ private javax.swing.JCheckBox randomCheckBox;
+ private javax.swing.JScrollPane scrollPane;
+ private javax.swing.JSplitPane splitPane;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JInternalWorld.java b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JInternalWorld.java
new file mode 100644
index 0000000..e702bc2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JInternalWorld.java
@@ -0,0 +1,232 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.jcanvas3d;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+
+import javax.swing.JInternalFrame;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Text3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.exp.swing.JCanvas3D;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+
+/**
+ * This is a JInternalFrame holding an universe, which can be configured to
+ * be interactive -that is, where user can interact with object- or automatic
+ * -where the object spins only-. When in automatic mode, spinning speed is
+ * changed so that they look less the same. Changing the spinning start angle
+ * helps unsynchronizing the rotations too.
+ *
+ * @author pepe
+ */
+public class JInternalWorld extends JInternalFrame {
+ /** DOCUMENT ME! */
+ private Component comp;
+
+ /**
+ * Creates a new JInternalWorld object.
+ *
+ * @param isInteractive tells the world to be constructed as interactive
+ * @param isDelayed tells the rotator to start at a random alpha.
+ */
+ public JInternalWorld(boolean isInteractive, boolean isDelayed, boolean isRandom) {
+ super();
+ setSize(256, 256);
+ setClosable(true);
+
+ JCanvas3D canvas = new JCanvas3D(new GraphicsConfigTemplate3D());
+
+ if (true == isDelayed) {
+ canvas.setResizeMode(canvas.RESIZE_DELAYED);
+ }
+
+ comp = canvas;
+
+ Dimension dim = new Dimension(256, 256);
+ comp.setPreferredSize(dim);
+ comp.setSize(dim);
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(comp, BorderLayout.CENTER);
+ pack();
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph(isInteractive, isRandom);
+ SimpleUniverse universe = new SimpleUniverse(canvas.getOffscreenCanvas3D()); //TODO: this is awful and must not be done like that in final version
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ universe.getViewingPlatform().setNominalViewingTransform();
+ universe.getViewer().getView().setMinimumFrameCycleTime(30);
+ universe.addBranchGraph(scene);
+ }
+
+ /**
+ * Creates the world. Only exists to cleanup the source a bit
+ *
+ * @param isInteractive tells the world to be constructed as interactive
+ * @param isDelayed tells the rotator to start at a random alpha.
+ *
+ * @return a global branchgroup containing the world, as desired.
+ */
+ private BranchGroup createSceneGraph(boolean isInteractive, boolean isRandom) {
+ // 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();
+ Transform3D t3dTrans = new Transform3D();
+ t3dTrans.setTranslation(new Vector3d(0, 0, -1));
+ objTrans.setTransform(t3dTrans);
+
+ TransformGroup objRot = new TransformGroup();
+ objRot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+ objTrans.addChild(objRot);
+
+ // Create a simple Shape3D node; add it to the scene graph.
+ // issue 383: changed the cube to a text, so that any graphical problem related to Yup can be seen.
+ Font3D f3d = new Font3D(new Font("dialog", Font.PLAIN, 1),
+ new FontExtrusion());
+ Text3D text = new Text3D(f3d, "JCanvas3D",
+ new Point3f( -2.3f, -0.5f, 0.f));
+
+ Shape3D sh = new Shape3D();
+ Appearance app = new Appearance();
+ Material mm = new Material();
+ mm.setLightingEnable(true);
+ app.setMaterial(mm);
+ sh.setGeometry(text);
+ sh.setAppearance(app);
+
+ objRot.addChild( sh );
+
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
+ 100.0);
+
+ // 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);
+
+
+ if (true == isInteractive) {
+ MouseRotate mr = new MouseRotate(comp, objRot);
+ mr.setSchedulingBounds(bounds);
+ mr.setSchedulingInterval(1);
+ objRoot.addChild(mr);
+ } else {
+ // 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();
+
+ // rotation speed is randomized a bit so that it does not go at the same speed on every canvases,
+ // which will make it more natural and express the differences between every present universes
+ Alpha rotationAlpha = null;
+
+ if (true == isRandom) {
+ int duration = Math.max(2000, (int) (Math.random() * 8000.));
+ rotationAlpha = new Alpha(-1,
+ (int) ((double) duration * Math.random()), 0, duration,
+ 0, 0);
+ } else {
+ rotationAlpha = new Alpha(-1, 4000);
+ }
+
+ RotationInterpolator rotator = new RotationInterpolator(rotationAlpha,
+ objRot, yAxis, 0.0f, (float) Math.PI * 2.0f);
+
+ rotator.setSchedulingBounds(bounds);
+ objRoot.addChild(rotator);
+ }
+
+ return objRoot;
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JInternalWorldGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JInternalWorldGL2ES2.java
new file mode 100644
index 0000000..d38dc6e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/jcanvas3d/JInternalWorldGL2ES2.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.jcanvas3d;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+
+import javax.swing.JInternalFrame;
+
+import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Text3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.exp.swing.JCanvas3D;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+
+/**
+ * This is a JInternalFrame holding an universe, which can be configured to
+ * be interactive -that is, where user can interact with object- or automatic
+ * -where the object spins only-. When in automatic mode, spinning speed is
+ * changed so that they look less the same. Changing the spinning start angle
+ * helps unsynchronizing the rotations too.
+ *
+ * @author pepe
+ */
+public class JInternalWorldGL2ES2 extends JInternalFrame {
+ /** DOCUMENT ME! */
+ private Component comp;
+
+ /**
+ * Creates a new JInternalWorld object.
+ *
+ * @param isInteractive tells the world to be constructed as interactive
+ * @param isDelayed tells the rotator to start at a random alpha.
+ */
+ public JInternalWorldGL2ES2(boolean isInteractive, boolean isDelayed, boolean isRandom) {
+ super();
+ setSize(256, 256);
+ setClosable(true);
+
+ JCanvas3D canvas = new JCanvas3D(new GraphicsConfigTemplate3D());
+
+ if (true == isDelayed) {
+ canvas.setResizeMode(canvas.RESIZE_DELAYED);
+ }
+
+ comp = canvas;
+
+ Dimension dim = new Dimension(256, 256);
+ comp.setPreferredSize(dim);
+ comp.setSize(dim);
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(comp, BorderLayout.CENTER);
+ pack();
+
+ // Create a simple scene and attach it to the virtual universe
+ BranchGroup scene = createSceneGraph(isInteractive, isRandom);
+ SimpleUniverse universe = new SimpleUniverse(canvas.getOffscreenCanvas3D()); //TODO: this is awful and must not be done like that in final version
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ universe.getViewingPlatform().setNominalViewingTransform();
+ universe.getViewer().getView().setMinimumFrameCycleTime(30);
+ universe.addBranchGraph(scene);
+ }
+
+ /**
+ * Creates the world. Only exists to cleanup the source a bit
+ *
+ * @param isInteractive tells the world to be constructed as interactive
+ * @param isDelayed tells the rotator to start at a random alpha.
+ *
+ * @return a global branchgroup containing the world, as desired.
+ */
+ private BranchGroup createSceneGraph(boolean isInteractive, boolean isRandom) {
+ // 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();
+ Transform3D t3dTrans = new Transform3D();
+ t3dTrans.setTranslation(new Vector3d(0, 0, -1));
+ objTrans.setTransform(t3dTrans);
+
+ TransformGroup objRot = new TransformGroup();
+ objRot.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objRoot.addChild(objTrans);
+ objTrans.addChild(objRot);
+
+ // Create a simple Shape3D node; add it to the scene graph.
+ // issue 383: changed the cube to a text, so that any graphical problem related to Yup can be seen.
+ Font3D f3d = new Font3D(new Font("dialog", Font.PLAIN, 1),
+ new FontExtrusion());
+ Text3D text = new Text3D(f3d, "JCanvas3D",
+ new Point3f( -2.3f, -0.5f, 0.f));
+
+ Shape3D sh = new Shape3D();
+ Appearance app = new SimpleShaderAppearance(false,false);
+ Material mm = new Material();
+ mm.setLightingEnable(true);
+ app.setMaterial(mm);
+ sh.setGeometry(text);
+ sh.setAppearance(app);
+
+ objRot.addChild( sh );
+
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
+ 100.0);
+
+ // 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);
+
+
+ if (true == isInteractive) {
+ MouseRotate mr = new MouseRotate(comp, objRot);
+ mr.setSchedulingBounds(bounds);
+ mr.setSchedulingInterval(1);
+ objRoot.addChild(mr);
+ } else {
+ // 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();
+
+ // rotation speed is randomized a bit so that it does not go at the same speed on every canvases,
+ // which will make it more natural and express the differences between every present universes
+ Alpha rotationAlpha = null;
+
+ if (true == isRandom) {
+ int duration = Math.max(2000, (int) (Math.random() * 8000.));
+ rotationAlpha = new Alpha(-1,
+ (int) ((double) duration * Math.random()), 0, duration,
+ 0, 0);
+ } else {
+ rotationAlpha = new Alpha(-1, 4000);
+ }
+
+ RotationInterpolator rotator = new RotationInterpolator(rotationAlpha,
+ objRot, yAxis, 0.0f, (float) Math.PI * 2.0f);
+
+ rotator.setSchedulingBounds(bounds);
+ objRoot.addChild(rotator);
+ }
+
+ return objRoot;
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/lightwave/README.txt b/src/main/java/org/jdesktop/j3d/examples/lightwave/README.txt
new file mode 100644
index 0000000..6ae5ce6
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/lightwave/README.txt
@@ -0,0 +1,321 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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/main/java/org/jdesktop/j3d/examples/lightwave/Viewer.java b/src/main/java/org/jdesktop/j3d/examples/lightwave/Viewer.java
new file mode 100644
index 0000000..063c7cc
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/lightwave/Viewer.java
@@ -0,0 +1,206 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.View;
+import org.jogamp.java3d.loaders.Loader;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.lw3d.Lw3dLoader;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Matrix4d;
+
+
+/**
+ * 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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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();
+ }
+
+ private static void usage() {
+ System.out.println("Usage: java Viewer <.lws>") ;
+ System.exit(0) ;
+ }
+
+ /**
+ * 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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 {
+ usage();
+ }
+ new MainFrame(new Viewer(url), 500, 500);
+ }
+}
+
+
+
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/lod/LOD.form b/src/main/java/org/jdesktop/j3d/examples/lod/LOD.form
new file mode 100644
index 0000000..7bba785
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/lod/LOD.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="LOD"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/lod/LOD.java b/src/main/java/org/jdesktop/j3d/examples/lod/LOD.java
new file mode 100644
index 0000000..67aac84
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/lod/LOD.java
@@ -0,0 +1,235 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.DistanceLOD;
+import org.jogamp.java3d.Switch;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program to display a spinning cube.
+ */
+public class LOD 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();
+
+ 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(Switch.ALLOW_SWITCH_READ);
+ sw.setCapability(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);
+ }
+
+ 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);
+
+ // only add zoom mouse behavior to viewingPlatform
+ ViewingPlatform viewingPlatform = univ.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);
+
+ // 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 LOD
+ */
+ public LOD() {
+ // 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("LOD");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new LOD().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/main/java/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java b/src/main/java/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java
new file mode 100644
index 0000000..618b7f2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java
@@ -0,0 +1,190 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.ModelClip;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseZoom;
+import org.jogamp.java3d.utils.geometry.Cylinder;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+import org.jogamp.vecmath.Vector4d;
+
+/**
+ * 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() {System.setProperty("sun.awt.noerasebackground", "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
+ 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/main/java/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java b/src/main/java/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java
new file mode 100644
index 0000000..ef5a407
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java
@@ -0,0 +1,213 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.ModelClip;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseZoom;
+import org.jogamp.java3d.utils.geometry.Box;
+import org.jogamp.java3d.utils.geometry.Cylinder;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.AxisAngle4f;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+import org.jogamp.vecmath.Vector4d;
+
+/**
+ * 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() {System.setProperty("sun.awt.noerasebackground", "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
+ 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/main/java/org/jdesktop/j3d/examples/morphing/ColorCube.java b/src/main/java/org/jdesktop/j3d/examples/morphing/ColorCube.java
new file mode 100644
index 0000000..df36e9d
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/morphing/ColorCube.java
@@ -0,0 +1,122 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.QuadArray;
+
+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/main/java/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java b/src/main/java/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java
new file mode 100644
index 0000000..89d1a8b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java
@@ -0,0 +1,122 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.QuadArray;
+
+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/main/java/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java b/src/main/java/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java
new file mode 100644
index 0000000..b94e6f0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java
@@ -0,0 +1,124 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.QuadArray;
+
+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/main/java/org/jdesktop/j3d/examples/morphing/Morphing.form b/src/main/java/org/jdesktop/j3d/examples/morphing/Morphing.form
new file mode 100644
index 0000000..631f59a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/morphing/Morphing.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="Morphing"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/morphing/Morphing.java b/src/main/java/org/jdesktop/j3d/examples/morphing/Morphing.java
new file mode 100644
index 0000000..4604f66
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/morphing/Morphing.java
@@ -0,0 +1,304 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.io.FileNotFoundException;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Morph;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.loaders.IncorrectFormatException;
+import org.jogamp.java3d.loaders.ParsingErrorException;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.objectfile.ObjectFile;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class Morphing extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+ private java.net.URL[] objFiles = 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;
+ }
+
+
+ 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 LOD
+ */
+ public Morphing(String args[]) {
+
+ objFiles = new java.net.URL[3];
+ for(int i=0; i<3; i++) {
+ objFiles[i] = Resources.getResource("resources/geometry/hand" + (i+1) + ".obj");
+ if (objFiles[i] == null) {
+ System.err.println("resources/geometry/hand" + (i+1) + ".obj not found");
+ System.exit(1);
+ }
+ }
+
+ // 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("Morphing");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ Morphing morphing = new Morphing(args);
+ morphing.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/main/java/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java b/src/main/java/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java
new file mode 100644
index 0000000..49520c2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java
@@ -0,0 +1,102 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.Morph;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+
+// 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/main/java/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.form b/src/main/java/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.form
new file mode 100644
index 0000000..0c0b7e2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.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="Pyramid2Cube"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java b/src/main/java/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java
new file mode 100644
index 0000000..7435588
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java
@@ -0,0 +1,250 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.Morph;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+
+public class Pyramid2Cube extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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;
+ }
+
+ 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 Pyramid2Cube
+ */
+ public Pyramid2Cube() {
+ // 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("Pyramid2Cube");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new Pyramid2Cube().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/main/java/org/jdesktop/j3d/examples/objload/ObjLoad.form b/src/main/java/org/jdesktop/j3d/examples/objload/ObjLoad.form
new file mode 100644
index 0000000..f8ced41
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/objload/ObjLoad.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="ObjLoad"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/objload/ObjLoad.java b/src/main/java/org/jdesktop/j3d/examples/objload/ObjLoad.java
new file mode 100644
index 0000000..9936e97
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/objload/ObjLoad.java
@@ -0,0 +1,325 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.awt.GraphicsConfiguration;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.loaders.IncorrectFormatException;
+import org.jogamp.java3d.loaders.ParsingErrorException;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.objectfile.ObjectFile;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.universe.PlatformGeometry;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program to display an .obj object.
+ */
+public class ObjLoad extends javax.swing.JFrame {
+
+ private boolean spin = false;
+ private boolean noTriangulate = false;
+ private boolean noStripify = false;
+ private double creaseAngle = 60.0;
+ private URL filename = null;
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = 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.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);
+
+ 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 canvas3d = new Canvas3D(config);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(canvas3d);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = univ.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(canvas3d,
+ OrbitBehavior.REVERSE_ALL);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+ }
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return canvas3d;
+ }
+
+ 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
+
+ /**
+ * Creates new form ObjLoad
+ */
+ 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);
+ }
+ }
+ }
+ }
+
+ if (filename == null) {
+ filename = Resources.getResource("resources/geometry/galleon.obj");
+ if (filename == null) {
+ System.err.println("resources/geometry/galleon.obj not found");
+ System.exit(1);
+ }
+ }
+
+ // 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("ObjLoad");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ ObjLoad objLoad = new ObjLoad(args);
+ objLoad.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/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java
new file mode 100644
index 0000000..913bc74
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java
@@ -0,0 +1,107 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.GraphicsConfiguration;
+import java.awt.image.BufferedImage;
+
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ImageComponent;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Raster;
+
+
+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, true, true);
+ 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, true, true);
+
+ drawRaster.setImage(newImageComponent);
+ }
+}
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form
new file mode 100644
index 0000000..39a0712
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java
new file mode 100644
index 0000000..dbb841e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java
@@ -0,0 +1,231 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.ImageComponent;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Raster;
+import org.jogamp.java3d.Screen3D;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.View;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+
+/**
+ * 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, true, true);
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java
new file mode 100644
index 0000000..ce671e2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java
@@ -0,0 +1,79 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.GraphicsConfiguration;
+
+import org.jogamp.java3d.Canvas3D;
+
+
+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/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form
new file mode 100644
index 0000000..54d6721
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java
new file mode 100644
index 0000000..e53a094
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java
@@ -0,0 +1,274 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+
+import javax.swing.JPopupMenu;
+
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.ImageComponent;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Raster;
+import org.jogamp.java3d.Screen3D;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.View;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+
+/**
+ * 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, true, true);
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java b/src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java
new file mode 100644
index 0000000..473eaf7
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java
@@ -0,0 +1,200 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.AWTEvent;
+import java.awt.event.MouseEvent;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.WakeupCriterion;
+import org.jogamp.java3d.WakeupOnAWTEvent;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseBehavior;
+import org.jogamp.vecmath.Matrix4d;
+import org.jogamp.vecmath.Vector3d;
+
+/**
+ * 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/main/java/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java b/src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java
new file mode 100644
index 0000000..2810378
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java
@@ -0,0 +1,309 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Font;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.OrientedShape3D;
+import org.jogamp.java3d.Text3D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.geometry.Cone;
+import org.jogamp.java3d.utils.geometry.Cylinder;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+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"),
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, 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 | Cone.GENERATE_TEXTURE_COORDS_Y_UP, apStone));
+ objTrans.addChild(coneTrans);
+
+ TextureLoader earthTex = new TextureLoader(earthImage, new String("RGB"),
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, 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 |
+ Cylinder.GENERATE_TEXTURE_COORDS_Y_UP, 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() {System.setProperty("sun.awt.noerasebackground", "true");
+ // the paths to the image files for an applet
+ earthImage = Resources.getResource("resources/images/earth.jpg");
+ if (earthImage == null) {
+ System.err.println("resources/images/earth.jpg not found");
+ System.exit(1);
+ }
+
+ stoneImage = Resources.getResource("resources/images/stone.jpg");
+ if (stoneImage == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.net.URL earthURL = null;
+ java.net.URL stoneURL = null;
+ earthURL = Resources.getResource("resources/images/earth.jpg");
+ if (earthURL == null) {
+ System.err.println("resources/images/earth.jpg not found");
+ System.exit(1);
+ }
+
+ stoneURL = Resources.getResource("resources/images/stone.jpg");
+ if (stoneURL == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ System.exit(1);
+ }
+
+ new MainFrame(new OrientedPtTest(earthURL, stoneURL), 400, 400);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java b/src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java
new file mode 100644
index 0000000..0f062e1
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java
@@ -0,0 +1,329 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Font;
+import java.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.OrientedShape3D;
+import org.jogamp.java3d.Text3D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseTranslate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseZoom;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.geometry.Cone;
+import org.jogamp.java3d.utils.geometry.Cylinder;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+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"),
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, 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 |
+ Cone.GENERATE_TEXTURE_COORDS_Y_UP, apStone));
+ objTrans.addChild(coneTrans);
+
+ TextureLoader earthTex = new TextureLoader(earthImage, new String("RGB"),
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP, 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 |
+ Cylinder.GENERATE_TEXTURE_COORDS_Y_UP, 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() {System.setProperty("sun.awt.noerasebackground", "true");
+ // the paths to the image files for an applet
+ earthImage = Resources.getResource("resources/images/earth.jpg");
+ if (earthImage == null) {
+ System.err.println("resources/images/earth.jpg not found");
+ System.exit(1);
+ }
+
+ stoneImage = Resources.getResource("resources/images/stone.jpg");
+ if (stoneImage == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.net.URL earthURL = null;
+ java.net.URL stoneURL = null;
+
+ earthURL = Resources.getResource("resources/images/earth.jpg");
+ if (earthURL == null) {
+ System.err.println("resources/images/earth.jpg not found");
+ System.exit(1);
+ }
+
+ stoneURL = Resources.getResource("resources/images/stone.jpg");
+ if (stoneURL == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ System.exit(1);
+ }
+
+ new MainFrame(new OrientedTest(earthURL, stoneURL), 400, 400);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/overlay2d/Canvas3D2D.java b/src/main/java/org/jdesktop/j3d/examples/overlay2d/Canvas3D2D.java
new file mode 100644
index 0000000..f0e20cb
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/overlay2d/Canvas3D2D.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.overlay2d;
+
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.J3DGraphics2D;
+
+/**
+ * This is an extension to the Canvas3D with the postRender method overridden to draw some things on the
+ * 2DGraphics of the Canvas3D
+ */
+public class Canvas3D2D extends Canvas3D
+{
+
+ public Canvas3D2D(GraphicsConfiguration gc)
+ {
+ super(gc);
+ }
+
+ @Override
+ public void postRender()
+ {
+ J3DGraphics2D g = getGraphics2D();
+
+ // draw a cross hair
+ g.drawLine((this.getWidth() / 2) - 5, (this.getHeight() / 2), (this.getWidth() / 2) + 5, (this.getHeight() / 2));
+ g.drawLine((this.getWidth() / 2), (this.getHeight() / 2) - 5, (this.getWidth() / 2), (this.getHeight() / 2) + 5);
+
+ g.drawString("This is an example String", 50, 20);
+
+ // etc e.g.
+ //g.drawImage(getBufferedImage(), 10, 50, null);
+
+ g.flush(false);
+
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/jdesktop/j3d/examples/overlay2d/Overlay2D.java b/src/main/java/org/jdesktop/j3d/examples/overlay2d/Overlay2D.java
new file mode 100644
index 0000000..adf4d8f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/overlay2d/Overlay2D.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.overlay2d;
+
+import java.awt.GraphicsConfiguration;
+import java.net.URL;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.TexCoord2f;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program to show use of the 2DGraphics overlay.
+ */
+public class Overlay2D extends javax.swing.JFrame
+{
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ public BranchGroup createSceneGraph()
+ {
+ final BranchGroup objRoot = new BranchGroup();
+
+ // Create a triangle with each point a different color. Remember to
+ // draw the points in counter-clockwise order. That is the default
+ // way of determining which is the front of a polygon.
+ // o (1)
+ // / \
+ // / \
+ // (2) o-----o (0)
+ Shape3D shape = new Shape3D();
+ TriangleArray tri = new TriangleArray(3, GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.TEXTURE_COORDINATE_2);
+ tri.setCoordinate(0, new Point3f(0.5f, 0.0f, 0.0f));
+ tri.setCoordinate(1, new Point3f(0.0f, 0.5f, 0.0f));
+ tri.setCoordinate(2, new Point3f(-0.5f, 0.0f, 0.0f));
+ tri.setColor(0, new Color3f(1.0f, 0.0f, 0.0f));
+ tri.setColor(1, new Color3f(0.0f, 1.0f, 0.0f));
+ tri.setColor(2, new Color3f(0.0f, 0.0f, 1.0f));
+ tri.setTextureCoordinate(0, 0, new TexCoord2f(1.0f, 0.0f));
+ tri.setTextureCoordinate(0, 1, new TexCoord2f(0.0f, 1.0f));
+ tri.setTextureCoordinate(0, 2, new TexCoord2f(0.0f, 0.0f));
+
+ // Because we're about to spin this triangle, be sure to draw
+ // backfaces. If we don't, the back side of the triangle is invisible.
+ Appearance ap = new Appearance();
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setCullFace(PolygonAttributes.CULL_NONE);
+ ap.setPolygonAttributes(pa);
+
+ // Add a transformed texture to the cube, for interest sake
+ URL earthURL = Resources.getResource("resources/images/earth.jpg");
+ Texture earthTex = new TextureLoader(earthURL, this).getTexture();
+ ap.setTexture(earthTex);
+
+ TextureAttributes textureAttributes = new TextureAttributes();
+ Transform3D textureTransform = new Transform3D();
+ textureTransform.rotZ(Math.PI / 3f);
+ textureTransform.setTranslation(new Vector3f(10, 1, 0));
+ textureAttributes.setTextureTransform(textureTransform);
+
+ ap.setTextureAttributes(textureAttributes);
+
+ shape.setAppearance(ap);
+
+ // Set up a simple RotationInterpolator
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 5.0);
+ TransformGroup tg = new TransformGroup();
+ Transform3D yAxis = new Transform3D();
+ Alpha rotationAlpha = new Alpha(-1, 4000);
+ tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, tg, yAxis, 0.0f, (float) Math.PI * 2.0f);
+ rotator.setSchedulingBounds(bounds);
+
+ shape.setGeometry(tri);
+ tg.addChild(rotator);
+ tg.addChild(shape);
+ objRoot.addChild(tg);
+ objRoot.compile();
+ return objRoot;
+
+ }
+
+ private Canvas3D2D createUniverse()
+ {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+
+ // Create a Canvas3D using the preferred configuration
+ Canvas3D2D c = new Canvas3D2D(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;
+ }
+
+ public Overlay2D()
+ {
+ // Initialize the GUI components
+ initComponents();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ Canvas3D2D 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("Overlay2D");
+ 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[])
+ {
+
+ System.setProperty("sun.awt.noerasebackground", "true");
+ //System.setProperty("j3d.rend", "jogl2es2");
+
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ new Overlay2D().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/main/java/org/jdesktop/j3d/examples/package_info/PackageInfo.form b/src/main/java/org/jdesktop/j3d/examples/package_info/PackageInfo.form
new file mode 100644
index 0000000..a82c39c
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/package_info/PackageInfo.form
@@ -0,0 +1,45 @@
+<?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="Package Info"/>
+ </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.JScrollPane" name="jScrollPane1">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[400, 400]"/>
+ </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.support.JScrollPaneSupportLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JTextArea" name="myTextArea">
+ <Properties>
+ <Property name="columns" type="int" value="20"/>
+ <Property name="editable" type="boolean" value="false"/>
+ <Property name="rows" type="int" value="5"/>
+ </Properties>
+ </Component>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/main/java/org/jdesktop/j3d/examples/package_info/PackageInfo.java b/src/main/java/org/jdesktop/j3d/examples/package_info/PackageInfo.java
new file mode 100644
index 0000000..d44e2a9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/package_info/PackageInfo.java
@@ -0,0 +1,139 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 javax.swing.JTextArea;
+
+public class PackageInfo extends javax.swing.JFrame {
+
+ private void pkgInfo(JTextArea textArea,
+ ClassLoader classLoader,
+ String pkgName,
+ String className) {
+
+ try {
+ classLoader.loadClass(pkgName + "." + className);
+
+ Package p = Package.getPackage(pkgName);
+ if (p == null) {
+ textArea.append("WARNING: Package.getPackage(" +
+ pkgName +
+ ") is null\n");
+ } else {
+ textArea.append(p.toString() + "\n");
+ textArea.append("Specification Title = " +
+ p.getSpecificationTitle() + "\n");
+ textArea.append("Specification Vendor = " +
+ p.getSpecificationVendor() + "\n");
+ textArea.append("Specification Version = " +
+ p.getSpecificationVersion() + "\n");
+
+ textArea.append("Implementation Vendor = " +
+ p.getImplementationVendor() + "\n");
+ textArea.append("Implementation Version = " +
+ p.getImplementationVersion() + "\n");
+ }
+ } catch (ClassNotFoundException e) {
+ textArea.append("Unable to load " + pkgName + "\n");
+ }
+
+ textArea.append("\n");
+ }
+
+ /**
+ * Creates new form PackageInfo
+ */
+ public PackageInfo() {
+ initComponents();
+
+ ClassLoader classLoader = getClass().getClassLoader();
+
+ pkgInfo(myTextArea, classLoader, "org.jogamp.vecmath", "Point3d");
+ pkgInfo(myTextArea, classLoader, "org.jogamp.java3d", "SceneGraphObject");
+ pkgInfo(myTextArea, classLoader, "com.sun.j3d.utils.universe", "SimpleUniverse");
+ }
+
+ // ----------------------------------------------------------------
+
+ /** 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() {
+ jScrollPane1 = new javax.swing.JScrollPane();
+ myTextArea = new javax.swing.JTextArea();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("Package Info");
+ jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 400));
+ myTextArea.setColumns(20);
+ myTextArea.setEditable(false);
+ myTextArea.setRows(5);
+ jScrollPane1.setViewportView(myTextArea);
+
+ getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new PackageInfo().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JTextArea myTextArea;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/package_info/QueryProperties.form b/src/main/java/org/jdesktop/j3d/examples/package_info/QueryProperties.form
new file mode 100644
index 0000000..daef961
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/package_info/QueryProperties.form
@@ -0,0 +1,44 @@
+<?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="QueryProperties"/>
+ </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"/>
+ </AuxValues>
+
+ <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+ <SubComponents>
+ <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[400, 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.support.JScrollPaneSupportLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JTextArea" name="myTextArea">
+ <Properties>
+ <Property name="columns" type="int" value="20"/>
+ <Property name="editable" type="boolean" value="false"/>
+ <Property name="rows" type="int" value="5"/>
+ </Properties>
+ </Component>
+ </SubComponents>
+ </Container>
+ </SubComponents>
+</Form>
diff --git a/src/main/java/org/jdesktop/j3d/examples/package_info/QueryProperties.java b/src/main/java/org/jdesktop/j3d/examples/package_info/QueryProperties.java
new file mode 100644
index 0000000..16a3116
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/package_info/QueryProperties.java
@@ -0,0 +1,203 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JTextArea;
+
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.VirtualUniverse;
+
+public class QueryProperties extends javax.swing.JFrame {
+
+ public static void printProps(JTextArea textArea, 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)) {
+ textArea.append(key + " = " + map.get(key) + "\n");
+ 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)) {
+ textArea.append(key + " = " + map.get(key) + "\n");
+ hs.add(key);
+ }
+ }
+ }
+ else {
+ textArea.append(propList[i] +
+ " = ERROR: KEY WITH EMBEDDED WILD CARD IGNORED\n");
+ }
+ }
+
+ // Print out the values for those properties not already printed
+ it = keyList.iterator();
+ while (it.hasNext()) {
+ key = (String)it.next();
+ if (!hs.contains(key)) {
+ textArea.append(key + " = " + map.get(key) + "\n");
+ }
+ }
+
+ }
+
+ /** Creates new form QueryProperties */
+ public QueryProperties() {
+ initComponents();
+
+ 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(myTextArea, vuMap, vuPropList);
+ myTextArea.append("\n");
+
+ 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(myTextArea, c3dMap, c3dPropList);
+ }
+
+ // ----------------------------------------------------------------
+
+ /** 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() {
+ jScrollPane1 = new javax.swing.JScrollPane();
+ myTextArea = new javax.swing.JTextArea();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("QueryProperties");
+ jScrollPane1.setPreferredSize(new java.awt.Dimension(400, 500));
+ myTextArea.setColumns(20);
+ myTextArea.setEditable(false);
+ myTextArea.setRows(5);
+ jScrollPane1.setViewportView(myTextArea);
+
+ getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new QueryProperties().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JTextArea myTextArea;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/picking/BoltCG.java b/src/main/java/org/jdesktop/j3d/examples/picking/BoltCG.java
new file mode 100644
index 0000000..44db05f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/BoltCG.java
@@ -0,0 +1,359 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.CompressedGeometry;
+import org.jogamp.java3d.CompressedGeometryHeader;
+
+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/main/java/org/jdesktop/j3d/examples/picking/ColorCube.java b/src/main/java/org/jdesktop/j3d/examples/picking/ColorCube.java
new file mode 100644
index 0000000..a92f641
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/ColorCube.java
@@ -0,0 +1,122 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.QuadArray;
+
+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/main/java/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java b/src/main/java/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java
new file mode 100644
index 0000000..3cf18cb
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java
@@ -0,0 +1,122 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.QuadArray;
+
+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/main/java/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java b/src/main/java/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java
new file mode 100644
index 0000000..c59211d
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java
@@ -0,0 +1,124 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.QuadArray;
+
+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/main/java/org/jdesktop/j3d/examples/picking/Cube.java b/src/main/java/org/jdesktop/j3d/examples/picking/Cube.java
new file mode 100644
index 0000000..4c5faf4
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/Cube.java
@@ -0,0 +1,113 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Geometry;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.vecmath.Vector3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/CubeIQA.java b/src/main/java/org/jdesktop/j3d/examples/picking/CubeIQA.java
new file mode 100644
index 0000000..e9dcd12
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/CubeIQA.java
@@ -0,0 +1,140 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedQuadArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/CubeQA.java b/src/main/java/org/jdesktop/j3d/examples/picking/CubeQA.java
new file mode 100644
index 0000000..246e506
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/CubeQA.java
@@ -0,0 +1,137 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/GullCG.java b/src/main/java/org/jdesktop/j3d/examples/picking/GullCG.java
new file mode 100644
index 0000000..dee9e2a
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/GullCG.java
@@ -0,0 +1,578 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.CompressedGeometry;
+import org.jogamp.java3d.CompressedGeometryHeader;
+
+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/main/java/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java b/src/main/java/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java
new file mode 100644
index 0000000..5d87553
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java
@@ -0,0 +1,182 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedTriangleStripArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java b/src/main/java/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java
new file mode 100644
index 0000000..065b410
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java
@@ -0,0 +1,179 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.TriangleStripArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java b/src/main/java/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java
new file mode 100644
index 0000000..56c12da
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java
@@ -0,0 +1,271 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.AWTEvent;
+import java.awt.event.MouseEvent;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Node;
+import org.jogamp.java3d.PickInfo;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.WakeupCriterion;
+import org.jogamp.java3d.WakeupOnAWTEvent;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.pickfast.PickCanvas;
+import org.jogamp.java3d.utils.pickfast.PickIntersection;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Color4f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * 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/main/java/org/jdesktop/j3d/examples/picking/IntersectTest.java b/src/main/java/org/jdesktop/j3d/examples/picking/IntersectTest.java
new file mode 100644
index 0000000..a95c377
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/IntersectTest.java
@@ -0,0 +1,251 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.GraphicsConfiguration;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.LineArray;
+import org.jogamp.java3d.PointArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.View;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "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
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/picking/MorphingBehavior.java b/src/main/java/org/jdesktop/j3d/examples/picking/MorphingBehavior.java
new file mode 100644
index 0000000..0aaf1e1
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/MorphingBehavior.java
@@ -0,0 +1,102 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.Morph;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+
+// 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/main/java/org/jdesktop/j3d/examples/picking/OctahedronITFA.java b/src/main/java/org/jdesktop/j3d/examples/picking/OctahedronITFA.java
new file mode 100644
index 0000000..b81a00b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/OctahedronITFA.java
@@ -0,0 +1,117 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedTriangleFanArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/OctahedronTFA.java b/src/main/java/org/jdesktop/j3d/examples/picking/OctahedronTFA.java
new file mode 100644
index 0000000..18e1328
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/OctahedronTFA.java
@@ -0,0 +1,116 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.TriangleFanArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java b/src/main/java/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java
new file mode 100644
index 0000000..afc5630
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java
@@ -0,0 +1,102 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Bounds;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.utils.picking.PickResult;
+import org.jogamp.java3d.utils.picking.PickTool;
+import org.jogamp.java3d.utils.picking.behaviors.PickMouseBehavior;
+import org.jogamp.vecmath.Color3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/PickTest.java b/src/main/java/org/jdesktop/j3d/examples/picking/PickTest.java
new file mode 100644
index 0000000..e36c28b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/PickTest.java
@@ -0,0 +1,442 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.border.BevelBorder;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Geometry;
+import org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Morph;
+import org.jogamp.java3d.PickInfo;
+import org.jogamp.java3d.PointAttributes;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.View;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.pickfast.behaviors.PickRotateBehavior;
+import org.jogamp.java3d.utils.pickfast.behaviors.PickTranslateBehavior;
+import org.jogamp.java3d.utils.pickfast.behaviors.PickZoomBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * 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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/picking/PickText3DBounds.java b/src/main/java/org/jdesktop/j3d/examples/picking/PickText3DBounds.java
new file mode 100644
index 0000000..35ef883
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/PickText3DBounds.java
@@ -0,0 +1,254 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Font;
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Text3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.picking.PickTool;
+import org.jogamp.java3d.utils.picking.behaviors.PickRotateBehavior;
+import org.jogamp.java3d.utils.picking.behaviors.PickTranslateBehavior;
+import org.jogamp.java3d.utils.picking.behaviors.PickZoomBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new PickText3DBounds(), 700, 700);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java b/src/main/java/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java
new file mode 100644
index 0000000..577c217
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java
@@ -0,0 +1,273 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Font;
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.Geometry;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Text3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.picking.PickTool;
+import org.jogamp.java3d.utils.picking.behaviors.PickRotateBehavior;
+import org.jogamp.java3d.utils.picking.behaviors.PickTranslateBehavior;
+import org.jogamp.java3d.utils.picking.behaviors.PickZoomBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new PickText3DGeometry(), 700, 700);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/picking/RandomColorCube.java b/src/main/java/org/jdesktop/j3d/examples/picking/RandomColorCube.java
new file mode 100644
index 0000000..e278580
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/RandomColorCube.java
@@ -0,0 +1,133 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.QuadArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java b/src/main/java/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java
new file mode 100644
index 0000000..dd8c1b0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java
@@ -0,0 +1,103 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/Tetrahedron.java b/src/main/java/org/jdesktop/j3d/examples/picking/Tetrahedron.java
new file mode 100644
index 0000000..5f8859b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/Tetrahedron.java
@@ -0,0 +1,117 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Geometry;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.TexCoord2f;
+import org.jogamp.vecmath.Vector3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TetrahedronILA.java b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronILA.java
new file mode 100644
index 0000000..507edf1
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronILA.java
@@ -0,0 +1,108 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedLineArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java
new file mode 100644
index 0000000..27af0ae
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java
@@ -0,0 +1,99 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedLineStripArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java
new file mode 100644
index 0000000..3daec58
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java
@@ -0,0 +1,83 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedPointArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TetrahedronITA.java b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronITA.java
new file mode 100644
index 0000000..b4d7a48
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronITA.java
@@ -0,0 +1,106 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.IndexedTriangleArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TetrahedronLA.java b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronLA.java
new file mode 100644
index 0000000..52ed5b6
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronLA.java
@@ -0,0 +1,106 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.LineArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java
new file mode 100644
index 0000000..5d598fd
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java
@@ -0,0 +1,96 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.LineStripArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TetrahedronPA.java b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronPA.java
new file mode 100644
index 0000000..137efef
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronPA.java
@@ -0,0 +1,73 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.PointArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TetrahedronTA.java b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronTA.java
new file mode 100644
index 0000000..aeaef87
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TetrahedronTA.java
@@ -0,0 +1,104 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.GeometryArray;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3f;
+
+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/main/java/org/jdesktop/j3d/examples/picking/TickTockPicking.form b/src/main/java/org/jdesktop/j3d/examples/picking/TickTockPicking.form
new file mode 100644
index 0000000..8d60ac0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TickTockPicking.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="TickTockPicking"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/picking/TickTockPicking.java b/src/main/java/org/jdesktop/j3d/examples/picking/TickTockPicking.java
new file mode 100644
index 0000000..b9d76f9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/picking/TickTockPicking.java
@@ -0,0 +1,488 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointAttributes;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class TickTockPicking extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+ // path the the texture map image
+ private java.net.URL texImage = 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;
+ }
+
+ 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 TickTockPicking() {
+
+ // the path to the image for an applet
+ texImage = Resources.getResource("resources/images/stone.jpg");
+ if (texImage == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ System.exit(1);
+ }
+ // 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(c);
+ 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("TickTockPicking");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new TickTockPicking().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/main/java/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java b/src/main/java/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java
new file mode 100644
index 0000000..5cb03a5
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java
@@ -0,0 +1,213 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.TransparencyAttributes;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseTranslate;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.geometry.Cylinder;
+import org.jogamp.java3d.utils.universe.PlatformGeometry;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3d;
+
+/**
+ * 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() {System.setProperty("sun.awt.noerasebackground", "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
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new SimpleGeometry(args), 256, 256);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java
new file mode 100644
index 0000000..36dfeb0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java
@@ -0,0 +1,138 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.image.BufferedImage;
+
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
+
+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/main/java/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java
new file mode 100644
index 0000000..85b00ac
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java
@@ -0,0 +1,115 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+
+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/main/java/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java
new file mode 100644
index 0000000..782e5ad
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java
@@ -0,0 +1,84 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ImageComponent;
+import org.jogamp.java3d.ImageComponent2D;
+
+
+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/main/java/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form
new file mode 100644
index 0000000..5150ee2
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java
new file mode 100644
index 0000000..23b881f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java
@@ -0,0 +1,402 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Dimension;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Point;
+import java.awt.image.BufferedImage;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.swing.JPopupMenu;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.Screen3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.loaders.IncorrectFormatException;
+import org.jogamp.java3d.loaders.ParsingErrorException;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.objectfile.ObjectFile;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseRotate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseTranslate;
+import org.jogamp.java3d.utils.behaviors.mouse.MouseZoom;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+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 URL 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) {
+ filename = Resources.getResource("resources/geometry/beethoven.obj");
+ if (filename == null) {
+ System.err.println("resources/geometry/beethoven.obj not found");
+ System.exit(1);
+ }
+ } else {
+ for (int i = 0 ; i < args.length ; i++) {
+ if (args[i].startsWith("-")) {
+ System.err.println("Argument '" + args[i] + "' ignored.");
+ } else {
+ try{
+ filename = new URL(args[i]);
+ }
+ catch (MalformedURLException e) {
+ System.err.println(e.getMessage());
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+ 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/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.form b/src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.form
new file mode 100644
index 0000000..3c5f559
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.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="PureImmediate"/>
+ </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/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java b/src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java
new file mode 100644
index 0000000..7648cba
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java
@@ -0,0 +1,186 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.Geometry;
+import org.jogamp.java3d.GraphicsContext3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+
+/**
+ * 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 javax.swing.JFrame implements Runnable {
+
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ 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);
+
+ //
+ // 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();
+ }
+ }
+
+
+ private void createUniverse() {
+ // Get the preferred graphics configuration for the default screen
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ // Create a Canvas3D using the preferred configuration
+ canvas = new Canvas3D(config);
+ canvas.stopRenderer();
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(canvas);
+
+ // 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);
+ }
+
+ /**
+ * Creates new form PureImmediate
+ */
+ public PureImmediate() {
+ // Initialize the GUI components
+ initComponents();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ createUniverse();
+ drawingPanel.add(canvas, java.awt.BorderLayout.CENTER);
+
+ // Start a new thread that will continuously render
+ new Thread(this).start();
+ }
+
+ // ----------------------------------------------------------------
+
+ /** 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("PureImmediate");
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new PureImmediate().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/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.form b/src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.form
new file mode 100644
index 0000000..dd881b5
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.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="PureImmediateStereo"/>
+ </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="[512, 256]"/>
+ </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/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java b/src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java
new file mode 100644
index 0000000..9e0f0e5
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java
@@ -0,0 +1,308 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.util.Map;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.GraphicsContext3D;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.utils.geometry.Cone;
+import org.jogamp.java3d.utils.geometry.Primitive;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * 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 javax.swing.JFrame implements Runnable {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ // 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 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();
+ }
+ }
+
+
+ private void createUniverse() {
+ // 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();
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(canvas);
+
+ // 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);
+
+ // Start a new thread that will continuously render
+ (new Thread(this)).start();
+ }
+
+ /**
+ * Creates new form PureImmediateStereo
+ */
+ public PureImmediateStereo() {
+ // Initialize the GUI components
+ initComponents();
+
+ // Create Canvas3D and SimpleUniverse; add canvas to drawing panel
+ createUniverse();
+ drawingPanel.add(canvas, 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() {
+ drawingPanel = new javax.swing.JPanel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("PureImmediateStereo");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(512, 256));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new PureImmediateStereo().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/main/java/org/jdesktop/j3d/examples/read_raster/ReadRaster.java b/src/main/java/org/jdesktop/j3d/examples/read_raster/ReadRaster.java
new file mode 100644
index 0000000..780e3fe
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/read_raster/ReadRaster.java
@@ -0,0 +1,236 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.GraphicsConfiguration;
+import java.awt.image.BufferedImage;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.GraphicsContext3D;
+import org.jogamp.java3d.ImageComponent;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Raster;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+
+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, true, true);
+
+ 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() {System.setProperty("sun.awt.noerasebackground", "true");
+
+ int width = 128;
+ int height = 128;
+
+ ImageComponent2D readImageComponent = new ImageComponent2D(
+ ImageComponent.FORMAT_RGB, width, height, false, true);
+
+ 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_RGB);
+
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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, true, true);
+ drawRaster.setImage(newImageComponent);
+ super.processStimulus(criteria);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sound/AudioReverberate.java b/src/main/java/org/jdesktop/j3d/examples/sound/AudioReverberate.java
new file mode 100644
index 0000000..f54b43f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/AudioReverberate.java
@@ -0,0 +1,177 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.net.URL;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.AuralAttributes;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.MediaContainer;
+import org.jogamp.java3d.PointSound;
+import org.jogamp.java3d.WakeupOnBehaviorPost;
+import org.jogamp.java3d.WakeupOnElapsedTime;
+import org.jogamp.vecmath.Point3f;
+
+/*
+ * 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;
+ URL url = null;
+ 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.setURLObject(url);
+ 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, URL url, AuralAttributes sscape) {
+ this.psound = psound;
+ this.url = url;
+ this.sScape = sscape;
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundBehavior.java b/src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundBehavior.java
new file mode 100644
index 0000000..bc8f5e6
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundBehavior.java
@@ -0,0 +1,85 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.net.URL;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.BackgroundSound;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.Bounds;
+import org.jogamp.java3d.MediaContainer;
+import org.jogamp.java3d.WakeupCondition;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+import org.jogamp.vecmath.Point3d;
+
+public class BackgroundSoundBehavior extends Behavior {
+
+ private WakeupCondition condition = new WakeupOnElapsedFrames(0);
+
+ /** Creates a new instance of BackgroundSoundBehavior */
+ public BackgroundSoundBehavior(BackgroundSound bgs, URL url) {
+
+ Bounds b = new BoundingSphere(new Point3d(), 20);
+ bgs.setSoundData(new MediaContainer(url));
+ bgs.setEnable(true);
+ bgs.setPause(false);
+ bgs.setLoop(-1);
+ bgs.setContinuousEnable(true);
+ bgs.setSchedulingBounds(b);
+
+ }
+
+ public void initialize() {
+
+ wakeupOn(condition);
+ }
+
+ public void processStimulus(Enumeration enumeration) {
+ wakeupOn(condition);
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundTest.form b/src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundTest.form
new file mode 100644
index 0000000..9a2f209
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundTest.form
@@ -0,0 +1,37 @@
+<?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="BackgroundSoundTest"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+ <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="[800, 600]"/>
+ </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/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundTest.java b/src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundTest.java
new file mode 100644
index 0000000..b2011d0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/BackgroundSoundTest.java
@@ -0,0 +1,289 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.net.URL;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BackgroundSound;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.Bounds;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.LineArray;
+import org.jogamp.java3d.LineAttributes;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Sound;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.Viewer;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * This is a test for a BackgroundSound.
+ * This program is ported from an earlier version of BackgroundSoundTest, in the j3d-incubator project,
+ * contributed by David Grace ([email protected]).
+ *
+ */
+public class BackgroundSoundTest extends javax.swing.JFrame {
+
+ private URL url = null;
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ //The activation radius for the ViewPlatform
+ private float activationRadius = 1;
+
+ private Shape3D getDefaultGrid(int noOfLines, double size, double height){
+
+ Shape3D shape = new Shape3D();
+ double lineLength = noOfLines * size / 2;
+ LineArray la = new LineArray(noOfLines * 4, LineArray.COORDINATES);
+ int count = 0;
+ for (int i=0; i<noOfLines; i++){
+ la.setCoordinate(count, new Point3d(-lineLength, height, i*size - lineLength));
+ count++;
+ la.setCoordinate(count, new Point3d(lineLength, height, i*size - lineLength));
+ count++;
+ }
+ for (int i=0; i<noOfLines; i++){
+ la.setCoordinate(count, new Point3d(i*size - lineLength, height, -lineLength));
+ count++;
+ la.setCoordinate(count, new Point3d(i*size - lineLength, height, lineLength));
+ count++;
+ }
+ shape.setGeometry(la);
+ Appearance a = new Appearance();
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(0.3f, 0.3f, 0.3f);
+ a.setColoringAttributes(ca);
+ LineAttributes sla = new LineAttributes();
+ sla.setLineWidth(1.0f);
+ a.setLineAttributes(sla);
+ shape.setAppearance(a);
+
+ return shape;
+ }
+
+
+ private Sphere createSoundBoundingGeometry(Sound sound){
+ Bounds bounds = sound.getSchedulingBounds();
+ assert ((bounds != null) && (bounds instanceof BoundingSphere));
+ BoundingSphere bs = (BoundingSphere) bounds;
+ float radius = (float) bs.getRadius();
+
+ return getSphere(radius);
+ }
+
+ private Sphere getSphere(float radius){
+
+ Appearance a = new Appearance();
+ Material m = new Material();
+
+ m.setDiffuseColor(1, 0, 0);
+ m.setAmbientColor(1, 0, 0);
+ m.setShininess(8);
+ a.setMaterial(m);
+
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(PolygonAttributes.POLYGON_LINE);
+ pa.setCullFace(PolygonAttributes.CULL_NONE);
+ a.setPolygonAttributes(pa);
+ return new Sphere(radius, a);
+ }
+
+ private TransformGroup createSoundNodeGeometry(float x, float y, float z){
+
+ TransformGroup rootTransformGroup = new TransformGroup();
+ Transform3D t3D = new Transform3D();
+ t3D.setTranslation(new Vector3f(x, y, z));
+ rootTransformGroup.setTransform(t3D);
+ ColorCube cc = new ColorCube(0.1);
+ rootTransformGroup.addChild(cc);
+ return rootTransformGroup;
+ }
+
+
+ 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);
+
+ AmbientLight al = new AmbientLight();
+ al.setInfluencingBounds(bounds);
+
+ DirectionalLight dl = new DirectionalLight();
+ dl.setDirection(-1, -1, -1);
+ dl.setInfluencingBounds(bounds);
+ objRoot.addChild(al);
+ objRoot.addChild(dl);
+
+ /*
+ * Create Sound and Behavior objects that will play the sound
+ */
+ BackgroundSound bgs = new BackgroundSound();
+ BackgroundSoundBehavior player = new BackgroundSoundBehavior( bgs, url);
+ player.setSchedulingBounds(bounds);
+ objRoot.addChild(bgs);
+ objRoot.addChild(player);
+
+ objRoot.addChild(getDefaultGrid(40, 1, -1));
+ objRoot.addChild(createSoundNodeGeometry(0, 0, 0));
+ objRoot.addChild(createSoundBoundingGeometry(bgs));
+ 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);
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ TransformGroup viewingPlatformTransformGroup = viewingPlatform.getViewPlatformTransform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ Viewer viewer = univ.getViewer();
+
+ viewer.createAudioDevice();
+ viewer.getView().setBackClipDistance(1000.0f);
+
+ // Ensure at least 50 msec per frame.
+ viewer.getView().setMinimumFrameCycleTime(30);
+
+ viewer.getView().getViewPlatform().setActivationRadius(activationRadius);
+
+ BranchGroup bg = new BranchGroup();
+ KeyNavigatorBehavior knb = new KeyNavigatorBehavior(c, viewingPlatformTransformGroup);
+ Bounds b = new BoundingSphere(new Point3d(), Double.POSITIVE_INFINITY);
+ knb.setSchedulingBounds(b);
+ bg.addChild(knb);
+ univ.addBranchGraph(bg);
+
+ return c;
+ }
+
+ /**
+ * Creates new form BackgroundSoundTest
+ */
+ public BackgroundSoundTest() {
+ // Initialize the GUI components
+ initComponents();
+
+ url = Resources.getResource("resources/audio/magic_bells.wav");
+ if (url == null) {
+ System.err.println("resources/audio/magic_bells.wav not found");
+ System.exit(1);
+ }
+
+ // 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("BackgroundSoundTest");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(800, 600));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new BackgroundSoundTest().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/main/java/org/jdesktop/j3d/examples/sound/PointSoundBehavior.java b/src/main/java/org/jdesktop/j3d/examples/sound/PointSoundBehavior.java
new file mode 100644
index 0000000..754847c
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/PointSoundBehavior.java
@@ -0,0 +1,89 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.net.URL;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.Bounds;
+import org.jogamp.java3d.MediaContainer;
+import org.jogamp.java3d.PointSound;
+import org.jogamp.java3d.WakeupCondition;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+
+public class PointSoundBehavior extends Behavior {
+
+ private WakeupCondition condition = new WakeupOnElapsedFrames(0);
+
+ /** Creates a new instance of PointSoundBehavior */
+ public PointSoundBehavior(PointSound ps, URL url, Point3f pos) {
+
+ Bounds b = new BoundingSphere(new Point3d(), 40);
+ ps.setSoundData(new MediaContainer(url));
+ ps.setPosition(pos);
+ float distanceAtZero = 30;
+ ps.setDistanceGain(new float []{0, distanceAtZero}, new float []{1, 0});
+ ps.setEnable(true);
+ ps.setPause(false);
+ ps.setContinuousEnable(true);
+ ps.setSchedulingBounds(b);
+ ps.setLoop(-1);
+
+ }
+
+ public void initialize() {
+
+ wakeupOn(condition);
+ }
+
+ public void processStimulus(Enumeration enumeration) {
+ wakeupOn(condition);
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sound/PointSoundTest.form b/src/main/java/org/jdesktop/j3d/examples/sound/PointSoundTest.form
new file mode 100644
index 0000000..41f5f7d
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/PointSoundTest.form
@@ -0,0 +1,37 @@
+<?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="PointSound Test"/>
+ </Properties>
+ <SyntheticProperties>
+ <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+ </SyntheticProperties>
+ <AuxValues>
+ <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+ <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="[800, 600]"/>
+ </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/main/java/org/jdesktop/j3d/examples/sound/PointSoundTest.java b/src/main/java/org/jdesktop/j3d/examples/sound/PointSoundTest.java
new file mode 100644
index 0000000..a39bc87
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/PointSoundTest.java
@@ -0,0 +1,318 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+import java.net.URL;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.Bounds;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.LineArray;
+import org.jogamp.java3d.LineAttributes;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointSound;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Sound;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.Viewer;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * This is a test for a PointSound.
+ * This program is ported from an earlier version of PointSoundTest, in the j3d-incubator project,
+ * contributed by David Grace ([email protected]).
+ *
+ */
+public class PointSoundTest extends javax.swing.JFrame {
+
+ private URL url = null;
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ //The activation radius for the ViewPlatform
+ private float activationRadius = 1;
+
+ private Shape3D getDefaultGrid(int noOfLines, double size, double height){
+
+ Shape3D shape = new Shape3D();
+ double lineLength = noOfLines * size / 2;
+ LineArray la = new LineArray(noOfLines * 4, LineArray.COORDINATES);
+ int count = 0;
+ for (int i=0; i<noOfLines; i++){
+ la.setCoordinate(count, new Point3d(-lineLength, height, i*size - lineLength));
+ count++;
+ la.setCoordinate(count, new Point3d(lineLength, height, i*size - lineLength));
+ count++;
+ }
+ for (int i=0; i<noOfLines; i++){
+ la.setCoordinate(count, new Point3d(i*size - lineLength, height, -lineLength));
+ count++;
+ la.setCoordinate(count, new Point3d(i*size - lineLength, height, lineLength));
+ count++;
+ }
+ shape.setGeometry(la);
+ Appearance a = new Appearance();
+ ColoringAttributes ca = new ColoringAttributes();
+ ca.setColor(0.3f, 0.3f, 0.3f);
+ a.setColoringAttributes(ca);
+ LineAttributes sla = new LineAttributes();
+ sla.setLineWidth(1.0f);
+ a.setLineAttributes(sla);
+ shape.setAppearance(a);
+
+ return shape;
+ }
+
+ private Group createSoundBoundingGeometries(PointSound ps) {
+ Group group = new Group();
+ Sphere sphere1 = getInnerBoundingSphere(ps);
+ group.addChild(sphere1);
+
+ assert(ps.getDistanceGainLength() == 2);
+
+ // create geometry for outer Bounding Sphere
+ float [] ds = new float [ps.getDistanceGainLength()];
+ float [] as = new float [ps.getDistanceGainLength()];
+ ps.getDistanceGain(ds, as);
+ float distanceAtZero = ds[ps.getDistanceGainLength() - 1];
+
+ Sphere sphere2 = getSphere(distanceAtZero, false);
+ group.addChild(sphere2);
+
+ return group;
+ }
+
+ private Sphere getInnerBoundingSphere(Sound sound){
+ Bounds bounds = sound.getSchedulingBounds();
+ assert ((bounds != null) && (bounds instanceof BoundingSphere));
+ BoundingSphere bs = (BoundingSphere) bounds;
+ float radius = (float) bs.getRadius();
+
+ return getSphere(radius, true);
+ }
+
+ private Sphere getSphere(float radius, boolean inner){
+
+ Appearance a = new Appearance();
+ Material m = new Material();
+
+ if (inner) {
+ m.setDiffuseColor(1, 0, 0);
+ m.setAmbientColor(1, 0, 0);
+ m.setShininess(8);
+ } else {
+ m.setDiffuseColor(0, 1, 0);
+ m.setAmbientColor(0, 1, 0);
+ m.setShininess(8);
+ }
+ a.setMaterial(m);
+
+ PolygonAttributes pa = new PolygonAttributes();
+ pa.setPolygonMode(PolygonAttributes.POLYGON_LINE);
+ pa.setCullFace(PolygonAttributes.CULL_NONE);
+ a.setPolygonAttributes(pa);
+ return new Sphere(radius, a);
+ }
+
+ private TransformGroup createSoundNodeGeometry(float x, float y, float z){
+
+ TransformGroup rootTransformGroup = new TransformGroup();
+ Transform3D t3D = new Transform3D();
+ t3D.setTranslation(new Vector3f(x, y, z));
+ rootTransformGroup.setTransform(t3D);
+ ColorCube cc = new ColorCube(0.1);
+ rootTransformGroup.addChild(cc);
+ return rootTransformGroup;
+ }
+
+
+ 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);
+
+ AmbientLight al = new AmbientLight();
+ al.setInfluencingBounds(bounds);
+
+ DirectionalLight dl = new DirectionalLight();
+ dl.setDirection(-1, -1, -1);
+ dl.setInfluencingBounds(bounds);
+ objRoot.addChild(al);
+ objRoot.addChild(dl);
+
+ /*
+ * Create Sound and Behavior objects that will play the sound
+ */
+ PointSound ps = new PointSound();
+ PointSoundBehavior player = new PointSoundBehavior( ps, url, new Point3f(0.0f, 0.0f, 0.0f));
+ player.setSchedulingBounds(bounds);
+ objRoot.addChild(ps);
+ objRoot.addChild(player);
+
+ objRoot.addChild(getDefaultGrid(40, 1, -1));
+ objRoot.addChild(createSoundNodeGeometry(0, 0, 0));
+ objRoot.addChild(createSoundBoundingGeometries(ps));
+ 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);
+
+ ViewingPlatform viewingPlatform = univ.getViewingPlatform();
+ TransformGroup viewingPlatformTransformGroup = viewingPlatform.getViewPlatformTransform();
+
+ // This will move the ViewPlatform back a bit so the
+ // objects in the scene can be viewed.
+ viewingPlatform.setNominalViewingTransform();
+
+ Viewer viewer = univ.getViewer();
+
+ viewer.createAudioDevice();
+ viewer.getView().setBackClipDistance(1000.0f);
+
+ // Ensure at least 50 msec per frame.
+ viewer.getView().setMinimumFrameCycleTime(30);
+
+ viewer.getView().getViewPlatform().setActivationRadius(activationRadius);
+
+ BranchGroup bg = new BranchGroup();
+ KeyNavigatorBehavior knb = new KeyNavigatorBehavior(c, viewingPlatformTransformGroup);
+ Bounds b = new BoundingSphere(new Point3d(), Double.POSITIVE_INFINITY);
+ knb.setSchedulingBounds(b);
+ bg.addChild(knb);
+ univ.addBranchGraph(bg);
+
+ return c;
+ }
+
+
+ /**
+ * Creates new form PointSoundTest
+ */
+ public PointSoundTest() {
+ // Initialize the GUI components
+ initComponents();
+
+ url = Resources.getResource("resources/audio/magic_bells.wav");
+ if (url == null) {
+ System.err.println("resources/audio/magic_bells.wav not found");
+ System.exit(1);
+ }
+
+ // 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("PointSound Test");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(800, 600));
+ 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new PointSoundTest().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/main/java/org/jdesktop/j3d/examples/sound/ReverberateSound.java b/src/main/java/org/jdesktop/j3d/examples/sound/ReverberateSound.java
new file mode 100644
index 0000000..9cf7ad0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/ReverberateSound.java
@@ -0,0 +1,202 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.GraphicsConfiguration;
+import java.net.URL;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AudioDevice;
+import org.jogamp.java3d.AuralAttributes;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.PointSound;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Soundscape;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+public class ReverberateSound extends Applet {
+
+ // File name of sound sample
+ private static URL url = null;
+ 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, url, attributes2);
+ player.setSchedulingBounds(bounds);
+ objTrans.addChild(player);
+
+ return objRoot;
+ }
+
+ public ReverberateSound() {
+ }
+
+ public void init() {System.setProperty("sun.awt.noerasebackground", "true");
+ url = Resources.getResource("resources/audio/hello_universe.au");
+ if (url == null) {
+ System.err.println("resources/audio/hello_universe.au not found");
+ 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
+ */
+ 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);
+
+ JOptionPane.showMessageDialog(this,
+ ("This program is still a work in progress.\n" +
+ "Please check back in Java 3D 1.5.\n"),
+ "Incomplete Work",
+ JOptionPane.INFORMATION_MESSAGE);
+ }
+
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new ReverberateSound(), 256, 256);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sound/SimpleSounds.java b/src/main/java/org/jdesktop/j3d/examples/sound/SimpleSounds.java
new file mode 100644
index 0000000..c5df424
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/SimpleSounds.java
@@ -0,0 +1,262 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.BorderLayout;
+import java.awt.GraphicsConfiguration;
+import java.net.URL;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AudioDevice;
+import org.jogamp.java3d.BackgroundSound;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.PointSound;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+/*
+ * 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 {
+
+ private static URL[] url = new URL[3];
+ 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() {System.setProperty("sun.awt.noerasebackground", "true");
+
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+ add("Center", c);
+
+ url[0] = Resources.getResource("resources/audio/techno_machine.au");
+ if (url == null) {
+ System.err.println("resources/audio/techno_machine.au not found");
+ System.exit(1);
+ }
+
+ url[1] = Resources.getResource("resources/audio/hello_universe.au");
+ if (url == null) {
+ System.err.println("resources/audio/hello_universe.au not found");
+ System.exit(1);
+ }
+
+ url[2] = Resources.getResource("resources/audio/roar.au");
+ if (url == null) {
+ System.err.println("resources/audio/roar.au not found");
+ System.exit(1);
+ }
+
+ /*
+ * 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);
+
+ JOptionPane.showMessageDialog(this,
+ ("This program is still a work in progress.\n" +
+ "Please check back in Java 3D 1.5.\n"),
+ "Incomplete Work",
+ JOptionPane.INFORMATION_MESSAGE);
+ }
+
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new SimpleSounds(), args, 256, 256);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java b/src/main/java/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java
new file mode 100644
index 0000000..3c7560e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java
@@ -0,0 +1,187 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.net.URL;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.BackgroundSound;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.MediaContainer;
+import org.jogamp.java3d.PointSound;
+import org.jogamp.java3d.Sound;
+import org.jogamp.java3d.WakeupOnBehaviorPost;
+import org.jogamp.java3d.WakeupOnElapsedTime;
+import org.jogamp.vecmath.Point3f;
+
+// 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/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.form b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.form
new file mode 100644
index 0000000..036d770
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.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="SphereMotion"/>
+ </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="[700, 700]"/>
+ </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/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java
new file mode 100644
index 0000000..f98085b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java
@@ -0,0 +1,365 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.PositionInterpolator;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.SpotLight;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class SphereMotion extends javax.swing.JFrame {
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ // 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;
+
+ 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 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 =
+ univ.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 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 SphereMotion
+ */
+ public SphereMotion(final 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);
+ }
+ }
+
+ // 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("SphereMotion");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[]) {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ SphereMotion sphereMotion = new SphereMotion(args);
+ sphereMotion.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/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGL2ES2.java b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGL2ES2.java
new file mode 100644
index 0000000..547c998
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGL2ES2.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.sphere_motion;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+
+import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.PositionInterpolator;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.SpotLight;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class SphereMotionGL2ES2 extends javax.swing.JFrame
+{
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ // 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;
+
+ 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 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(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.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 SimpleShaderAppearance(false, false);
+ Appearance appL2 = new SimpleShaderAppearance(false, false);
+ 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 = univ.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 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 SphereMotion
+ */
+ public SphereMotionGL2ES2(final 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);
+ }
+ }
+
+ // 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("SphereMotionGL2ES2");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ SphereMotionGL2ES2 sphereMotion = new SphereMotionGL2ES2(args);
+ sphereMotion.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/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGL2ES3_Texture.java b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGL2ES3_Texture.java
new file mode 100644
index 0000000..a1cee22
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGL2ES3_Texture.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+package org.jdesktop.j3d.examples.sphere_motion;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jdesktop.j3d.examples.gl2es2pipeline.SimpleShaderAppearance;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.PositionInterpolator;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.SpotLight;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class SphereMotionGL2ES3_Texture extends javax.swing.JFrame
+{
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ // 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;
+
+ 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 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(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.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);
+ shaderProgram.setShaderAttrNames(new String[] { "BaseMap" });
+
+ a.setShaderProgram(shaderProgram);
+
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ shaderAttributeSet.put(new ShaderAttributeValue("BaseMap", new Integer(0)));
+ a.setShaderAttributeSet(shaderAttributeSet);
+
+
+ a.setMaterial(m);
+ Texture txtr = new TextureLoader(Resources.getResource("resources/images/earth.jpg"), this).getTexture();
+ a.setTexture(txtr);
+ Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS | Sphere.GENERATE_TEXTURE_COORDS, 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 SimpleShaderAppearance(false, false);
+ Appearance appL2 = new SimpleShaderAppearance(false, false);
+ 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 = univ.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 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 SphereMotion
+ */
+ public SphereMotionGL2ES3_Texture(final 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);
+ }
+ }
+
+ // 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("SphereMotionGL2ES2_Texture");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ System.setProperty("j3d.rend", "jogl2es2");
+ System.setProperty("j3d.displaylist", "false");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ SphereMotionGL2ES3_Texture sphereMotion = new SphereMotionGL2ES3_Texture(args);
+ sphereMotion.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/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGLSL_FFP.java b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGLSL_FFP.java
new file mode 100644
index 0000000..ce1fdc0
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/SphereMotionGLSL_FFP.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.sphere_motion;
+
+import java.awt.GraphicsConfiguration;
+import java.io.File;
+import java.io.IOException;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PointLight;
+import org.jogamp.java3d.PositionInterpolator;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.java3d.SpotLight;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.shader.StringIO;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+public class SphereMotionGLSL_FFP extends javax.swing.JFrame
+{
+
+ private SimpleUniverse univ = null;
+ private BranchGroup scene = null;
+
+ // 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;
+
+ 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 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(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.vert"));
+ fragmentProgram = StringIO.readFully(
+ new File(System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.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 = univ.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 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 SphereMotion
+ */
+ public SphereMotionGLSL_FFP(final 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);
+ }
+ }
+
+ // 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("SphereMotionGLSL_FFP");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ SphereMotionGLSL_FFP sphereMotion = new SphereMotionGLSL_FFP(args);
+ sphereMotion.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/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.frag b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.frag
new file mode 100644
index 0000000..ba72696
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.frag
@@ -0,0 +1,66 @@
+#version 120
+
+// Per-pixel normal (input from vertex shader)
+varying vec3 normalDirection;
+varying vec3 viewDirection;
+varying vec4 position;
+
+const int numberOfLights = 2;
+
+void main()
+{
+ vec3 lightDirection;
+ float attenuation;
+
+ // initialize total lighting with ambient lighting
+ vec3 totalLighting = vec3(gl_FrontMaterial.emission) + (vec3(gl_LightModel.ambient) * vec3(gl_FrontMaterial.ambient));
+
+ for (int index = 0; index < numberOfLights; index++) // for all light sources
+ {
+ if (0.0 == gl_LightSource[index].position.w) // directional light?
+ {
+ attenuation = 1.0; // no attenuation
+ lightDirection = normalize(vec3(gl_LightSource[index].position));
+ }
+ else // point light or spotlight (or other kind of light)
+ {
+ vec3 positionToLightSource = vec3(gl_LightSource[index].position - position);
+ float distance = length(positionToLightSource);
+ lightDirection = normalize(positionToLightSource);
+ attenuation = 1.0 / (gl_LightSource[index].constantAttenuation
+ + gl_LightSource[index].linearAttenuation * distance
+ + gl_LightSource[index].quadraticAttenuation * distance * distance);
+
+
+ if (gl_LightSource[index].spotCutoff <= 90.0) // spotlight?
+ {
+ float clampedCosine = max(0.0, dot(-lightDirection, normalize(gl_LightSource[index].spotDirection)));
+ if (clampedCosine < cos(radians(gl_LightSource[index].spotCutoff))) // outside of spotlight cone?
+ {
+ attenuation = 0.0;
+ }
+ else
+ {
+ attenuation = attenuation * pow(clampedCosine, gl_LightSource[index].spotExponent);
+ }
+ }
+ }
+
+ vec3 diffuseReflection = attenuation * vec3(gl_LightSource[index].diffuse) * vec3(gl_FrontMaterial.diffuse)* max(0.0, dot(normalDirection, lightDirection));
+
+ vec3 specularReflection;
+ if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
+ {
+ specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
+ }
+ else // light source on the right side
+ {
+ specularReflection = attenuation * vec3(gl_LightSource[index].specular) * vec3(gl_FrontMaterial.specular)
+ * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), gl_FrontMaterial.shininess);
+ }
+
+ totalLighting = totalLighting + diffuseReflection + specularReflection;
+ }
+
+ gl_FragColor = vec4(totalLighting, 1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.vert b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.vert
new file mode 100644
index 0000000..caf1732
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_ffp.vert
@@ -0,0 +1,19 @@
+
+
+// A GLSL vertex program for doing Phone shading (per-fragment lighting)
+
+// Per-pixel normal (output to fragment shader)
+varying vec3 normalDirection;
+varying vec3 viewDirection;
+varying vec4 position;
+
+void main()
+{
+ normalDirection = normalize(vec3(gl_NormalMatrix * gl_Normal));
+ vec3 v = vec3(gl_ModelViewMatrix * gl_Vertex);
+ viewDirection = normalize(-v.xyz);
+ position = vec4(v,1);
+
+ // Transform the vertex
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.frag b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.frag
new file mode 100644
index 0000000..af65808
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.frag
@@ -0,0 +1,96 @@
+#version 120
+
+// Per-pixel normal (input from vertex shader)
+varying vec3 normalDirection;
+varying vec3 viewDirection;
+varying vec4 position;
+
+uniform vec4 glLightModelambient;
+
+
+struct material
+{
+ int lightEnabled;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 emission;// note vec4 extra 1.0 sent through for ease
+ vec3 specular;
+ float shininess;
+};
+uniform material glFrontMaterial;
+
+struct lightSource
+{
+ int enabled;
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ float constantAttenuation, linearAttenuation, quadraticAttenuation;
+ float spotCutoff, spotExponent;
+ vec3 spotDirection;
+};
+
+uniform int numberOfLights;
+const int maxLights = 2;
+uniform lightSource glLightSource[maxLights];
+
+void main()
+{
+ vec3 lightDirection;
+ float attenuation;
+
+ // initialize total lighting with ambient lighting
+ vec3 totalLighting = vec3(glFrontMaterial.emission) + (vec3(glLightModelambient) * vec3(glFrontMaterial.ambient));
+
+ for (int index = 0; index < numberOfLights; index++) // for all light sources
+ {
+ if(glLightSource[index].enabled == 1)
+ {
+ if (0.0 == glLightSource[index].position.w) // directional light?
+ {
+ attenuation = 1.0; // no attenuation
+ lightDirection = normalize(vec3(glLightSource[index].position));
+
+ }
+ else // point light or spotlight (or other kind of light)
+ {
+ vec3 positionToLightSource = vec3(glLightSource[index].position - position);
+ float distance = length(positionToLightSource);
+ lightDirection = normalize(positionToLightSource);
+ attenuation = 1.0 / (glLightSource[index].constantAttenuation
+ + glLightSource[index].linearAttenuation * distance
+ + glLightSource[index].quadraticAttenuation * distance * distance);
+
+ if (glLightSource[index].spotCutoff <= 90.0) // spotlight?
+ {
+ float clampedCosine = max(0.0, dot(-lightDirection, normalize(glLightSource[index].spotDirection)));
+ if (clampedCosine < cos(radians(glLightSource[index].spotCutoff))) // outside of spotlight cone?
+ {
+ attenuation = 0.0;
+ }
+ else
+ {
+ attenuation = attenuation * pow(clampedCosine, glLightSource[index].spotExponent);
+ }
+ }
+ }
+
+ vec3 diffuseReflection = attenuation * vec3(glLightSource[index].diffuse) * vec3(glFrontMaterial.diffuse)* max(0.0, dot(normalDirection, lightDirection));
+
+ vec3 specularReflection;
+ if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
+ {
+ specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
+ }
+ else // light source on the right side
+ {
+ specularReflection = attenuation * vec3(glLightSource[index].specular) * vec3(glFrontMaterial.specular)
+ * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), glFrontMaterial.shininess);
+ }
+
+ totalLighting = totalLighting + diffuseReflection + specularReflection;
+ }
+ }
+
+ gl_FragColor = vec4(totalLighting, 1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.vert b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.vert
new file mode 100644
index 0000000..4d8fb67
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2.vert
@@ -0,0 +1,31 @@
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat4 glModelViewMatrix;
+uniform mat3 glNormalMatrix;
+
+
+// Per-pixel normal (output to fragment shader)
+varying vec3 normalDirection;
+varying vec3 viewDirection;
+varying vec4 position;
+
+void main()
+{
+ normalDirection = normalize(vec3(glNormalMatrix * glNormal));
+ vec3 v = vec3(glModelViewMatrix * glVertex);
+ viewDirection = normalize(-v.xyz);
+ position = vec4(v,1);
+
+ // Transform the vertex
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+}
+
+
+
+
+
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.frag b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.frag
new file mode 100644
index 0000000..2b1a258
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.frag
@@ -0,0 +1,105 @@
+#version 120
+
+// Per-pixel normal (input from vertex shader)
+varying vec3 normalDirection;
+varying vec3 viewDirection;
+varying vec4 position;
+
+varying vec2 glTexCoord0;
+uniform sampler2D BaseMap;
+
+uniform vec4 glLightModelambient;
+
+
+struct material
+{
+ int lightEnabled;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 emission;
+ vec3 specular;
+ float shininess;
+};
+uniform material glFrontMaterial;
+
+struct lightSource
+{
+ int enabled;
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ float constantAttenuation, linearAttenuation, quadraticAttenuation;
+ float spotCutoff, spotExponent;
+ vec3 spotDirection;
+};
+
+uniform int numberOfLights;
+const int maxLights = 2;
+uniform lightSource glLightSource[maxLights];
+
+void main()
+{
+ vec4 baseMap = texture2D( BaseMap, glTexCoord0.st );
+
+ vec3 lightDirection;
+ float attenuation;
+
+ // initialize total lighting with ambient lighting
+ vec3 totalDiffuseLighting = vec3(glFrontMaterial.emission) + (vec3(glLightModelambient) * vec3(glFrontMaterial.ambient));
+ vec3 totalSpecularLighting;
+
+ for (int index = 0; index < numberOfLights; index++) // for all light sources
+ {
+ if(glLightSource[index].enabled == 1)
+ {
+ if (0.0 == glLightSource[index].position.w) // directional light?
+ {
+ attenuation = 1.0; // no attenuation
+ lightDirection = normalize(vec3(glLightSource[index].position));
+
+ }
+ else // point light or spotlight (or other kind of light)
+ {
+ vec3 positionToLightSource = vec3(glLightSource[index].position - position);
+ float distance = length(positionToLightSource);
+ lightDirection = normalize(positionToLightSource);
+ attenuation = 1.0 / (glLightSource[index].constantAttenuation
+ + glLightSource[index].linearAttenuation * distance
+ + glLightSource[index].quadraticAttenuation * distance * distance);
+
+ if (glLightSource[index].spotCutoff <= 90.0) // spotlight?
+ {
+ float clampedCosine = max(0.0, dot(-lightDirection, normalize(glLightSource[index].spotDirection)));
+ if (clampedCosine < cos(radians(glLightSource[index].spotCutoff))) // outside of spotlight cone?
+ {
+ attenuation = 0.0;
+ }
+ else
+ {
+ attenuation = attenuation * pow(clampedCosine, glLightSource[index].spotExponent);
+ }
+ }
+ }
+
+ vec3 diffuseReflection = attenuation * vec3(glLightSource[index].diffuse) * vec3(glFrontMaterial.diffuse)* max(0.0, dot(normalDirection, lightDirection));
+
+ vec3 specularReflection;
+ if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
+ {
+ specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
+ }
+ else // light source on the right side
+ {
+ specularReflection = attenuation * vec3(glLightSource[index].specular) * vec3(glFrontMaterial.specular)
+ * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), glFrontMaterial.shininess);
+ }
+
+ totalDiffuseLighting = totalDiffuseLighting + diffuseReflection;
+ totalSpecularLighting = totalSpecularLighting + specularReflection;
+ }
+ }
+
+ totalDiffuseLighting = totalDiffuseLighting * baseMap.rgb;
+
+ gl_FragColor = vec4(totalDiffuseLighting + totalSpecularLighting, 1.0);
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.vert b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.vert
new file mode 100644
index 0000000..7e492e3
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/sphere_motion/phong_gl2es2_texture.vert
@@ -0,0 +1,35 @@
+// GL2ES2: Java3D built-in attributes, these are calculated and passsed in if declared here
+attribute vec4 glVertex;
+attribute vec3 glNormal;
+attribute vec2 glMultiTexCoord0;
+
+// GL2ES2: Java3D built-in uniforms, these are calculated and passsed in if declared here
+uniform mat4 glModelViewProjectionMatrix;
+uniform mat4 glModelViewMatrix;
+uniform mat3 glNormalMatrix;
+
+
+// Per-pixel normal (output to fragment shader)
+varying vec3 normalDirection;
+varying vec3 viewDirection;
+varying vec4 position;
+
+varying vec2 glTexCoord0;
+
+void main()
+{
+ normalDirection = normalize(vec3(glNormalMatrix * glNormal));
+ vec3 v = vec3(glModelViewMatrix * glVertex);
+ viewDirection = normalize(-v.xyz);
+ position = vec4(v,1);
+ glTexCoord0 = glMultiTexCoord0.st;
+
+ // Transform the vertex
+ gl_Position = glModelViewProjectionMatrix * glVertex;
+}
+
+
+
+
+
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java b/src/main/java/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java
new file mode 100644
index 0000000..4b4d28f
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java
@@ -0,0 +1,631 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.applet.Applet;
+import java.awt.Button;
+import java.awt.Choice;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.ItemSelectable;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.Scrollbar;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Light;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.interpolators.KBKeyFrame;
+import org.jogamp.java3d.utils.behaviors.interpolators.KBRotPosScaleSplinePathInterpolator;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.geometry.Cone;
+import org.jogamp.java3d.utils.geometry.Sphere;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3d;
+import org.jogamp.vecmath.Vector3f;
+
+
+
+/*
+ * 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() {System.setProperty("sun.awt.noerasebackground", "true");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ Frame frame = new MainFrame(new SplineAnim(), 500, 600);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/stencil/StencilOutline.java b/src/main/java/org/jdesktop/j3d/examples/stencil/StencilOutline.java
new file mode 100644
index 0000000..3c7b405
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/stencil/StencilOutline.java
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+package org.jdesktop.j3d.examples.stencil;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.GraphicsConfigTemplate3D;
+import org.jogamp.java3d.Group;
+import org.jogamp.java3d.LineAttributes;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.Node;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderError;
+import org.jogamp.java3d.ShaderErrorListener;
+import org.jogamp.java3d.ShaderProgram;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.loaders.IncorrectFormatException;
+import org.jogamp.java3d.loaders.ParsingErrorException;
+import org.jogamp.java3d.loaders.Scene;
+import org.jogamp.java3d.loaders.objectfile.ObjectFile;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.universe.PlatformGeometry;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+/**
+ * Simple Java 3D example program to display an .obj object with shader programs.
+ * And then add a stencil based outline around it
+ */
+public class StencilOutline extends javax.swing.JFrame
+{
+
+ 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 univ = null;
+ private BranchGroup scene = 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.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);
+ }
+
+ //Uncomment to use the gl2es2 pipeline, also see other commented code
+ // Set vertex and fragment shader program for all Shape3D nodes in scene
+ /* String vertexProgram = null;
+ String fragmentProgram = null;
+ try
+ {
+ vertexProgram = StringIO.readFully(new File(
+ System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/" + shaderName + ".vert"));
+ fragmentProgram = StringIO.readFully(new File(
+ System.getProperty("user.dir") + "/src/classes/org/jdesktop/j3d/examples/gl2es2pipeline/" + 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);*/
+
+ setOutline(s.getSceneGroup());
+
+ 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);
+
+ return objRoot;
+ }
+
+ private Canvas3D createUniverse()
+ {
+ // Critical!!! notice this is not using this call, but explicitly asks for a stencil buffer
+ //GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+ GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
+ template.setStencilSize(16);
+ // Return the GraphicsConfiguration that best fits our needs.
+ GraphicsConfiguration config = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
+ .getBestConfiguration(template);
+
+ // Create a Canvas3D using the preferred configuration
+ Canvas3D canvas3d = new Canvas3D(config);
+
+ // Create simple universe with view branch
+ univ = new SimpleUniverse(canvas3d);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+
+ // Add a ShaderErrorListener
+ univ.addShaderErrorListener(new ShaderErrorListener() {
+ @Override
+ public void errorOccurred(ShaderError error)
+ {
+ error.printVerbose();
+ JOptionPane.showMessageDialog(StencilOutline.this, error.toString(), "ShaderError", JOptionPane.ERROR_MESSAGE);
+ }
+ });
+
+ // add mouse behaviors to the ViewingPlatform
+ ViewingPlatform viewingPlatform = univ.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(canvas3d, OrbitBehavior.REVERSE_ALL);
+ orbit.setSchedulingBounds(bounds);
+ viewingPlatform.setViewPlatformBehavior(orbit);
+ }
+
+ // Ensure at least 5 msec per frame (i.e., < 200Hz)
+ univ.getViewer().getView().setMinimumFrameCycleTime(5);
+
+ return canvas3d;
+ }
+
+ private static 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
+
+ // 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<Node> e = g.getAllChildren();
+ while (e.hasMoreElements())
+ {
+ Node n = e.nextElement();
+ if (n instanceof Group)
+ {
+ setShaderProgram((Group) n, myApp);
+ }
+ else if (n instanceof Shape3D)
+ {
+ Shape3D s = (Shape3D) n;
+ s.setAppearance(myApp);
+ }
+ }
+ }
+
+ private Color3f c = new Color3f(1.0f, 1.0f, 0);
+ private int outlineStencilMask = (int) (c.x * 255) + (int) (c.y * 255) + (int) (c.z * 255);
+
+ // Recursively set an outline onto all Shape3D nodes
+ private void setOutline(Group g)
+ {
+
+ Enumeration<Node> e = g.getAllChildren();
+ while (e.hasMoreElements())
+ {
+ Node n = e.nextElement();
+ if (n instanceof Group)
+ {
+ setOutline((Group) n);
+ }
+ else if (n instanceof Shape3D)
+ {
+ // start by giving the current appearance a rendering attribute
+ Shape3D s = (Shape3D) n;
+ Appearance sapp = s.getAppearance();
+
+ // get and ensure rend atts exist
+ RenderingAttributes ra1 = sapp.getRenderingAttributes();
+ if (ra1 == null)
+ {
+ ra1 = new RenderingAttributes();
+ sapp.setRenderingAttributes(ra1);
+ }
+
+ ra1.setStencilEnable(true);
+ ra1.setStencilWriteMask(outlineStencilMask);
+ ra1.setStencilFunction(RenderingAttributes.ALWAYS, outlineStencilMask, outlineStencilMask);
+ ra1.setStencilOp(RenderingAttributes.STENCIL_REPLACE, //
+ RenderingAttributes.STENCIL_REPLACE, //
+ RenderingAttributes.STENCIL_REPLACE);
+
+ sapp.setRenderingAttributes(ra1);
+
+ // now attach an outline shape
+ Shape3D outliner = new Shape3D();
+
+ ////////////////////////////////
+ //Outliner gear, note empty geom should be ignored
+
+ //Uncomment to use the gl2es2 pipeline, also see other commented code
+ //Appearance app = new SimpleShaderAppearance(c);
+
+ //Comment to use the gl2es2 pipeline, also see other commented code
+ Appearance app = new Appearance();
+
+ // lineAntialiasing MUST be true, to force this to be done during rendering pass (otherwise it's hidden)
+ LineAttributes la = new LineAttributes(4, LineAttributes.PATTERN_SOLID, true);
+ app.setLineAttributes(la);
+ PolygonAttributes pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_BACK, 0.0f, true, 0.0f);
+ app.setPolygonAttributes(pa);
+ ColoringAttributes colorAtt = new ColoringAttributes(c, ColoringAttributes.FASTEST);
+ app.setColoringAttributes(colorAtt);
+
+ RenderingAttributes ra2 = new RenderingAttributes();
+ ra2.setStencilEnable(true);
+ ra2.setStencilWriteMask(outlineStencilMask);
+ ra2.setStencilFunction(RenderingAttributes.NOT_EQUAL, outlineStencilMask, outlineStencilMask);
+ ra2.setStencilOp(RenderingAttributes.STENCIL_KEEP, //
+ RenderingAttributes.STENCIL_KEEP, //
+ RenderingAttributes.STENCIL_KEEP);
+
+ // draw it even when hidden, which we don't want now
+ ra2.setDepthBufferEnable(false);
+ ra2.setDepthTestFunction(RenderingAttributes.ALWAYS);
+
+ app.setRenderingAttributes(ra2);
+
+ outliner.setAppearance(app);
+
+ // use the same geometry ass teh shape we are outlining!
+ outliner.setGeometry(s.getGeometry());
+
+ g.addChild(outliner);
+
+ }
+ }
+ }
+
+ /**
+ * Creates new form ObjLoadGLSL
+ */
+ public StencilOutline(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)
+ {
+ System.err.println(e);
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+ if (filename == null)
+ {
+ filename = Resources.getResource("resources/geometry/galleon.obj");
+ if (filename == null)
+ {
+ System.err.println("resources/geometry/galleon.obj not found");
+ System.exit(1);
+ }
+ }
+
+ // 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("StencilOutline");
+ drawingPanel.setLayout(new java.awt.BorderLayout());
+
+ drawingPanel.setPreferredSize(new java.awt.Dimension(700, 700));
+ getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(final String args[])
+ {
+ System.setProperty("sun.awt.noerasebackground", "true");
+
+ System.setProperty("j3d.stencilClear", "true");
+
+ //Uncomment to use the gl2es2 pipeline, also see other commented code
+ //System.setProperty("j3d.rend", "jogl2es2");
+
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run()
+ {
+ StencilOutline objLoadGLSL = new StencilOutline(args);
+ objLoadGLSL.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/main/java/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form b/src/main/java/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form
new file mode 100644
index 0000000..591580c
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java b/src/main/java/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java
new file mode 100644
index 0000000..e360059
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java
@@ -0,0 +1,259 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.awt.GraphicsConfiguration;
+import java.util.Enumeration;
+
+import javax.swing.JPopupMenu;
+
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.WakeupCriterion;
+import org.jogamp.java3d.WakeupOnBehaviorPost;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+/**
+ * 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[]) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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/main/java/org/jdesktop/j3d/examples/text2d/MoverBehavior.java b/src/main/java/org/jdesktop/j3d/examples/text2d/MoverBehavior.java
new file mode 100644
index 0000000..6005d5b
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/text2d/MoverBehavior.java
@@ -0,0 +1,151 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.AWTEvent;
+import java.awt.event.KeyEvent;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.Bounds;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.WakeupCondition;
+import org.jogamp.java3d.WakeupCriterion;
+import org.jogamp.java3d.WakeupOnAWTEvent;
+import org.jogamp.java3d.WakeupOr;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+// 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/main/java/org/jdesktop/j3d/examples/text2d/Text2DTest.java b/src/main/java/org/jdesktop/j3d/examples/text2d/Text2DTest.java
new file mode 100644
index 0000000..49a0ac2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/text2d/Text2DTest.java
@@ -0,0 +1,205 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.Font;
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.Text2D;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "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
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new Text2DTest(), 256, 256);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/text3d/Text3DLoad.java b/src/main/java/org/jdesktop/j3d/examples/text3d/Text3DLoad.java
new file mode 100644
index 0000000..a61531e
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/text3d/Text3DLoad.java
@@ -0,0 +1,308 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Font;
+import java.awt.GraphicsConfiguration;
+import java.awt.Panel;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Background;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.Font3D;
+import org.jogamp.java3d.FontExtrusion;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.Text3D;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.Vector3f;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new Text3DLoad(args), 700, 700);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/texture/MultiTextureTest.java b/src/main/java/org/jdesktop/j3d/examples/texture/MultiTextureTest.java
new file mode 100644
index 0000000..49f9406
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/texture/MultiTextureTest.java
@@ -0,0 +1,344 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.Choice;
+import java.awt.GraphicsConfiguration;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.image.BufferedImage;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.ImageComponent;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.Texture2D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.TextureUnitState;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.behaviors.vp.OrbitBehavior;
+import org.jogamp.java3d.utils.geometry.Box;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.java3d.utils.universe.ViewingPlatform;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+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, true, true);
+
+ 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"),
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP,
+ this);
+ if (tex == null)
+ return null;
+ stoneTex = tex.getTexture();
+
+ tex = new TextureLoader(skyImage, new String("RGB"),
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP,
+ 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 |
+ Box.GENERATE_TEXTURE_COORDS_Y_UP, 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() {System.setProperty("sun.awt.noerasebackground", "true");
+ if (stoneImage == null) {
+ // the path to the image for an applet
+ stoneImage = Resources.getResource("resources/images/stone.jpg");
+ if (stoneImage == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ System.exit(1);
+ }
+
+ if (skyImage == null) {
+ // the path to the image for an applet
+ skyImage = Resources.getResource("resources/images/bg.jpg");
+ if (skyImage == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ 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
+
+ stoneURL = Resources.getResource("resources/images/stone.jpg");
+ if (stoneURL == null) {
+ System.err.println("resources/images/stone.jpg not found");
+ System.exit(1);
+ }
+
+ skyURL = Resources.getResource("resources/images/bg.jpg");
+ if (skyURL == null) {
+ System.err.println("resources/images/bg.jpg not found");
+ System.exit(1);
+ }
+
+ new MainFrame(new MultiTextureTest(stoneURL, skyURL), 750, 750);
+ }
+}
+
diff --git a/src/main/java/org/jdesktop/j3d/examples/texture/TextureImage.java b/src/main/java/org/jdesktop/j3d/examples/texture/TextureImage.java
new file mode 100644
index 0000000..59f8aa5
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/texture/TextureImage.java
@@ -0,0 +1,196 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.GraphicsConfiguration;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.Box;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+public class TextureImage extends Applet {
+
+ private static final String defaultFileName = "resources/images/stone.jpg";
+ 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,
+ TextureLoader.BY_REFERENCE | TextureLoader.Y_UP,
+ 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 |
+ Box.GENERATE_TEXTURE_COORDS_Y_UP, 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() {System.setProperty("sun.awt.noerasebackground", "true");
+ if (texImage == null) {
+ // the path to the image for an applet
+ texImage = Resources.getResource(defaultFileName);
+ if (texImage == null) {
+ System.err.println(defaultFileName + " not found");
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ java.net.URL url = null;
+ if (args.length > 0) {
+ try {
+ final String name = args[0];
+ if (name.startsWith("http:") ||
+ name.startsWith("https:") ||
+ name.startsWith("ftp:") ||
+ name.startsWith("file:")) {
+ url = new java.net.URL(name);
+ } else {
+ url = new java.net.URL("file:" + name);
+ }
+ } catch (java.net.MalformedURLException ex) {
+ System.out.println(ex.getMessage());
+ System.exit(1);
+ }
+ } else {
+ // the path to the image for an application
+ url = Resources.getResource(defaultFileName);
+ if (url == null) {
+ System.err.println(defaultFileName + " not found");
+ System.exit(1);
+ }
+ }
+ new MainFrame(new TextureImage(url), 256, 256);
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/texture/TextureImageNPOT.java b/src/main/java/org/jdesktop/j3d/examples/texture/TextureImageNPOT.java
new file mode 100644
index 0000000..f55493c
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/texture/TextureImageNPOT.java
@@ -0,0 +1,249 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.GraphicsConfiguration;
+import java.util.Map;
+
+import javax.swing.JOptionPane;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.ScaleInterpolator;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.Box;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+public class TextureImageNPOT extends Applet {
+
+ private static final String defaultFileName = "resources/images/Java3d.jpg";
+ private java.net.URL texImage = null;
+
+ private SimpleUniverse u = null;
+ private boolean allowNonPowerOfTwo = true;
+ private boolean mipmap = true;
+
+ 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 the scaling 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
+ // objTrans group
+ TransformGroup objScale = new TransformGroup();
+ objScale.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ objTrans.addChild(objScale);
+
+ // Create appearance object for textured cube
+ Appearance app = new Appearance();
+ int flags = TextureLoader.BY_REFERENCE | TextureLoader.Y_UP;
+
+ if (allowNonPowerOfTwo) {
+ flags |= TextureLoader.ALLOW_NON_POWER_OF_TWO;
+ }
+ if (mipmap) {
+ flags |= TextureLoader.GENERATE_MIPMAP;
+ }
+ Texture tex = new TextureLoader(texImage, flags, this).getTexture();
+ tex.setMagFilter(Texture.BASE_LEVEL_LINEAR);
+ if (mipmap) {
+ tex.setMinFilter(Texture.MULTI_LEVEL_LINEAR);
+ } else {
+ tex.setMinFilter(Texture.BASE_LEVEL_LINEAR);
+ }
+ 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 |
+ Box.GENERATE_TEXTURE_COORDS_Y_UP, app);
+ objScale.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,
+ 50000, 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);
+
+ // Create a new Behavior object that will perform the desired
+ // operation on the specified transform object and add it into
+ // the scene graph.
+ Alpha scaleAlpha = new Alpha(-1,
+ Alpha.INCREASING_ENABLE | Alpha.DECREASING_ENABLE,
+ 0, 0,
+ 8000, 0, 0,
+ 8000, 0, 0);
+
+ ScaleInterpolator scaler =
+ new ScaleInterpolator(scaleAlpha, objScale, yAxis,
+ 0.01f, 1.5f);
+ scaler.setSchedulingBounds(bounds);
+ objScale.addChild(scaler);
+
+ // Have Java 3D perform optimizations on this scene graph.
+ objRoot.compile();
+
+ return objRoot;
+ }
+
+ public TextureImageNPOT() {
+ }
+
+ public TextureImageNPOT(java.net.URL url) {
+ texImage = url;
+ }
+
+ public void init() {System.setProperty("sun.awt.noerasebackground", "true");
+ if (texImage == null) {
+ // the path to the image for an applet
+ texImage = Resources.getResource(defaultFileName);
+ if (texImage == null) {
+ System.err.println(defaultFileName + " not found");
+ System.exit(1);
+ }
+ }
+ setLayout(new BorderLayout());
+ GraphicsConfiguration config =
+ SimpleUniverse.getPreferredConfiguration();
+
+ Canvas3D c = new Canvas3D(config);
+
+ Map map = c.queryProperties();
+ Boolean value = (Boolean) map.get("textureNonPowerOfTwoAvailable");
+ String errorStr = null;
+ if (value == null) {
+ errorStr = "Canvas3D: textureNonPowerOfTwoAvailable property not found";
+ } else if (!value) {
+ errorStr = "Non-power-of-two textures are not available";
+ }
+
+ if (errorStr != null) {
+ String errorMessage = errorStr + "\n" +
+ "You should expect to see a white cube as a result";
+// System.err.println(errorMessage);
+ JOptionPane.showMessageDialog(this,
+ errorMessage,
+ "Insufficient Capabilities",
+ JOptionPane.ERROR_MESSAGE);
+ }
+
+ 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 TextureImageNPOT to be run as an application
+ // as well as an applet
+ //
+ public static void main(String[] args) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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
+ url = Resources.getResource(defaultFileName);
+ if (url == null) {
+ System.err.println(defaultFileName + " not found");
+ System.exit(1);
+ }
+ }
+ new MainFrame(new TextureImageNPOT(url), 512, 512);
+ }
+
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java b/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java
new file mode 100644
index 0000000..a0fb1e1
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java
@@ -0,0 +1,323 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.image.BufferedImage;
+import java.util.Enumeration;
+
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.ImageComponent;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Texture2D;
+import org.jogamp.java3d.WakeupCriterion;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+import org.jogamp.java3d.utils.image.TextureLoader;
+
+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/main/java/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java b/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java
new file mode 100644
index 0000000..aa689b6
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java
@@ -0,0 +1,181 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+// 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/main/java/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java b/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java
new file mode 100644
index 0000000..063529c
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java
@@ -0,0 +1,228 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.Shape3D;
+import org.jogamp.java3d.TriangleArray;
+import org.jogamp.vecmath.Point2f;
+import org.jogamp.vecmath.Point3f;
+import org.jogamp.vecmath.TexCoord2f;
+import org.jogamp.vecmath.Vector3f;
+
+
+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/main/java/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java b/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java
new file mode 100644
index 0000000..b30b9a2
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java
@@ -0,0 +1,581 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GraphicsConfiguration;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.image.BufferedImage;
+
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.jdesktop.j3d.examples.Resources;
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.AmbientLight;
+import org.jogamp.java3d.Appearance;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.DirectionalLight;
+import org.jogamp.java3d.ImageComponent2D;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Texture;
+import org.jogamp.java3d.Texture2D;
+import org.jogamp.java3d.TextureAttributes;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.image.TextureLoader;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Color3f;
+import org.jogamp.vecmath.Point3d;
+import org.jogamp.vecmath.Vector3f;
+
+
+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 = {
+ "resources/images/animation1.gif",
+ "resources/images/animation2.gif",
+ "resources/images/animation3.gif",
+ "resources/images/animation4.gif",
+ "resources/images/animation5.gif",
+ "resources/images/animation6.gif",
+ "resources/images/animation7.gif",
+ "resources/images/animation8.gif",
+ "resources/images/animation9.gif",
+ "resources/images/animation10.gif"};
+
+ private java.net.URL[] urls = null;
+
+
+ public TextureByReference() {
+ }
+
+ public TextureByReference(java.net.URL[] fnamesP) {
+ urls = fnamesP;
+ }
+
+ public void init() {System.setProperty("sun.awt.noerasebackground", "true");
+ if (urls == null) {
+ urls = new java.net.URL[defaultFiles.length];
+ for (int i = 0; i < defaultFiles.length; i++) {
+ urls[i] = Resources.getResource(defaultFiles[i]);
+ if (urls[i] == null) {
+ System.err.println(defaultFiles[i] + " not found");
+ System.exit(1);
+ }
+ /*
+ 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ 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++) {
+ fnames[i] = Resources.getResource(defaultFiles[i]);
+ if (fnames[i] == null) {
+ System.err.println(TextureByReference.defaultFiles[i] + " not found");
+ System.exit(1);
+ }
+
+/*
+ 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/main/java/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java
new file mode 100644
index 0000000..82f3393
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java
@@ -0,0 +1,214 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.Button;
+import java.awt.GridLayout;
+import java.awt.Panel;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import org.jogamp.java3d.InputDevice;
+import org.jogamp.vecmath.Vector3f;
+
+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/main/java/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java
new file mode 100644
index 0000000..eeff16d
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java
@@ -0,0 +1,69 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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 org.jogamp.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/main/java/org/jdesktop/j3d/examples/virtual_input_device/README.txt b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/README.txt
new file mode 100644
index 0000000..f769dac
--- /dev/null
+++ b/src/main/java/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/main/java/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java
new file mode 100644
index 0000000..ea5b8c9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java
@@ -0,0 +1,71 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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;
+
+// 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/main/java/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java
new file mode 100644
index 0000000..0cb0ca6
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java
@@ -0,0 +1,77 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.util.Enumeration;
+
+import org.jogamp.java3d.Behavior;
+import org.jogamp.java3d.Sensor;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.WakeupOnElapsedFrames;
+
+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/main/java/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java
new file mode 100644
index 0000000..380dae9
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java
@@ -0,0 +1,265 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.Frame;
+import java.awt.Panel;
+
+import org.jogamp.java3d.InputDevice;
+import org.jogamp.java3d.Sensor;
+import org.jogamp.java3d.SensorRead;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.vecmath.Vector3f;
+
+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/main/java/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java
new file mode 100644
index 0000000..281bc63
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java
@@ -0,0 +1,144 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.BorderLayout;
+import java.awt.GraphicsConfiguration;
+
+import org.jogamp.java3d.Alpha;
+import org.jogamp.java3d.BoundingSphere;
+import org.jogamp.java3d.BranchGroup;
+import org.jogamp.java3d.Canvas3D;
+import org.jogamp.java3d.InputDevice;
+import org.jogamp.java3d.RotationInterpolator;
+import org.jogamp.java3d.Transform3D;
+import org.jogamp.java3d.TransformGroup;
+import org.jogamp.java3d.utils.applet.MainFrame;
+import org.jogamp.java3d.utils.geometry.ColorCube;
+import org.jogamp.java3d.utils.universe.SimpleUniverse;
+import org.jogamp.vecmath.Point3d;
+
+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() {System.setProperty("sun.awt.noerasebackground", "true");
+ // 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) {System.setProperty("sun.awt.noerasebackground", "true");
+ new MainFrame(new VirtualInputDeviceTest(), 350, 350);
+ }
+}
diff --git a/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java
new file mode 100644
index 0000000..60181af
--- /dev/null
+++ b/src/main/java/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java
@@ -0,0 +1,410 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2007 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.Canvas;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.geom.AffineTransform;
+
+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;
+ }
+}