From 1f9cc0db52f9a8e5ccb839930bff07145b2cf745 Mon Sep 17 00:00:00 2001 From: nobody Date: Wed, 8 Feb 2006 22:48:24 +0000 Subject: This commit was manufactured by cvs2svn to create branch 'dev-1_5'. --- .../AlternateAppearanceBoundsTest.java | 310 +++ .../AlternateAppearanceScopeTest.java | 356 +++ .../examples/alternate_appearance/SphereGroup.java | 125 ++ .../j3d/examples/appearance/AppearanceMixed.java | 508 +++++ .../j3d/examples/appearance/AppearanceTest.java | 382 ++++ .../j3d/examples/appearance/Tetrahedron.java | 109 + .../jdesktop/j3d/examples/applet3d/Applet3D.html | 15 + .../jdesktop/j3d/examples/applet3d/Applet3D.java | 129 ++ .../j3d/examples/applet3d/Applet3D_plugin.html | 39 + .../examples/background/BackgroundGeometry.java | 238 ++ .../jdesktop/j3d/examples/cg_shader/ObjLoadCg.java | 345 +++ .../jdesktop/j3d/examples/cg_shader/SphereCg.java | 348 +++ .../jdesktop/j3d/examples/cg_shader/simple_fp.cg | 68 + .../jdesktop/j3d/examples/cg_shader/simple_vp.cg | 167 ++ .../org/jdesktop/j3d/examples/collision/Box.java | 100 + .../j3d/examples/collision/CollisionDetector.java | 92 + .../j3d/examples/collision/TickTockCollision.java | 219 ++ .../configured_universe/ConfigObjLoad.java | 311 +++ .../j3d/examples/configured_universe/README.txt | 142 ++ .../j3d/examples/configured_universe/j3d1x1 | 98 + .../examples/configured_universe/j3d1x1-behavior | 149 ++ .../j3d/examples/configured_universe/j3d1x1-stereo | 113 + .../j3d/examples/configured_universe/j3d1x1-vr | 212 ++ .../j3d/examples/configured_universe/j3d1x1-window | 89 + .../j3d/examples/configured_universe/j3d1x2-flat | 134 ++ .../j3d/examples/configured_universe/j3d1x2-rot30 | 99 + .../j3d/examples/configured_universe/j3d1x3-cave | 171 ++ .../examples/configured_universe/j3d1x3-cave-vr | 222 ++ .../j3d/examples/configured_universe/j3d1x3-rot45 | 110 + .../j3d/examples/configured_universe/j3d2x2-flat | 135 ++ .../j3d/examples/depth_func/DepthFuncTest.form | 217 ++ .../j3d/examples/depth_func/DepthFuncTest.java | 359 +++ .../j3d/examples/depth_func/RenderFrame.form | 25 + .../j3d/examples/depth_func/RenderFrame.java | 292 +++ .../examples/distort_glyph/DistortBehavior.java | 194 ++ .../examples/distort_glyph/DistortGlyphTest.java | 210 ++ .../j3d/examples/four_by_four/BigCube.java | 140 ++ .../jdesktop/j3d/examples/four_by_four/Board.java | 2312 ++++++++++++++++++++ .../j3d/examples/four_by_four/Canvas2D.java | 94 + .../jdesktop/j3d/examples/four_by_four/Cube.java | 133 ++ .../j3d/examples/four_by_four/Cylinder.java | 116 + .../j3d/examples/four_by_four/FourByFour.html | 15 + .../j3d/examples/four_by_four/FourByFour.java | 886 ++++++++ .../examples/four_by_four/FourByFour_plugin.html | 39 + .../org/jdesktop/j3d/examples/four_by_four/ID.java | 61 + .../examples/four_by_four/PickDragBehavior.java | 218 ++ .../jdesktop/j3d/examples/four_by_four/Poles.java | 82 + .../j3d/examples/four_by_four/Positions.java | 313 +++ .../jdesktop/j3d/examples/four_by_four/README.txt | 8 + .../j3d/examples/four_by_four/instructions.txt | 98 + .../jdesktop/j3d/examples/four_by_four/scores.txt | 20 + .../j3d/examples/fps_counter/FPSCounter.java | 281 +++ .../j3d/examples/fps_counter/FPSCounterDemo.java | 221 ++ .../org/jdesktop/j3d/examples/gears/Gear.java | 399 ++++ .../org/jdesktop/j3d/examples/gears/GearBox.java | 356 +++ .../org/jdesktop/j3d/examples/gears/GearTest.java | 208 ++ .../org/jdesktop/j3d/examples/gears/Shaft.java | 198 ++ .../org/jdesktop/j3d/examples/gears/SpurGear.java | 558 +++++ .../j3d/examples/gears/SpurGearThinBody.java | 187 ++ .../GeometryByReferenceNIOBuffer.java | 519 +++++ .../geometry_by_ref/GeometryByReferenceTest.java | 554 +++++ .../ImageComponentByReferenceTest.java | 330 +++ .../geometry_by_ref/InterleavedNIOBuffer.java | 536 +++++ .../examples/geometry_by_ref/InterleavedTest.java | 506 +++++ .../j3d/examples/geometry_by_ref/TiledImage.java | 358 +++ .../geometry_compression/ObjectFileCompressor.java | 249 +++ .../j3d/examples/geometry_compression/README.txt | 23 + .../j3d/examples/geometry_compression/cgview.java | 214 ++ .../j3d/examples/geometry_compression/obj2cg.java | 73 + .../j3d/examples/glsl_shader/ObjLoadGLSL.java | 342 +++ .../j3d/examples/glsl_shader/PhongShadingGLSL.form | 138 ++ .../j3d/examples/glsl_shader/PhongShadingGLSL.java | 450 ++++ .../j3d/examples/glsl_shader/ShaderTestGLSL.form | 266 +++ .../j3d/examples/glsl_shader/ShaderTestGLSL.java | 668 ++++++ .../j3d/examples/glsl_shader/SphereGLSL.java | 341 +++ .../jdesktop/j3d/examples/glsl_shader/aabrick.frag | 55 + .../jdesktop/j3d/examples/glsl_shader/aabrick.vert | 42 + .../jdesktop/j3d/examples/glsl_shader/dimple.frag | 61 + .../jdesktop/j3d/examples/glsl_shader/dimple.vert | 42 + .../jdesktop/j3d/examples/glsl_shader/gouraud.frag | 50 + .../jdesktop/j3d/examples/glsl_shader/gouraud.vert | 100 + .../jdesktop/j3d/examples/glsl_shader/phong.frag | 98 + .../jdesktop/j3d/examples/glsl_shader/phong.vert | 56 + .../j3d/examples/glsl_shader/polkadot3d.frag | 48 + .../j3d/examples/glsl_shader/polkadot3d.vert | 58 + .../jdesktop/j3d/examples/glsl_shader/simple.frag | 62 + .../jdesktop/j3d/examples/glsl_shader/simple.vert | 129 ++ .../jdesktop/j3d/examples/glsl_shader/toon.frag | 34 + .../jdesktop/j3d/examples/glsl_shader/toon.vert | 19 + .../jdesktop/j3d/examples/glsl_shader/wood.frag | 66 + .../jdesktop/j3d/examples/glsl_shader/wood.vert | 25 + .../j3d/examples/hello_universe/HelloUniverse.form | 36 + .../j3d/examples/hello_universe/HelloUniverse.java | 169 ++ .../org/jdesktop/j3d/examples/lightwave/README.txt | 321 +++ .../jdesktop/j3d/examples/lightwave/Viewer.java | 209 ++ src/classes/org/jdesktop/j3d/examples/lod/LOD.java | 181 ++ .../j3d/examples/model_clip/ModelClipTest.java | 176 ++ .../j3d/examples/model_clip/ModelClipTest2.java | 197 ++ .../jdesktop/j3d/examples/morphing/ColorCube.java | 123 ++ .../j3d/examples/morphing/ColorPyramidDown.java | 123 ++ .../j3d/examples/morphing/ColorPyramidUp.java | 125 ++ .../jdesktop/j3d/examples/morphing/Morphing.java | 262 +++ .../j3d/examples/morphing/MorphingBehavior.java | 99 + .../j3d/examples/morphing/Pyramid2Cube.java | 194 ++ .../org/jdesktop/j3d/examples/objload/ObjLoad.java | 287 +++ .../offscreen_canvas3d/OffScreenCanvas3D.java | 105 + .../examples/offscreen_canvas3d/OffScreenTest.form | 36 + .../examples/offscreen_canvas3d/OffScreenTest.java | 219 ++ .../offscreen_canvas3d/OnScreenCanvas3D.java | 85 + .../offscreen_canvas3d/PrintFromButton.form | 82 + .../offscreen_canvas3d/PrintFromButton.java | 262 +++ .../examples/oriented_shape3d/MouseRotateY.java | 196 ++ .../examples/oriented_shape3d/OrientedPtTest.java | 297 +++ .../examples/oriented_shape3d/OrientedTest.java | 305 +++ .../j3d/examples/package_info/PackageInfo.java | 95 + .../j3d/examples/package_info/QueryProperties.java | 150 ++ .../org/jdesktop/j3d/examples/picking/BoltCG.java | 359 +++ .../jdesktop/j3d/examples/picking/ColorCube.java | 123 ++ .../j3d/examples/picking/ColorPyramidDown.java | 123 ++ .../j3d/examples/picking/ColorPyramidUp.java | 125 ++ .../org/jdesktop/j3d/examples/picking/Cube.java | 110 + .../org/jdesktop/j3d/examples/picking/CubeIQA.java | 138 ++ .../org/jdesktop/j3d/examples/picking/CubeQA.java | 135 ++ .../org/jdesktop/j3d/examples/picking/GullCG.java | 578 +++++ .../j3d/examples/picking/IcosahedronITSA.java | 180 ++ .../j3d/examples/picking/IcosahedronTSA.java | 177 ++ .../examples/picking/IntersectInfoBehavior.java | 253 +++ .../j3d/examples/picking/IntersectTest.java | 235 ++ .../j3d/examples/picking/MorphingBehavior.java | 99 + .../j3d/examples/picking/OctahedronITFA.java | 115 + .../j3d/examples/picking/OctahedronTFA.java | 114 + .../examples/picking/PickHighlightBehavior.java | 102 + .../jdesktop/j3d/examples/picking/PickTest.java | 416 ++++ .../j3d/examples/picking/PickText3DBounds.java | 234 ++ .../j3d/examples/picking/PickText3DGeometry.java | 252 +++ .../j3d/examples/picking/RandomColorCube.java | 131 ++ .../examples/picking/RandomColorTetrahedron.java | 101 + .../jdesktop/j3d/examples/picking/Tetrahedron.java | 112 + .../j3d/examples/picking/TetrahedronILA.java | 106 + .../j3d/examples/picking/TetrahedronILSA.java | 97 + .../j3d/examples/picking/TetrahedronIPA.java | 81 + .../j3d/examples/picking/TetrahedronITA.java | 104 + .../j3d/examples/picking/TetrahedronLA.java | 104 + .../j3d/examples/picking/TetrahedronLSA.java | 94 + .../j3d/examples/picking/TetrahedronPA.java | 71 + .../j3d/examples/picking/TetrahedronTA.java | 102 + .../j3d/examples/picking/TickTockPicking.java | 448 ++++ .../examples/platform_geometry/SimpleGeometry.java | 200 ++ .../examples/print_canvas3d/ImageDisplayer.java | 130 ++ .../j3d/examples/print_canvas3d/ImagePrinter.java | 112 + .../examples/print_canvas3d/OffScreenCanvas3D.java | 82 + .../j3d/examples/print_canvas3d/PrintCanvas3D.form | 74 + .../j3d/examples/print_canvas3d/PrintCanvas3D.java | 374 ++++ .../j3d/examples/pure_immediate/PureImmediate.java | 151 ++ .../pure_immediate/PureImmediateStereo.java | 266 +++ .../j3d/examples/read_raster/ReadRaster.java | 224 ++ .../j3d/examples/sound/AudioBehaviorMoveOne.java | 106 + .../j3d/examples/sound/AudioReverberate.java | 171 ++ .../j3d/examples/sound/MoveAppBoundingLeaf.java | 389 ++++ .../j3d/examples/sound/ReverberateSound.java | 222 ++ .../jdesktop/j3d/examples/sound/SimpleSounds.java | 294 +++ .../j3d/examples/sound/SimpleSoundsBehavior.java | 179 ++ .../j3d/examples/sphere_motion/SphereMotion.java | 303 +++ .../j3d/examples/spline_anim/SplineAnim.java | 603 +++++ .../swing_interaction/SwingInteraction.form | 82 + .../swing_interaction/SwingInteraction.java | 252 +++ .../j3d/examples/text2d/MoverBehavior.java | 141 ++ .../jdesktop/j3d/examples/text2d/Text2DTest.java | 193 ++ .../jdesktop/j3d/examples/text3d/Text3DLoad.java | 286 +++ .../j3d/examples/texture/MultiTextureTest.java | 320 +++ .../j3d/examples/texture/TextureImage.java | 180 ++ .../texture_by_ref/AnimateTexturesBehavior.java | 317 +++ .../j3d/examples/texture_by_ref/ImageOps.java | 175 ++ .../j3d/examples/texture_by_ref/Tetrahedron.java | 223 ++ .../texture_by_ref/TextureByReference.java | 532 +++++ .../ButtonPositionControls.java | 209 ++ .../virtual_input_device/PositionControls.java | 70 + .../j3d/examples/virtual_input_device/README.txt | 195 ++ .../virtual_input_device/RotationControls.java | 73 + .../virtual_input_device/SensorBehavior.java | 72 + .../virtual_input_device/VirtualInputDevice.java | 260 +++ .../VirtualInputDeviceTest.java | 136 ++ .../virtual_input_device/WheelControls.java | 401 ++++ 183 files changed, 38037 insertions(+) create mode 100644 src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java create mode 100644 src/classes/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java create mode 100644 src/classes/org/jdesktop/j3d/examples/appearance/AppearanceTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/appearance/Tetrahedron.java create mode 100644 src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.html create mode 100644 src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.java create mode 100644 src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D_plugin.html create mode 100644 src/classes/org/jdesktop/j3d/examples/background/BackgroundGeometry.java create mode 100644 src/classes/org/jdesktop/j3d/examples/cg_shader/ObjLoadCg.java create mode 100644 src/classes/org/jdesktop/j3d/examples/cg_shader/SphereCg.java create mode 100644 src/classes/org/jdesktop/j3d/examples/cg_shader/simple_fp.cg create mode 100644 src/classes/org/jdesktop/j3d/examples/cg_shader/simple_vp.cg create mode 100644 src/classes/org/jdesktop/j3d/examples/collision/Box.java create mode 100644 src/classes/org/jdesktop/j3d/examples/collision/CollisionDetector.java create mode 100644 src/classes/org/jdesktop/j3d/examples/collision/TickTockCollision.java create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/README.txt create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1 create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30 create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45 create mode 100644 src/classes/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat create mode 100644 src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form create mode 100644 src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.form create mode 100644 src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.java create mode 100644 src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/BigCube.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/Board.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/Canvas2D.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/Cube.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/Cylinder.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.html create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour_plugin.html create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/ID.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/Poles.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/Positions.java create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/README.txt create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/instructions.txt create mode 100644 src/classes/org/jdesktop/j3d/examples/four_by_four/scores.txt create mode 100644 src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounter.java create mode 100644 src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java create mode 100644 src/classes/org/jdesktop/j3d/examples/gears/Gear.java create mode 100644 src/classes/org/jdesktop/j3d/examples/gears/GearBox.java create mode 100644 src/classes/org/jdesktop/j3d/examples/gears/GearTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/gears/Shaft.java create mode 100644 src/classes/org/jdesktop/j3d/examples/gears/SpurGear.java create mode 100644 src/classes/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_compression/README.txt create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_compression/cgview.java create mode 100644 src/classes/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.frag create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.vert create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.frag create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.vert create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.frag create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.vert create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.frag create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.vert create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.frag create mode 100644 src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.vert create mode 100644 src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form create mode 100644 src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java create mode 100644 src/classes/org/jdesktop/j3d/examples/lightwave/README.txt create mode 100644 src/classes/org/jdesktop/j3d/examples/lightwave/Viewer.java create mode 100644 src/classes/org/jdesktop/j3d/examples/lod/LOD.java create mode 100644 src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java create mode 100644 src/classes/org/jdesktop/j3d/examples/morphing/ColorCube.java create mode 100644 src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java create mode 100644 src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java create mode 100644 src/classes/org/jdesktop/j3d/examples/morphing/Morphing.java create mode 100644 src/classes/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java create mode 100644 src/classes/org/jdesktop/j3d/examples/objload/ObjLoad.java create mode 100644 src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java create mode 100644 src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form create mode 100644 src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java create mode 100644 src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form create mode 100644 src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java create mode 100644 src/classes/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java create mode 100644 src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedPtTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/oriented_shape3d/OrientedTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/package_info/PackageInfo.java create mode 100644 src/classes/org/jdesktop/j3d/examples/package_info/QueryProperties.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/BoltCG.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/ColorCube.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidDown.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/ColorPyramidUp.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/Cube.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/CubeIQA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/CubeQA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/GullCG.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/IcosahedronITSA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/IcosahedronTSA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/IntersectInfoBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/IntersectTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/MorphingBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/OctahedronITFA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/OctahedronTFA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/PickHighlightBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/PickTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/PickText3DBounds.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/PickText3DGeometry.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/RandomColorCube.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/RandomColorTetrahedron.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/Tetrahedron.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TetrahedronILSA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TetrahedronIPA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TetrahedronITA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TetrahedronLSA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TetrahedronPA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TetrahedronTA.java create mode 100644 src/classes/org/jdesktop/j3d/examples/picking/TickTockPicking.java create mode 100644 src/classes/org/jdesktop/j3d/examples/platform_geometry/SimpleGeometry.java create mode 100644 src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImageDisplayer.java create mode 100644 src/classes/org/jdesktop/j3d/examples/print_canvas3d/ImagePrinter.java create mode 100644 src/classes/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java create mode 100644 src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form create mode 100644 src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java create mode 100644 src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java create mode 100644 src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java create mode 100644 src/classes/org/jdesktop/j3d/examples/read_raster/ReadRaster.java create mode 100644 src/classes/org/jdesktop/j3d/examples/sound/AudioBehaviorMoveOne.java create mode 100644 src/classes/org/jdesktop/j3d/examples/sound/AudioReverberate.java create mode 100644 src/classes/org/jdesktop/j3d/examples/sound/MoveAppBoundingLeaf.java create mode 100644 src/classes/org/jdesktop/j3d/examples/sound/ReverberateSound.java create mode 100644 src/classes/org/jdesktop/j3d/examples/sound/SimpleSounds.java create mode 100644 src/classes/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java create mode 100644 src/classes/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java create mode 100644 src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form create mode 100644 src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java create mode 100644 src/classes/org/jdesktop/j3d/examples/text2d/MoverBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/text2d/Text2DTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/text3d/Text3DLoad.java create mode 100644 src/classes/org/jdesktop/j3d/examples/texture/MultiTextureTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/texture/TextureImage.java create mode 100644 src/classes/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java create mode 100644 src/classes/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java create mode 100644 src/classes/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java create mode 100644 src/classes/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java create mode 100644 src/classes/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java create mode 100644 src/classes/org/jdesktop/j3d/examples/virtual_input_device/README.txt create mode 100644 src/classes/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java create mode 100644 src/classes/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java create mode 100644 src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java create mode 100644 src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDeviceTest.java create mode 100644 src/classes/org/jdesktop/j3d/examples/virtual_input_device/WheelControls.java (limited to 'src/classes') diff --git a/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java new file mode 100644 index 0000000..6f7e499 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceBoundsTest.java @@ -0,0 +1,310 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.alternate_appearance; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.*; +import com.sun.j3d.utils.behaviors.mouse.*; + +public class AlternateAppearanceBoundsTest extends JApplet +implements ActionListener { + + + Material mat1, altMat; + Appearance app, otherApp; + JComboBox altAppMaterialColor; + JComboBox appMaterialColor; + JCheckBox useBoundingLeaf; + JCheckBox override; + JComboBox boundsType; + private Group content1 = null; + AlternateAppearance altApp; + Shape3D[] shapes1; + boolean boundingLeafOn = false; + // Globally used colors + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f red = new Color3f(1.0f, 0.0f, 0.0f); + Color3f green = new Color3f(0.0f, 1.0f, 0.0f); + Color3f blue = new Color3f(0.0f, 0.0f, 1.0f); + Color3f[] colors = {white, red, green, blue}; + + private Bounds worldBounds = new BoundingSphere( + new Point3d( 0.0, 0.0, 0.0 ), // Center + 1000.0 ); // Extent + private Bounds smallBounds = new BoundingSphere( + new Point3d( 0.0, 0.0, 0.0 ), // Center + 0.25 ); // Extent + private Bounds tinyBounds = new BoundingSphere( + new Point3d( 0.0, 0.0, 0.0 ), // Center + 0.05 ); // Extent + private BoundingLeaf leafBounds = null; + private int currentBounds = 2; + + private Bounds[] allBounds = {tinyBounds, smallBounds, worldBounds}; + + DirectionalLight light1 = null; + + // Get the current bounding leaf position + private int currentPosition = 0; + // Point3f pos = (Point3f)positions[currentPosition].value; + + private SimpleUniverse u = null; + + public AlternateAppearanceBoundsTest() { + } + + public void init() { + Container contentPane = getContentPane(); + + Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + contentPane.add("Center", c); + + BranchGroup scene = createSceneGraph(); + // SimpleUniverse is a Convenience Utility class + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + u.addBranchGraph(scene); + + + // Create GUI + JPanel p = new JPanel(); + BoxLayout boxlayout = new BoxLayout(p, + BoxLayout.Y_AXIS); + p.add(createBoundsPanel()); + p.add(createMaterialPanel()); + p.setLayout(boxlayout); + + contentPane.add("South", p); + } + + public void destroy() { + u.cleanup(); + } + + BranchGroup createSceneGraph() { + BranchGroup objRoot = new BranchGroup(); + + // Create an alternate appearance + otherApp = new Appearance(); + altMat = new Material(); + altMat.setCapability(Material.ALLOW_COMPONENT_WRITE); + altMat.setDiffuseColor( new Color3f( 0.0f, 1.0f, 0.0f ) ); + otherApp.setMaterial(altMat); + + altApp = new AlternateAppearance(); + altApp.setAppearance(otherApp); + altApp.setCapability(AlternateAppearance.ALLOW_BOUNDS_WRITE); + altApp.setCapability(AlternateAppearance.ALLOW_INFLUENCING_BOUNDS_WRITE); + altApp.setInfluencingBounds( worldBounds ); + objRoot.addChild(altApp); + + // Build foreground geometry + Appearance app1 = new Appearance(); + mat1 = new Material(); + mat1.setCapability(Material.ALLOW_COMPONENT_WRITE); + mat1.setDiffuseColor( new Color3f( 1.0f, 0.0f, 0.0f ) ); + app1.setMaterial(mat1); + content1 = new SphereGroup( + 0.05f, // radius of spheres + 0.15f, // x spacing + 0.15f, // y spacing + 5, // number of spheres in X + 5, // number of spheres in Y + app1, // appearance + true); // alt app override = true + objRoot.addChild( content1 ); + shapes1 = ((SphereGroup)content1).getShapes(); + + + + // Add lights + light1 = new DirectionalLight( ); + light1.setEnable( true ); + light1.setColor( new Color3f(0.2f, 0.2f, 0.2f) ); + light1.setDirection( new Vector3f( 1.0f, 0.0f, -1.0f ) ); + light1.setInfluencingBounds( worldBounds ); + light1.setCapability( + DirectionalLight.ALLOW_INFLUENCING_BOUNDS_WRITE ); + light1.setCapability( + DirectionalLight.ALLOW_BOUNDS_WRITE ); + objRoot.addChild( light1 ); + + // Add an ambient light to dimly illuminate the rest of + // the shapes in the scene to help illustrate that the + // directional lights are being scoped... otherwise it looks + // like we're just removing shapes from the scene + AmbientLight ambient = new AmbientLight( ); + ambient.setEnable( true ); + ambient.setColor( new Color3f(1.0f, 1.0f, 1.0f) ); + ambient.setInfluencingBounds( worldBounds ); + objRoot.addChild( ambient ); + + + // Define a bounding leaf + leafBounds = new BoundingLeaf( allBounds[currentBounds] ); + leafBounds.setCapability( BoundingLeaf.ALLOW_REGION_WRITE ); + objRoot.addChild( leafBounds ); + if (boundingLeafOn) { + altApp.setInfluencingBoundingLeaf(leafBounds); + } + else { + altApp.setInfluencingBounds(allBounds[currentBounds]); + } + + + + return objRoot; + } + JPanel createBoundsPanel() { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Scopes")); + + + String boundsValues[] = { "Tiny Bounds", "Small Bounds", "Big Bounds"}; + + boundsType = new JComboBox(boundsValues); + boundsType.addActionListener(this); + boundsType.setSelectedIndex(2); + panel.add(new JLabel("Bounds")); + panel.add(boundsType); + + useBoundingLeaf = new JCheckBox("Enable BoundingLeaf", + boundingLeafOn); + useBoundingLeaf.addActionListener(this); + panel.add(useBoundingLeaf); + + override = new JCheckBox("Enable App Override", + false); + override.addActionListener(this); + panel.add(override); + + return panel; + + } + + JPanel createMaterialPanel() { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Appearance Attributes")); + + String colorVals[] = { "WHITE", "RED", "GREEN", "BLUE"}; + + altAppMaterialColor = new JComboBox(colorVals); + altAppMaterialColor.addActionListener(this); + altAppMaterialColor.setSelectedIndex(2); + panel.add(new JLabel("Alternate Appearance MaterialColor")); + panel.add(altAppMaterialColor); + + + + appMaterialColor = new JComboBox(colorVals); + appMaterialColor.addActionListener(this); + appMaterialColor.setSelectedIndex(1); + panel.add(new JLabel("Normal Appearance MaterialColor")); + panel.add(appMaterialColor); + + return panel; + + + } + + public void actionPerformed(ActionEvent e) { + int i; + + Object target = e.getSource(); + if (target == altAppMaterialColor) { + altMat.setDiffuseColor(colors[altAppMaterialColor.getSelectedIndex()]); + } + else if (target == useBoundingLeaf) { + boundingLeafOn = useBoundingLeaf.isSelected(); + if (boundingLeafOn) { + leafBounds.setRegion(allBounds[currentBounds]); + altApp.setInfluencingBoundingLeaf( leafBounds ); + } + else { + altApp.setInfluencingBoundingLeaf( null ); + altApp.setInfluencingBounds(allBounds[currentBounds]); + } + + } + else if (target == boundsType) { + currentBounds = boundsType.getSelectedIndex(); + if (boundingLeafOn) { + leafBounds.setRegion(allBounds[currentBounds]); + altApp.setInfluencingBoundingLeaf( leafBounds ); + } + else { + altApp.setInfluencingBoundingLeaf( null ); + altApp.setInfluencingBounds(allBounds[currentBounds]); + } + + } + else if (target == override) { + for (i = 0; i < shapes1.length; i++) + shapes1[i].setAppearanceOverrideEnable(override.isSelected()); + } + else if (target == appMaterialColor) { + mat1.setDiffuseColor(colors[appMaterialColor.getSelectedIndex()]); + } + + } + + + public static void main(String[] args) { + Frame frame = new MainFrame(new AlternateAppearanceBoundsTest(), 800, 800); + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java new file mode 100644 index 0000000..a2bf786 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/AlternateAppearanceScopeTest.java @@ -0,0 +1,356 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.alternate_appearance; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.*; +import com.sun.j3d.utils.behaviors.vp.*; + +public class AlternateAppearanceScopeTest extends JApplet +implements ActionListener { + + + Material mat1, altMat; + Appearance app, otherApp; + JComboBox altAppMaterialColor; + JComboBox appMaterialColor; + JComboBox altAppScoping; + JComboBox override; + private Group content1 = null; + private Group content2 = null; + BoundingSphere worldBounds; + AlternateAppearance altApp; + Shape3D[] shapes1, shapes2; + boolean shape1Enabled = false, shape2Enabled = false; + // Globally used colors + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f red = new Color3f(1.0f, 0.0f, 0.0f); + Color3f green = new Color3f(0.0f, 1.0f, 0.0f); + Color3f blue = new Color3f(0.0f, 0.0f, 1.0f); + Color3f[] colors = {white, red, green, blue}; + + private SimpleUniverse u; + + public AlternateAppearanceScopeTest() { + } + + public void init() { + Container contentPane = getContentPane(); + + Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + contentPane.add("Center", c); + + BranchGroup scene = createSceneGraph(); + // SimpleUniverse is a Convenience Utility class + u = new SimpleUniverse(c); + + // add mouse behaviors to the viewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + OrbitBehavior orbit = new OrbitBehavior(c, + OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), + 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + u.addBranchGraph(scene); + + + // Create GUI + JPanel p = new JPanel(); + BoxLayout boxlayout = new BoxLayout(p, + BoxLayout.Y_AXIS); + p.add(createScopingPanel()); + p.add(createMaterialPanel()); + p.setLayout(boxlayout); + + contentPane.add("South", p); + } + + public void destroy() { + u.cleanup(); + } + + BranchGroup createSceneGraph() { + BranchGroup objRoot = new BranchGroup(); + + // Create influencing bounds + worldBounds = new BoundingSphere( + new Point3d( 0.0, 0.0, 0.0 ), // Center + 1000.0 ); // Extent + + Transform3D t = new Transform3D(); + // move the object upwards + t.set(new Vector3f(0.0f, 0.1f, 0.0f)); + // Shrink the object + t.setScale(0.8); + + TransformGroup trans = new TransformGroup(t); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + + + otherApp = new Appearance(); + altMat = new Material(); + altMat.setCapability(Material.ALLOW_COMPONENT_WRITE); + altMat.setDiffuseColor( new Color3f( 0.0f, 1.0f, 0.0f ) ); + otherApp.setMaterial(altMat); + + altApp = new AlternateAppearance(); + altApp.setAppearance(otherApp); + altApp.setCapability(AlternateAppearance.ALLOW_SCOPE_WRITE); + altApp.setCapability(AlternateAppearance.ALLOW_SCOPE_READ); + altApp.setInfluencingBounds( worldBounds ); + objRoot.addChild(altApp); + + // Build foreground geometry into two groups. We'll + // create three directional lights below, one each with + // scope to cover the first geometry group only, the + // second geometry group only, or both geometry groups. + Appearance app1 = new Appearance(); + mat1 = new Material(); + mat1.setCapability(Material.ALLOW_COMPONENT_WRITE); + mat1.setDiffuseColor( new Color3f( 1.0f, 0.0f, 0.0f ) ); + app1.setMaterial(mat1); + content1 = new SphereGroup( + 0.05f, // radius of spheres + 0.4f, // x spacing + 0.2f, // y spacing + 3, // number of spheres in X + 5, // number of spheres in Y + app1, // appearance + true); // alt app override = true + trans.addChild( content1 ); + shapes1 = ((SphereGroup)content1).getShapes(); + + content2 = new SphereGroup( + 0.05f, // radius of spheres + .4f, // x spacing + 0.2f, // y spacing + 2, // number of spheres in X + 5, // number of spheres in Y + app1, // appearance + true); // alt app override = true + trans.addChild( content2 ); + shapes2 = ((SphereGroup)content2).getShapes(); + + + // Add lights + DirectionalLight light1 = null; + light1 = new DirectionalLight( ); + light1.setEnable( true ); + light1.setColor( new Color3f(0.2f, 0.2f, 0.2f) ); + light1.setDirection( new Vector3f( 1.0f, 0.0f, -1.0f ) ); + light1.setInfluencingBounds( worldBounds ); + objRoot.addChild( light1 ); + + DirectionalLight light2 = new DirectionalLight(); + light2.setEnable(true); + light2.setColor(new Color3f(0.2f, 0.2f, 0.2f)); + light2.setDirection(new Vector3f(-1.0f, 0.0f, 1.0f)); + light2.setInfluencingBounds(worldBounds); + objRoot.addChild(light2); + + // Add an ambient light to dimly illuminate the rest of + // the shapes in the scene to help illustrate that the + // directional lights are being scoped... otherwise it looks + // like we're just removing shapes from the scene + AmbientLight ambient = new AmbientLight( ); + ambient.setEnable( true ); + ambient.setColor( new Color3f(1.0f, 1.0f, 1.0f) ); + ambient.setInfluencingBounds( worldBounds ); + objRoot.addChild( ambient ); + + + objRoot.addChild(trans); + + return objRoot; + } + JPanel createScopingPanel() { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Scopes")); + + String values[] = {"Scoped Set1", "Scoped Set2", "Universal Scope"}; + altAppScoping = new JComboBox(values); + altAppScoping.addActionListener(this); + altAppScoping.setSelectedIndex(2); + panel.add(new JLabel("Scoping")); + panel.add(altAppScoping); + + + String enables[] = { "Enabled Set1", "Enabled Set2", "Enabled set1&2", "Disabled set1&2"}; + + override = new JComboBox(enables); + override.addActionListener(this); + override.setSelectedIndex(3); + panel.add(new JLabel("Alternate Appearance Override")); + panel.add(override); + + return panel; + + } + + JPanel createMaterialPanel() { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Appearance Attributes")); + + String colorVals[] = { "WHITE", "RED", "GREEN", "BLUE"}; + + altAppMaterialColor = new JComboBox(colorVals); + altAppMaterialColor.addActionListener(this); + altAppMaterialColor.setSelectedIndex(2); + panel.add(new JLabel("Alternate Appearance MaterialColor")); + panel.add(altAppMaterialColor); + + + + appMaterialColor = new JComboBox(colorVals); + appMaterialColor.addActionListener(this); + appMaterialColor.setSelectedIndex(1); + panel.add(new JLabel("Normal Appearance MaterialColor")); + panel.add(appMaterialColor); + + return panel; + + + } + + public void actionPerformed(ActionEvent e) { + Object target = e.getSource(); + if (target == altAppMaterialColor) { + altMat.setDiffuseColor(colors[altAppMaterialColor.getSelectedIndex()]); + } + else if (target == altAppScoping) { + for (int i = 0; i < altApp.numScopes(); i++) { + altApp.removeScope(0); + } + if (altAppScoping.getSelectedIndex() == 0) { + altApp.addScope(content1); + } + else if (altAppScoping.getSelectedIndex() == 1) { + altApp.addScope(content2); + } + } + else if (target == override) { + int i; + if (override.getSelectedIndex()== 0) { + if (!shape1Enabled) { + for (i = 0; i < shapes1.length; i++) + shapes1[i].setAppearanceOverrideEnable(true); + shape1Enabled = true; + } + + if (shape2Enabled) { + for (i = 0; i < shapes2.length; i++) + shapes2[i].setAppearanceOverrideEnable(false); + shape2Enabled = false; + } + } + else if (override.getSelectedIndex() == 1) { + if (!shape2Enabled) { + for (i = 0; i < shapes2.length; i++) + shapes2[i].setAppearanceOverrideEnable(true); + shape2Enabled = true; + } + + if (shape1Enabled) { + for (i = 0; i < shapes1.length; i++) + shapes1[i].setAppearanceOverrideEnable(false); + shape1Enabled = false; + } + } + else if (override.getSelectedIndex() == 2) { + if (!shape1Enabled) { + for (i = 0; i < shapes1.length; i++) + shapes1[i].setAppearanceOverrideEnable(true); + shape1Enabled = true; + } + if (!shape2Enabled) { + for (i = 0; i < shapes2.length; i++) + shapes2[i].setAppearanceOverrideEnable(true); + shape2Enabled = true; + } + } + else { + if (shape1Enabled) { + for (i = 0; i < shapes1.length; i++) + shapes1[i].setAppearanceOverrideEnable(false); + shape1Enabled = false; + } + + if (shape2Enabled) { + for (i = 0; i < shapes2.length; i++) + shapes2[i].setAppearanceOverrideEnable(false); + shape2Enabled = false; + } + } + + } + else if (target == appMaterialColor) { + mat1.setDiffuseColor(colors[appMaterialColor.getSelectedIndex()]); + } + + } + + + public static void main(String[] args) { + Frame frame = new MainFrame(new AlternateAppearanceScopeTest(), 800, 800); + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java new file mode 100644 index 0000000..5e8a421 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/alternate_appearance/SphereGroup.java @@ -0,0 +1,125 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.alternate_appearance; + +import javax.media.j3d.*; +import javax.vecmath.*; +import com.sun.j3d.utils.geometry.*; + +public class SphereGroup + extends Group +{ + Shape3D[] shapes; + int numShapes = 0; + // Constructors + public SphereGroup( ) + { + // radius x,y spacing x,y count appearance + this( 0.25f, 0.75f, 0.75f, 5, 5, null, false ); + } + + public SphereGroup( Appearance app ) + { + // radius x,y spacing x,y count appearance + this( 0.25f, 0.75f, 0.75f, 5, 5, app, false ); + } + + public SphereGroup( float radius, float xSpacing, float ySpacing, + int xCount, int yCount, boolean overrideflag ) + { + this( radius, xSpacing, ySpacing, xCount, yCount, null, overrideflag ); + } + + public SphereGroup( float radius, float xSpacing, float ySpacing, + int xCount, int yCount, Appearance app, boolean overrideflag ) + { + if ( app == null ) + { + app = new Appearance( ); + Material material = new Material( ); + material.setDiffuseColor( new Color3f( 0.8f, 0.8f, 0.8f ) ); + material.setSpecularColor( new Color3f( 0.0f, 0.0f, 0.0f ) ); + material.setShininess( 0.0f ); + app.setMaterial( material ); + } + + double xStart = -xSpacing * (double)(xCount-1) / 2.0; + double yStart = -ySpacing * (double)(yCount-1) / 2.0; + + Sphere sphere = null; + TransformGroup trans = null; + Transform3D t3d = new Transform3D( ); + Vector3d vec = new Vector3d( ); + double x, y = yStart, z = 0.0; + shapes = new Shape3D[xCount * yCount]; + for ( int i = 0; i < yCount; i++ ) + { + x = xStart; + for ( int j = 0; j < xCount; j++ ) { + vec.set( x, y, z ); + t3d.setTranslation( vec ); + trans = new TransformGroup( t3d ); + addChild( trans ); + + sphere = new Sphere( + radius, // sphere radius + Primitive.GENERATE_NORMALS, // generate normals + 16, // 16 divisions radially + app ); // it's appearance + trans.addChild( sphere ); + x += xSpacing; + shapes[numShapes] = sphere.getShape(); + if (overrideflag) + shapes[numShapes].setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE); + numShapes++; + } + y += ySpacing; + } + } + Shape3D[] getShapes() { + return shapes; + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java b/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java new file mode 100644 index 0000000..578401e --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceMixed.java @@ -0,0 +1,508 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.appearance; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import java.awt.GraphicsConfiguration; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.image.TextureLoader; +import com.sun.j3d.utils.geometry.ColorCube; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class AppearanceMixed extends Applet { + + private java.net.URL bgImage; + private java.net.URL texImage; + + private SimpleUniverse u = null; + + static class MyCanvas3D extends Canvas3D { + private GraphicsContext3D gc; + + private static final int vertIndices[] = { 0, 1, 2, 0, 2, 3 }; + private static final int normalIndices[] = { 0, 0, 0, 1, 1, 1 }; + private IndexedTriangleArray tri = + new IndexedTriangleArray(4, IndexedTriangleArray.COORDINATES | + IndexedTriangleArray.NORMALS, 6); + + private Point3f vert[] = { + new Point3f(-0.12f, -0.12f, 0.0f), + new Point3f( 0.12f, -0.12f, 0.0f), + new Point3f( 0.12f, 0.12f, 0.0f), + new Point3f(-0.12f, 0.12f, 0.0f), + }; + + private Point3f min[] = { + new Point3f(-0.24f, -0.24f, -0.20f), + new Point3f( 0.04f, -0.28f, -0.24f), + new Point3f( 0.00f, 0.00f, -0.24f), + new Point3f(-0.32f, 0.08f, -0.20f), + }; + + private Point3f max[] = { + new Point3f(-0.04f, -0.04f, 0.12f), + new Point3f( 0.32f, -0.04f, 0.16f), + new Point3f( 0.36f, 0.28f, 0.20f), + new Point3f(-0.04f, 0.24f, 0.16f), + }; + + private Point3f delta[] = { + new Point3f(-0.0021f, -0.0017f, 0.0014f), + new Point3f( 0.0025f, -0.0013f, -0.0018f), + new Point3f( 0.0021f, 0.0017f, 0.0018f), + new Point3f(-0.0025f, 0.0013f, -0.0014f), + }; + + private Vector3f normals[]; + private Vector3f v01 = new Vector3f(); + private Vector3f v02 = new Vector3f(); + private Vector3f v03 = new Vector3f(); + + public void renderField(int fieldDesc) { + computeVert(); + computeNormals(); + gc.draw(tri); + } + + private void computeVert() { + for (int i = 0; i < 4; i++) { + vert[i].add(delta[i]); + if (vert[i].x > max[i].x) { + vert[i].x = max[i].x; + delta[i].x *= -1.0f; + } + if (vert[i].x < min[i].x) { + vert[i].x = min[i].x; + delta[i].x *= -1.0f; + } + if (vert[i].y > max[i].y) { + vert[i].y = max[i].y; + delta[i].y *= -1.0f; + } + if (vert[i].y < min[i].y) { + vert[i].y = min[i].y; + delta[i].y *= -1.0f; + } + if (vert[i].z > max[i].z) { + vert[i].z = max[i].z; + delta[i].z *= -1.0f; + } + if (vert[i].z < min[i].z) { + vert[i].z = min[i].z; + delta[i].z *= -1.0f; + } + } + tri.setCoordinates(0, vert); + } + + private void computeNormals() { + v01.sub(vert[1], vert[0]); + v02.sub(vert[2], vert[0]); + v03.sub(vert[3], vert[0]); + normals[0].cross(v01, v02); + normals[0].normalize(); + normals[1].cross(v02, v03); + normals[1].normalize(); + tri.setNormals(0, normals); + } + + public MyCanvas3D(GraphicsConfiguration gcfg) { + super(gcfg); + + // Allocate memory for normals + normals = new Vector3f[2]; + normals[0] = new Vector3f(); + normals[1] = new Vector3f(); + + // Set up the indices + tri.setCoordinateIndices(0, vertIndices); + tri.setNormalIndices(0, normalIndices); + + // Set up the graphics context + gc = getGraphicsContext3D(); + + // Create the appearance for the triangle fan + Appearance app = new Appearance(); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f objColor = new Color3f(0.0f, 0.0f, 0.8f); + app.setMaterial(new Material(objColor, black, objColor, + white, 80.0f)); + gc.setAppearance(app); + + // Set up the global lights + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + gc.addLight(new AmbientLight(alColor)); + gc.addLight(new DirectionalLight(lColor1, lDir1)); + } + } + + + private BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + TextureLoader bgTexture = new TextureLoader(bgImage, this); + Background bg = new Background(bgTexture.getImage()); + bg.setApplicationBounds(bounds); + objRoot.addChild(bg); + + // Set up the global lights + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + objRoot.addChild(aLgt); + objRoot.addChild(lgt1); + + // Create a bunch of objects with a behavior and add them + // into the scene graph. + + int row, col; + Appearance[][] app = new Appearance[3][3]; + + for (row = 0; row < 3; row++) + for (col = 0; col < 3; col++) + app[row][col] = createAppearance(row * 3 + col); + + for (int i = 0; i < 3; i++) { + double ypos = (double)(i - 1) * 0.6; + for (int j = 0; j < 3; j++) { + double xpos = (double)(j - 1) * 0.6; + objRoot.addChild(createObject(app[i][j], 0.12, xpos, ypos)); + } + } + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + + private Appearance createAppearance(int idx) { + Appearance app = new Appearance(); + + // Globally used colors + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + + switch (idx) { + // Unlit solid + case 0: + { + // Set up the coloring properties + Color3f objColor = new Color3f(1.0f, 0.2f, 0.4f); + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(objColor); + app.setColoringAttributes(ca); + break; + } + + + // Unlit wire frame + case 1: + { + // Set up the coloring properties + Color3f objColor = new Color3f(0.5f, 0.0f, 0.2f); + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(objColor); + app.setColoringAttributes(ca); + + // Set up the polygon attributes + PolygonAttributes pa = new PolygonAttributes(); + pa.setPolygonMode(pa.POLYGON_LINE); + pa.setCullFace(pa.CULL_NONE); + app.setPolygonAttributes(pa); + break; + } + + // Unlit points + case 2: + { + // Set up the coloring properties + Color3f objColor = new Color3f(0.2f, 0.2f, 1.0f); + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(objColor); + app.setColoringAttributes(ca); + + // Set up the polygon attributes + PolygonAttributes pa = new PolygonAttributes(); + pa.setPolygonMode(pa.POLYGON_POINT); + pa.setCullFace(pa.CULL_NONE); + app.setPolygonAttributes(pa); + + // Set up point attributes + PointAttributes pta = new PointAttributes(); + pta.setPointSize(5.0f); + app.setPointAttributes(pta); + break; + } + + // Lit solid + case 3: + { + // Set up the material properties + Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f); + app.setMaterial(new Material(objColor, black, objColor, + white, 80.0f)); + break; + } + + // Texture mapped, lit solid + case 4: + { + // Set up the texture map + TextureLoader tex = new TextureLoader(texImage, this); + app.setTexture(tex.getTexture()); + + TextureAttributes texAttr = new TextureAttributes(); + texAttr.setTextureMode(TextureAttributes.MODULATE); + app.setTextureAttributes(texAttr); + + + // Set up the material properties + app.setMaterial(new Material(white, black, white, black, 1.0f)); + break; + } + + // Transparent, lit solid + case 5: + { + // Set up the transparency properties + TransparencyAttributes ta = new TransparencyAttributes(); + ta.setTransparencyMode(ta.BLENDED); + ta.setTransparency(0.6f); + app.setTransparencyAttributes(ta); + + // Set up the polygon attributes + PolygonAttributes pa = new PolygonAttributes(); + pa.setCullFace(pa.CULL_NONE); + app.setPolygonAttributes(pa); + + // Set up the material properties + Color3f objColor = new Color3f(0.7f, 0.8f, 1.0f); + app.setMaterial(new Material(objColor, black, objColor, + black, 1.0f)); + break; + } + + // Lit solid, no specular + case 6: + { + // Set up the material properties + Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f); + app.setMaterial(new Material(objColor, black, objColor, + black, 80.0f)); + break; + } + + // Lit solid, specular only + case 7: + { + // Set up the material properties + Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f); + app.setMaterial(new Material(black, black, black, + white, 80.0f)); + break; + } + + // Another lit solid with a different color + case 8: + { + // Set up the material properties + Color3f objColor = new Color3f(0.8f, 0.8f, 0.0f); + app.setMaterial(new Material(objColor, black, objColor, + white, 80.0f)); + break; + } + + default: + { + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(new Color3f(0.0f, 1.0f, 0.0f)); + app.setColoringAttributes(ca); + } + } + + return app; + } + + + private Group createObject(Appearance app, double scale, + double xpos, double ypos) { + + // Create a transform group node to scale and position the object. + Transform3D t = new Transform3D(); + t.set(scale, new Vector3d(xpos, ypos, 0.0)); + TransformGroup objTrans = new TransformGroup(t); + + // Create a second transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. + TransformGroup spinTg = new TransformGroup(); + spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + + // Create a simple shape leaf node and set the appearance + Shape3D shape = new Tetrahedron(); + shape.setAppearance(app); + + // add it to the scene graph. + spinTg.addChild(shape); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into + // the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 5000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, spinTg, yAxis, + 0.0f, (float) Math.PI*2.0f); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + rotator.setSchedulingBounds(bounds); + + // Add the behavior and the transform group to the object + objTrans.addChild(rotator); + objTrans.addChild(spinTg); + + return objTrans; + } + + + public AppearanceMixed() { + } + + public AppearanceMixed(java.net.URL bgurl, java.net.URL texurl) { + bgImage = bgurl; + texImage = texurl; + } + public void init() { + if (bgImage == null) { + // the path to the image for an applet + try { + bgImage = new java.net.URL(getCodeBase().toString() + + "../images/bg.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + if (texImage == null) { + // the path to the image for an applet + try { + texImage = new java.net.URL(getCodeBase().toString() + + "../images/apimage.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + MyCanvas3D c = new MyCanvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + + // + // The following allows AppearanceMixed to be run as an application + // as well as an applet + // + public static void main(String[] args) { + // the path to the image file for an application + java.net.URL bgurl = null; + java.net.URL texurl = null; + try { + bgurl = new java.net.URL("file:../images/bg.jpg"); + texurl = new java.net.URL("file:../images/apimage.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + new MainFrame(new AppearanceMixed(bgurl, texurl), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceTest.java b/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceTest.java new file mode 100644 index 0000000..8d57c48 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/appearance/AppearanceTest.java @@ -0,0 +1,382 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.appearance; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.image.TextureLoader; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class AppearanceTest extends Applet { + + private java.net.URL texImage = null; + private java.net.URL bgImage = null; + + private SimpleUniverse u = null; + + private BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + TextureLoader bgTexture = new TextureLoader(bgImage, this); + Background bg = new Background(bgTexture.getImage()); + bg.setApplicationBounds(bounds); + objRoot.addChild(bg); + + // Set up the global lights + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + objRoot.addChild(aLgt); + objRoot.addChild(lgt1); + + // Create a bunch of objects with a behavior and add them + // into the scene graph. + + int row, col; + Appearance[][] app = new Appearance[3][3]; + + for (row = 0; row < 3; row++) + for (col = 0; col < 3; col++) + app[row][col] = createAppearance(row * 3 + col); + + for (int i = 0; i < 3; i++) { + double ypos = (double)(i - 1) * 0.6; + for (int j = 0; j < 3; j++) { + double xpos = (double)(j - 1) * 0.6; + objRoot.addChild(createObject(app[i][j], 0.12, xpos, ypos)); + } + } + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + + private Appearance createAppearance(int idx) { + Appearance app = new Appearance(); + + // Globally used colors + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + + switch (idx) { + // Unlit solid + case 0: + { + // Set up the coloring properties + Color3f objColor = new Color3f(1.0f, 0.2f, 0.4f); + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(objColor); + app.setColoringAttributes(ca); + break; + } + + + // Unlit wire frame + case 1: + { + // Set up the coloring properties + Color3f objColor = new Color3f(0.5f, 0.0f, 0.2f); + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(objColor); + app.setColoringAttributes(ca); + + // Set up the polygon attributes + PolygonAttributes pa = new PolygonAttributes(); + pa.setPolygonMode(pa.POLYGON_LINE); + pa.setCullFace(pa.CULL_NONE); + app.setPolygonAttributes(pa); + break; + } + + // Unlit points + case 2: + { + // Set up the coloring properties + Color3f objColor = new Color3f(0.2f, 0.2f, 1.0f); + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(objColor); + app.setColoringAttributes(ca); + + // Set up the polygon attributes + PolygonAttributes pa = new PolygonAttributes(); + pa.setPolygonMode(pa.POLYGON_POINT); + pa.setCullFace(pa.CULL_NONE); + app.setPolygonAttributes(pa); + + // Set up point attributes + PointAttributes pta = new PointAttributes(); + pta.setPointSize(5.0f); + app.setPointAttributes(pta); + break; + } + + // Lit solid + case 3: + { + // Set up the material properties + Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f); + app.setMaterial(new Material(objColor, black, objColor, + white, 80.0f)); + break; + } + + // Texture mapped, lit solid + case 4: + { + // Set up the texture map + TextureLoader tex = new TextureLoader(texImage, this); + app.setTexture(tex.getTexture()); + + TextureAttributes texAttr = new TextureAttributes(); + texAttr.setTextureMode(TextureAttributes.MODULATE); + app.setTextureAttributes(texAttr); + + // Set up the material properties + app.setMaterial(new Material(white, black, white, black, 1.0f)); + break; + } + + // Transparent, lit solid + case 5: + { + // Set up the transparency properties + TransparencyAttributes ta = new TransparencyAttributes(); + ta.setTransparencyMode(ta.BLENDED); + ta.setTransparency(0.6f); + app.setTransparencyAttributes(ta); + + // Set up the polygon attributes + PolygonAttributes pa = new PolygonAttributes(); + pa.setCullFace(pa.CULL_NONE); + app.setPolygonAttributes(pa); + + // Set up the material properties + Color3f objColor = new Color3f(0.7f, 0.8f, 1.0f); + app.setMaterial(new Material(objColor, black, objColor, + black, 1.0f)); + break; + } + + // Lit solid, no specular + case 6: + { + // Set up the material properties + Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f); + app.setMaterial(new Material(objColor, black, objColor, + black, 80.0f)); + break; + } + + // Lit solid, specular only + case 7: + { + // Set up the material properties + Color3f objColor = new Color3f(0.8f, 0.0f, 0.0f); + app.setMaterial(new Material(black, black, black, + white, 80.0f)); + break; + } + + // Another lit solid with a different color + case 8: + { + // Set up the material properties + Color3f objColor = new Color3f(0.8f, 0.8f, 0.0f); + app.setMaterial(new Material(objColor, black, objColor, + white, 80.0f)); + break; + } + + default: + { + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(new Color3f(0.0f, 1.0f, 0.0f)); + app.setColoringAttributes(ca); + } + } + + return app; + } + + + private Group createObject(Appearance app, double scale, + double xpos, double ypos) { + + // Create a transform group node to scale and position the object. + Transform3D t = new Transform3D(); + t.set(scale, new Vector3d(xpos, ypos, 0.0)); + TransformGroup objTrans = new TransformGroup(t); + + // Create a second transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. + TransformGroup spinTg = new TransformGroup(); + spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + + // Create a simple shape leaf node and set the appearance + Shape3D shape = new Tetrahedron(); + shape.setAppearance(app); + + // add it to the scene graph. + spinTg.addChild(shape); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into + // the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 5000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, spinTg, yAxis, + 0.0f, (float) Math.PI*2.0f); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + rotator.setSchedulingBounds(bounds); + + // Add the behavior and the transform group to the object + objTrans.addChild(rotator); + objTrans.addChild(spinTg); + + return objTrans; + } + + + public AppearanceTest() { + } + + public AppearanceTest(java.net.URL bgurl, java.net.URL texurl) { + bgImage = bgurl; + texImage = texurl; + } + + public void init() { + if (bgImage == null) { + // the path to the image for an applet + try { + bgImage = new java.net.URL(getCodeBase().toString() + + "../images/bg.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + if (texImage == null) { + // the path to the image for an applet + try { + texImage = new java.net.URL(getCodeBase().toString() + + "../images/apimage.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + + // + // The following allows AppearanceTest to be run as an application + // as well as an applet + // + public static void main(String[] args) { + // the path to the image file for an application + java.net.URL bgurl = null; + java.net.URL texurl = null; + try { + bgurl = new java.net.URL("file:../images/bg.jpg"); + texurl = new java.net.URL("file:../images/apimage.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + new MainFrame(new AppearanceTest(bgurl, texurl), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/appearance/Tetrahedron.java b/src/classes/org/jdesktop/j3d/examples/appearance/Tetrahedron.java new file mode 100644 index 0000000..af67321 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/appearance/Tetrahedron.java @@ -0,0 +1,109 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.appearance; + +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Tetrahedron extends Shape3D { + private static final float sqrt3 = (float) Math.sqrt(3.0); + private static final float sqrt3_3 = sqrt3 / 3.0f; + private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f; + + private static final float ycenter = 0.5f * sqrt24_3; + private static final float zcenter = -sqrt3_3; + + private static final Point3f p1 = new Point3f(-1.0f, -ycenter, -zcenter); + private static final Point3f p2 = new Point3f(1.0f, -ycenter, -zcenter); + private static final Point3f p3 = + new Point3f(0.0f, -ycenter, -sqrt3 - zcenter); + private static final Point3f p4 = + new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f); + + private static final Point3f[] verts = { + p1, p2, p4, // front face + p1, p4, p3, // left, back face + p2, p3, p4, // right, back face + p1, p3, p2, // bottom face + }; + + private TexCoord2f texCoord[] = { + new TexCoord2f(0.0f, 0.0f), + new TexCoord2f(1.0f, 0.0f), + new TexCoord2f(0.5f, sqrt3 / 2.0f), + }; + + public Tetrahedron() { + int i; + + TriangleArray tetra = new TriangleArray(12, TriangleArray.COORDINATES | + TriangleArray.NORMALS | TriangleArray.TEXTURE_COORDINATE_2); + + tetra.setCoordinates(0, verts); + for (i = 0; i < 12; i++) { + tetra.setTextureCoordinate(0, i, texCoord[i%3]); + } + + int face; + Vector3f normal = new Vector3f(); + Vector3f v1 = new Vector3f(); + Vector3f v2 = new Vector3f(); + Point3f [] pts = new Point3f[3]; + for (i = 0; i < 3; i++) pts[i] = new Point3f(); + + for (face = 0; face < 4; face++) { + tetra.getCoordinates(face*3, pts); + v1.sub(pts[1], pts[0]); + v2.sub(pts[2], pts[0]); + normal.cross(v1, v2); + normal.normalize(); + for (i = 0; i < 3; i++) { + tetra.setNormal((face * 3 + i), normal); + } + } + this.setGeometry(tetra); + this.setAppearance(new Appearance()); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.html b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.html new file mode 100644 index 0000000..8ab3a5d --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.html @@ -0,0 +1,15 @@ + + +Hello, Universe + + + +
+
+If you were using a Java-capable browser, +you would see Applet3D instead of this paragraph. +
+
+
+ + diff --git a/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.java b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.java new file mode 100644 index 0000000..9abecd9 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D.java @@ -0,0 +1,129 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.applet3d; + +import java.applet.Applet; +import java.awt.BorderLayout; +import java.awt.event.*; +import java.awt.GraphicsConfiguration; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Applet3D extends Applet { + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create the TransformGroup node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at run time. Add it to + // the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple Shape3D node; add it to the scene graph. + objTrans.addChild(new ColorCube(0.4)); + + // Create a new Behavior object that will perform the + // desired operation on the specified transform and add + // it into the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, 4000); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objRoot.addChild(rotator); + + // Have Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public Applet3D() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows Applet3D to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new Applet3D(), 256, 256); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D_plugin.html b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D_plugin.html new file mode 100644 index 0000000..e47eecc --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/applet3d/Applet3D_plugin.html @@ -0,0 +1,39 @@ + + +Hello, Universe! + + + + + + + + + + +</COMMENT> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see Hello Universe! instead of this paragraph. +<hr> +</blockquote> + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/background/BackgroundGeometry.java b/src/classes/org/jdesktop/j3d/examples/background/BackgroundGeometry.java new file mode 100644 index 0000000..e6ea23c --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/background/BackgroundGeometry.java @@ -0,0 +1,238 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.background; + +import com.sun.j3d.utils.image.TextureLoader; +import com.sun.j3d.utils.behaviors.mouse.*; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class BackgroundGeometry extends Applet { + + BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + private java.net.URL bgImage = null; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. + TransformGroup objTrans = new TransformGroup(); + objScale.addChild(objTrans); + + Background bg = new Background(); + bg.setApplicationBounds(bounds); + BranchGroup backGeoBranch = new BranchGroup(); + Sphere sphereObj = new Sphere(1.0f, Sphere.GENERATE_NORMALS | + Sphere.GENERATE_NORMALS_INWARD | + Sphere.GENERATE_TEXTURE_COORDS, 45); + Appearance backgroundApp = sphereObj.getAppearance(); + backGeoBranch.addChild(sphereObj); + bg.setGeometry(backGeoBranch); + objTrans.addChild(bg); + + TextureLoader tex = new TextureLoader(bgImage, + new String("RGB"), this); + if (tex != null) + backgroundApp.setTexture(tex.getTexture()); + + Vector3f tranlation = new Vector3f(2.0f, 0.0f, 0.0f); + Transform3D modelTransform = new Transform3D(); + Transform3D tmpTransform = new Transform3D(); + double angleInc = Math.PI/8.0; + double angle = 0.0; + int numBoxes = 16; + + float scaleX[] = {0.1f, 0.2f, 0.2f, 0.3f, + 0.2f, 0.1f, 0.2f, 0.3f, + 0.1f, 0.3f, 0.2f, 0.3f, + 0.1f, 0.3f, 0.2f, 0.3f}; + + float scaleY[] = {0.3f, 0.4f, 0.3f, 0.4f, + 0.3f, 0.4f, 0.3f, 0.4f, + 0.3f, 0.3f, 0.3f, 0.3f, + 0.3f, 0.3f, 0.3f, 0.4f}; + + float scaleZ[] = {0.3f, 0.2f, 0.1f, 0.1f, + 0.3f, 0.2f, 0.1f, 0.3f, + 0.3f, 0.2f, 0.1f, 0.3f, + 0.3f, 0.2f, 0.1f, 0.2f}; + + Appearance a1 = new Appearance(); + Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f); + Color3f sColor = new Color3f(0.5f, 0.5f, 1.0f); + Color3f oColor = new Color3f(0.5f, 0.5f, 0.3f); + + Material m = new Material(oColor, eColor, oColor, sColor, 100.0f); + m.setLightingEnable(true); + a1.setMaterial(m); + + for (int i=0; i"); + System.out.println(" -s Spin (no user interaction)"); + System.out.println(" -n No triangulation"); + System.out.println(" -t No stripification"); + System.out.println( + " -c Set crease angle for normal generation (default is 60 without"); + System.out.println( + " smoothing group info, otherwise 180 within smoothing groups)"); + System.exit(0); + } // End of usage + + + + public void init() { + if (filename == null) { + // Applet + try { + URL path = getCodeBase(); + filename = new URL(path.toString() + "./galleon.obj"); + } + catch (MalformedURLException e) { + System.err.println(e); + System.exit(1); + } + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // add mouse behaviors to the ViewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + PlatformGeometry pg = new PlatformGeometry(); + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + pg.addChild(ambientLightNode); + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 0.2f, 0.4f); + Vector3f light1Direction = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light2Direction = new Vector3f(1.0f, 1.0f, 1.0f); + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + pg.addChild(light1); + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + pg.addChild(light2); + + viewingPlatform.setPlatformGeometry( pg ); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + if (!spin) { + OrbitBehavior orbit = new OrbitBehavior(c, + OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + } + + /* + // Limit the frame rate to 100 Hz + u.getViewer().getView().setMinimumFrameCycleTime(10); + */ + + u.addBranchGraph(scene); + } + + // Set shader program for all nodes in specified branch graph + private void setShaderProgram(BranchGroup g, ShaderProgram shaderProgram) { + ShaderAppearance myApp = new ShaderAppearance(); + Material mat = new Material(); + Texture2D tex2d = new Texture2D(); + myApp.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + myApp.setShaderProgram(shaderProgram); + myApp.setMaterial(mat); + myApp.setTexture(tex2d); + setShaderProgram(g, myApp); + } + + // Recursively set shader program for all children of specified group + private void setShaderProgram(Group g, + ShaderAppearance myApp) { + + Enumeration e = g.getAllChildren(); + while (e.hasMoreElements()) { + Node n = (Node)(e.nextElement()); + if (n instanceof Group) { + setShaderProgram((Group)n, myApp); + } + else if (n instanceof Shape3D) { + Shape3D s = (Shape3D)n; + s.setAppearance(myApp); + } + } + } + + // Caled if running as a program + public ObjLoadCg(String[] args) { + if (args.length != 0) { + for (int i = 0 ; i < args.length ; i++) { + if (args[i].startsWith("-")) { + if (args[i].equals("-s")) { + spin = true; + } else if (args[i].equals("-n")) { + noTriangulate = true; + } else if (args[i].equals("-t")) { + noStripify = true; + } else if (args[i].equals("-c")) { + if (i < args.length - 1) { + creaseAngle = (new Double(args[++i])).doubleValue(); + } else usage(); + } else { + usage(); + } + } else { + try { + if ((args[i].indexOf("file:") == 0) || + (args[i].indexOf("http") == 0)) { + filename = new URL(args[i]); + } + else if (args[i].charAt(0) != '/') { + filename = new URL("file:./" + args[i]); + } + else { + filename = new URL("file:" + args[i]); + } + } + catch (MalformedURLException e) { + System.err.println(e); + System.exit(1); + } + } + } + } + } + + + + // Running as an applet + public ObjLoadCg() { + } + + public void destroy() { + u.cleanup(); + } + + + + // + // The following allows ObjLoadCg to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new ObjLoadCg(args), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/cg_shader/SphereCg.java b/src/classes/org/jdesktop/j3d/examples/cg_shader/SphereCg.java new file mode 100644 index 0000000..2757006 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/cg_shader/SphereCg.java @@ -0,0 +1,348 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.cg_shader; + +import java.applet.Applet; +import java.awt.*; +import java.io.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.shader.StringIO; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; +import java.net.URL; +import java.net.MalformedURLException; + +/** + * Simple CG Shader test program + */ +public class SphereCg extends Applet { + + // Constants for type of light to use + private static final int DIRECTIONAL_LIGHT = 0; + private static final int POINT_LIGHT = 1; + private static final int SPOT_LIGHT = 2; + + // Flag indicates type of lights: directional, point, or spot + // lights. This flag is set based on command line argument + private static int lightType = DIRECTIONAL_LIGHT; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph(SimpleUniverse u) { + Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f); + Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f); + Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f); + Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f); + Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + + Transform3D t; + + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + objScale.addChild(bg); + + // Create a Sphere object, generate one copy of the sphere, + // and add it into the scene graph. + ShaderAppearance a = new ShaderAppearance(); + Material m = new Material(objColor, eColor, objColor, sColor, 100.0f); + m.setLightingEnable(true); + Texture t2d = new Texture2D(); + a.setTexture(t2d); + a.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + + String vertexProgram = null; + String fragmentProgram = null; + try { + vertexProgram = StringIO.readFully("./simple_vp.cg"); + fragmentProgram = StringIO.readFully("./simple_fp.cg"); + } + catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + Shader[] shaders = new Shader[2]; + shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_CG, + Shader.SHADER_TYPE_VERTEX, + vertexProgram); + shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_CG, + Shader.SHADER_TYPE_FRAGMENT, + fragmentProgram); + ShaderProgram shaderProgram = new CgShaderProgram(); + shaderProgram.setShaders(shaders); + + a.setShaderProgram(shaderProgram); + a.setMaterial(m); + Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS, 200, a); + objScale.addChild(sph); + + // Create the transform group node for the each light and initialize + // it to the identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add them to the root + // of the subgraph. + TransformGroup l1RotTrans = new TransformGroup(); + l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(l1RotTrans); + + TransformGroup l2RotTrans = new TransformGroup(); + l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(l2RotTrans); + + // Create transformations for the positional lights + t = new Transform3D(); + Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0); + t.set(lPos1); + TransformGroup l1Trans = new TransformGroup(t); + l1RotTrans.addChild(l1Trans); + + t = new Transform3D(); + Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0); + t.set(lPos2); + TransformGroup l2Trans = new TransformGroup(t); + l2RotTrans.addChild(l2Trans); + + /* + // Create Geometry for point lights + ColoringAttributes caL1 = new ColoringAttributes(); + ColoringAttributes caL2 = new ColoringAttributes(); + caL1.setColor(lColor1); + caL2.setColor(lColor2); + Appearance appL1 = new Appearance(); + Appearance appL2 = new Appearance(); + appL1.setColoringAttributes(caL1); + appL2.setColoringAttributes(caL2); + l1Trans.addChild(new Sphere(0.05f, appL1)); + l2Trans.addChild(new Sphere(0.05f, appL2)); + */ + + // Create lights + AmbientLight aLgt = new AmbientLight(alColor); + + Light lgt1 = null; + Light lgt2 = null; + + Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f); + Point3f atten = new Point3f(1.0f, 0.0f, 0.0f); + Vector3f lDirect1 = new Vector3f(lPos1); + Vector3f lDirect2 = new Vector3f(lPos2); + lDirect1.negate(); + lDirect2.negate(); + + switch (lightType) { + case DIRECTIONAL_LIGHT: + lgt1 = new DirectionalLight(lColor1, lDirect1); + lgt2 = new DirectionalLight(lColor2, lDirect2); + break; + case POINT_LIGHT: + lgt1 = new PointLight(lColor1, lPoint, atten); + lgt2 = new PointLight(lColor2, lPoint, atten); + break; + case SPOT_LIGHT: + lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1, + 25.0f * (float)Math.PI / 180.0f, 10.0f); + lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2, + 25.0f * (float)Math.PI / 180.0f, 10.0f); + break; + } + + // Set the influencing bounds + aLgt.setInfluencingBounds(bounds); + lgt1.setInfluencingBounds(bounds); + lgt2.setInfluencingBounds(bounds); + + // Add the lights into the scene graph + objScale.addChild(aLgt); + l1Trans.addChild(lgt1); + l2Trans.addChild(lgt2); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator1 = + new RotationInterpolator(rotor1Alpha, + l1RotTrans, + yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator1.setSchedulingBounds(bounds); + l1RotTrans.addChild(rotator1); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Alpha rotor2Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 1000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator2 = + new RotationInterpolator(rotor2Alpha, + l2RotTrans, + yAxis, + 0.0f, 0.0f); + bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator2.setSchedulingBounds(bounds); + l2RotTrans.addChild(rotator2); + + // Create a position interpolator and attach it to the view + // platform + TransformGroup vpTrans = + u.getViewingPlatform().getViewPlatformTransform(); + Transform3D axisOfTranslation = new Transform3D(); + Alpha transAlpha = new Alpha(-1, + Alpha.INCREASING_ENABLE | + Alpha.DECREASING_ENABLE, + 0, 0, + 5000, 0, 0, + 5000, 0, 0); + axisOfTranslation.rotY(-Math.PI/2.0); + PositionInterpolator translator = + new PositionInterpolator(transAlpha, + vpTrans, + axisOfTranslation, + 2.0f, 3.5f); + translator.setSchedulingBounds(bounds); + objScale.addChild(translator); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public SphereCg() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + u = new SimpleUniverse(c); + BranchGroup scene = createSceneGraph(u); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + /* + // Limit the frame rate to 100 Hz + u.getViewer().getView().setMinimumFrameCycleTime(10); + */ + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows SphereCg to be run as an application + // as well as an applet + // + public static void main(String[] args) { + // Parse the Input Arguments + String usage = "Usage: java SphereCg [-point | -spot | -dir]"; + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("-")) { + if (args[i].equals("-point")) { + /* + System.out.println("Using point lights"); + lightType = POINT_LIGHT; + */ + System.out.println("Point lights not yet implemented, option ignored"); + } + else if (args[i].equals("-spot")) { + /* + System.out.println("Using spot lights"); + lightType = SPOT_LIGHT; + */ + System.out.println("Spot lights not yet implemented, option ignored"); + } + else if (args[i].equals("-dir")) { + System.out.println("Using directional lights"); + lightType = DIRECTIONAL_LIGHT; + } + else { + System.out.println(usage); + System.exit(0); + } + } + else { + System.out.println(usage); + System.exit(0); + } + } + + new MainFrame(new SphereCg(), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_fp.cg b/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_fp.cg new file mode 100644 index 0000000..e9cd44b --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_fp.cg @@ -0,0 +1,68 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +// Simple fragment program to attenuate the input fragment color as a +// function of the distance of the fragment position from the center +// of the window + +// define inputs from vertex shader to fragment shader +struct vertin +{ + float4 HPosition : POSITION; + float4 FragPos : TEXCOORD0; + float4 Color0 : COLOR0; +}; + +float4 main(vertin IN) : COLOR +{ + // Compute distance from center in range [0.0, 1.0] + float2 dist = min(abs(IN.FragPos.xy), 1.0f); + float2 invDist = 1.0f - dist; + + // Compute attenuation + float atten = invDist.x * invDist.y; + float4 outcolor = float4(IN.Color0 * atten); + + return outcolor; +} diff --git a/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_vp.cg b/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_vp.cg new file mode 100644 index 0000000..d030818 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/cg_shader/simple_vp.cg @@ -0,0 +1,167 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/*********************************************************************NVMH3**** +Path: NVSDK\Common\media\programs +File: simple.cg + +Copyright NVIDIA Corporation 2002 +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS +BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES +WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, +BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) +ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +Comments: + +******************************************************************************/ + +// Simple vertex shader, derived from NVIDIA's simple.cg sample +// shader, that modulates the lit color with a noise pattern based on +// vertex position. + +// define inputs from application +struct appin +{ + float4 Position : POSITION; + float4 Normal : NORMAL; +}; + +// define outputs from vertex shader +struct vertout +{ + float4 HPosition : POSITION; + float4 FragPos : TEXCOORD0; + float4 Color0 : COLOR0; +}; + +vertout main(appin IN, + uniform float4x4 ModelViewProj, + uniform float4x4 ModelViewIT, + uniform float4 LightVec, + uniform float4 LightColor, + uniform float4 DiffuseMaterial, + uniform float4 SpecularMaterial) +{ + vertout OUT; + +// Assume that the profile is PROFILE_ARBVP1... +// #ifdef PROFILE_ARBVP1 + ModelViewProj = glstate.matrix.mvp; + ModelViewIT = glstate.matrix.invtrans.modelview[0]; + LightVec = glstate.light[0].position; + LightColor = glstate.light[0].diffuse; + DiffuseMaterial = glstate.material.front.diffuse; + SpecularMaterial = glstate.material.front.specular; +// #endif + + // transform vertex position into homogenous clip-space + OUT.HPosition = mul(ModelViewProj, IN.Position); + + // Output the post-perspective-divide position as FragPos + float invW = 1.0f / OUT.HPosition.w; + OUT.FragPos = OUT.HPosition * invW; + + // transform normal from model-space to view-space + float3 normalVec = normalize(mul(ModelViewIT, IN.Normal).xyz); + + // store normalized light vector + float3 lightVec = normalize(LightVec.xyz); + + // calculate half angle vector + float3 eyeVec = float3(0.0, 0.0, 1.0); + float3 halfVec = normalize(lightVec + eyeVec); + + // calculate diffuse component + float diffuse = dot(normalVec, lightVec); + + // calculate specular component + float specular = dot(normalVec, halfVec); + + // The lit() function is a handy function in the standard library that + // can be used to accelerate your lighting calculations. + // + // This function return a vector containing these values: + // result.x = 1.0; + // result.y = max(diffuse, 0); + // result.z = if (result.y > 0.0) then pow(specular, 32) else 0.0 + // result.w = 1.0; + + // Use the lit function to compute lighting vector from diffuse and + // specular values + float4 lighting = lit(diffuse, specular, 32); + + // combine diffuse and specular contributions + float3 color0 = (lighting.y * DiffuseMaterial.xyz * LightColor.xyz) + + (lighting.z * SpecularMaterial.xyz); + + // Generate a pseudo-random noise pattern +// float3 xyz = clamp((normalVec.xyz + 1.0) * 0.5, 0.0, 1.0); + float3 xyz = clamp((OUT.HPosition.xyz + 1.0) * 0.5, 0.0, 1.0); + + xyz = frac(xyz * 262144.0); + float randSeed = frac(3.0 * xyz.x + 5.0 * xyz.y + 7.0 * xyz.z); + + float3 altColor; + + randSeed = frac(37.0 * randSeed); + altColor.x = randSeed * 0.5 + 0.5; + randSeed = frac(37.0 * randSeed); + altColor.y = randSeed * 0.5 + 0.5; + randSeed = frac(37.0 * randSeed); + altColor.z = randSeed * 0.5 + 0.5; + randSeed = frac(37.0 * randSeed); + float altAlpha = randSeed * 0.5; + + // Apply noise and output final vertex color + OUT.Color0.rgb = lerp(color0, altColor, altAlpha); + OUT.Color0.a = 1.0; + + return OUT; +} diff --git a/src/classes/org/jdesktop/j3d/examples/collision/Box.java b/src/classes/org/jdesktop/j3d/examples/collision/Box.java new file mode 100644 index 0000000..db39e1d --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/collision/Box.java @@ -0,0 +1,100 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.collision; + +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Box extends Shape3D { + + public Box(double xsize, double ysize, double zsize) { + super(); + double xmin = -xsize/2.0; + double xmax = xsize/2.0; + double ymin = -ysize/2.0; + double ymax = ysize/2.0; + double zmin = -zsize/2.0; + double zmax = zsize/2.0; + + QuadArray box = new QuadArray(24, QuadArray.COORDINATES); + + Point3d verts[] = new Point3d[24]; + + // front face + verts[0] = new Point3d(xmax, ymin, zmax); + verts[1] = new Point3d(xmax, ymax, zmax); + verts[2] = new Point3d(xmin, ymax, zmax); + verts[3] = new Point3d(xmin, ymin, zmax); + // back face + verts[4] = new Point3d(xmin, ymin, zmin); + verts[5] = new Point3d(xmin, ymax, zmin); + verts[6] = new Point3d(xmax, ymax, zmin); + verts[7] = new Point3d(xmax, ymin, zmin); + // right face + verts[8] = new Point3d(xmax, ymin, zmin); + verts[9] = new Point3d(xmax, ymax, zmin); + verts[10] = new Point3d(xmax, ymax, zmax); + verts[11] = new Point3d(xmax, ymin, zmax); + // left face + verts[12] = new Point3d(xmin, ymin, zmax); + verts[13] = new Point3d(xmin, ymax, zmax); + verts[14] = new Point3d(xmin, ymax, zmin); + verts[15] = new Point3d(xmin, ymin, zmin); + // top face + verts[16] = new Point3d(xmax, ymax, zmax); + verts[17] = new Point3d(xmax, ymax, zmin); + verts[18] = new Point3d(xmin, ymax, zmin); + verts[19] = new Point3d(xmin, ymax, zmax); + // bottom face + verts[20] = new Point3d(xmin, ymin, zmax); + verts[21] = new Point3d(xmin, ymin, zmin); + verts[22] = new Point3d(xmax, ymin, zmin); + verts[23] = new Point3d(xmax, ymin, zmax); + + box.setCoordinates(0, verts); + setGeometry(box); + setAppearance(new Appearance()); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/collision/CollisionDetector.java b/src/classes/org/jdesktop/j3d/examples/collision/CollisionDetector.java new file mode 100644 index 0000000..935b146 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/collision/CollisionDetector.java @@ -0,0 +1,92 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.collision; + +import java.util.Enumeration; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class CollisionDetector extends Behavior { + private static final Color3f highlightColor = + new Color3f(0.0f, 1.0f, 0.0f); + private static final ColoringAttributes highlight = + new ColoringAttributes(highlightColor, + ColoringAttributes.SHADE_GOURAUD); + + private boolean inCollision = false; + private Shape3D shape; + private ColoringAttributes shapeColoring; + private Appearance shapeAppearance; + + private WakeupOnCollisionEntry wEnter; + private WakeupOnCollisionExit wExit; + + + public CollisionDetector(Shape3D s) { + shape = s; + shapeAppearance = shape.getAppearance(); + shapeColoring = shapeAppearance.getColoringAttributes(); + inCollision = false; + } + + public void initialize() { + wEnter = new WakeupOnCollisionEntry(shape); + wExit = new WakeupOnCollisionExit(shape); + wakeupOn(wEnter); + } + + public void processStimulus(Enumeration criteria) { + inCollision = !inCollision; + + if (inCollision) { + shapeAppearance.setColoringAttributes(highlight); + wakeupOn(wExit); + } + else { + shapeAppearance.setColoringAttributes(shapeColoring); + wakeupOn(wEnter); + } + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/collision/TickTockCollision.java b/src/classes/org/jdesktop/j3d/examples/collision/TickTockCollision.java new file mode 100644 index 0000000..731dff7 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/collision/TickTockCollision.java @@ -0,0 +1,219 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.collision; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class TickTockCollision extends Applet { + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create a bounds for the background and behaviors + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + objScale.addChild(bg); + + // Create a pair of transform group nodes and initialize them to + // identity. Enable the TRANSFORM_WRITE capability so that + // our behaviors can modify them at runtime. Add them to the + // root of the subgraph. + TransformGroup objTrans1 = new TransformGroup(); + objTrans1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(objTrans1); + + TransformGroup objTrans2 = new TransformGroup(); + objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans1.addChild(objTrans2); + + // Create the positioning and scaling transform group node. + Transform3D t = new Transform3D(); + t.set(0.3, new Vector3d(0.0, -1.5, 0.0)); + TransformGroup objTrans3 = new TransformGroup(t); + objTrans2.addChild(objTrans3); + + // Create a simple shape leaf node, add it to the scene graph. + objTrans3.addChild(new ColorCube()); + + // Create a new Behavior object that will perform the desired + // rotation on the specified transform object and add it into + // the scene graph. + Transform3D yAxis1 = new Transform3D(); + yAxis1.rotX(Math.PI/2.0); + Alpha tickTockAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE | + Alpha.DECREASING_ENABLE, + 0, 0, + 5000, 2500, 200, + 5000, 2500, 200); + + RotationInterpolator tickTock = + new RotationInterpolator(tickTockAlpha, objTrans1, yAxis1, + -(float) Math.PI/2.0f, + (float) Math.PI/2.0f); + tickTock.setSchedulingBounds(bounds); + objTrans2.addChild(tickTock); + + // Create a new Behavior object that will perform the desired + // rotation on the specified transform object and add it into + // the scene graph. + Transform3D yAxis2 = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans2, yAxis2, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objTrans2.addChild(rotator); + + // Now create a pair of rectangular boxes, each with a collision + // detection behavior attached. The behavior will highlight the + // object when it is in a state of collision. + + Group box1 = createBox(0.3, new Vector3d(-1.3, 0.0, 0.0)); + Group box2 = createBox(0.3, new Vector3d( 1.3, 0.0, 0.0)); + + objScale.addChild(box1); + objScale.addChild(box2); + + // Have Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + + private Group createBox(double scale, Vector3d pos) { + // Create a transform group node to scale and position the object. + Transform3D t = new Transform3D(); + t.set(scale, pos); + TransformGroup objTrans = new TransformGroup(t); + + // Create a simple shape leaf node and add it to the scene graph + Shape3D shape = new Box(0.5, 5.0, 1.0); + objTrans.addChild(shape); + + // Create a new ColoringAttributes object for the shape's + // appearance and make it writable at runtime. + Appearance app = shape.getAppearance(); + ColoringAttributes ca = new ColoringAttributes(); + ca.setColor(0.6f, 0.3f, 0.0f); + app.setCapability(app.ALLOW_COLORING_ATTRIBUTES_WRITE); + app.setColoringAttributes(ca); + + // Create a new Behavior object that will perform the collision + // detection on the specified object, and add it into + // the scene graph. + CollisionDetector cd = new CollisionDetector(shape); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + cd.setSchedulingBounds(bounds); + + // Add the behavior to the scene graph + objTrans.addChild(cd); + + return objTrans; + } + + + public TickTockCollision() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows TickTockCollision to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new TickTockCollision(), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java b/src/classes/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java new file mode 100644 index 0000000..f96b2ed --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/ConfigObjLoad.java @@ -0,0 +1,311 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.configured_universe; + +import com.sun.j3d.loaders.objectfile.ObjectFile; +import com.sun.j3d.loaders.ParsingErrorException; +import com.sun.j3d.loaders.IncorrectFormatException; +import com.sun.j3d.loaders.Scene; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.io.*; +import com.sun.j3d.utils.behaviors.vp.*; +import com.sun.j3d.utils.behaviors.sensor.Mouse6DPointerBehavior; +import java.net.URL; +import java.net.MalformedURLException; +import java.util.Map; + +public class ConfigObjLoad { + + private boolean spin = false; + private boolean noTriangulate = false; + private boolean noStripify = false; + private double creaseAngle = 60.0; + private URL filename = null; + + private ConfiguredUniverse u; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.7); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objScale.addChild(objTrans); + + int flags = ObjectFile.RESIZE; + if (!noTriangulate) flags |= ObjectFile.TRIANGULATE; + if (!noStripify) flags |= ObjectFile.STRIPIFY; + ObjectFile f = new ObjectFile(flags, + (float)(creaseAngle * Math.PI / 180.0)); + Scene s = null; + try { + s = f.load(filename); + } + catch (FileNotFoundException e) { + System.err.println(e); + System.exit(1); + } + catch (ParsingErrorException e) { + System.err.println(e); + System.exit(1); + } + catch (IncorrectFormatException e) { + System.err.println(e); + System.exit(1); + } + + objTrans.addChild(s.getSceneGroup()); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + if (spin) { + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + } + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f); + Background bgNode = new Background(bgColor); + bgNode.setApplicationBounds(bounds); + objRoot.addChild(bgNode); + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + objRoot.addChild(ambientLightNode); + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f); + Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f); + Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f); + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + objRoot.addChild(light1); + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + objRoot.addChild(light2); + + return objRoot; + } + + private void usage() + { + System.out.println( + "Usage: java ObjLoad [-s] [-n] [-t] [-c degrees] <.obj file>"); + System.out.println(" -s Spin (no user interaction)"); + System.out.println(" -n No triangulation"); + System.out.println(" -t No stripification"); + System.out.println( + " -c Set crease angle for normal generation (default is 60 without"); + System.out.println( + " smoothing group info, otherwise 180 within smoothing groups)"); + System.exit(0); + } // End of usage + + + public void init() { + if (filename == null) { + try { + filename = new URL("file:../geometry/galleon.obj"); + } + catch (MalformedURLException e) { + System.err.println(e); + System.exit(1); + } + } + + // Get the config file URL from the j3d.configURL property or use the + // default config file "j3d1x1-window" in the current directory. + URL configURL = ConfiguredUniverse.getConfigURL("file:j3d1x1-window"); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new ConfiguredUniverse(configURL); + + // Get the ViewingPlatform. + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the objects in the + // scene can be viewed. This will only have an effect if the config + // file sets the window eyepoint policy to something other than + // RELATIVE_TO_COEXISTENCE, which is the default eyepoint policy + // applied by ConfiguredUniverse. + // + // The default view attach policy for ConfiguredUniverse applications + // is NOMINAL_SCREEN. This sets the view platform origin in the + // physical world to the center of coexistence, which allows eye + // positions expressed relative to coexistence to see the appropriate + // field of view automatically. + viewingPlatform.setNominalViewingTransform(); + + // Add a ViewPlatformBehavior if not specified in the config file. + if (!spin && viewingPlatform.getViewPlatformBehavior() == null) { + OrbitBehavior orbit = new OrbitBehavior(u.getCanvas(), + OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + } + + // See if there's a 6 degree of freedom mouse in the environment. + // We look for one named "mouse6d". + Map sensorMap = null; + sensorMap = u.getNamedSensors(); + if (sensorMap != null) { + Sensor mouse6d = (Sensor)sensorMap.get("mouse6d"); + if (mouse6d != null) { + Mouse6DPointerBehavior behavior = + new Mouse6DPointerBehavior(mouse6d, 1.0, true); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + behavior.setSchedulingBounds(bounds); + + scene.addChild(behavior); + scene.addChild(behavior.getEcho()); + } + } + + // Listen for a typed "q", "Q", or "Escape" key on each canvas to + // allow a convenient exit from full screen configurations. + Canvas3D[] canvases; + canvases = u.getViewer().getCanvas3Ds(); + + class QuitListener extends KeyAdapter { + public void keyTyped(KeyEvent e) { + char c = e.getKeyChar(); + if (c == 'q' || c == 'Q' || c == 27) + System.exit(0); + } + } + + QuitListener quitListener = new QuitListener(); + for (int i = 0; i < canvases.length; i++) + canvases[i].addKeyListener(quitListener); + + // Make the scenegraph live. + u.addBranchGraph(scene); + } + + public ConfigObjLoad(String[] args) { + if (args.length != 0) { + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("-")) { + if (args[i].equals("-s")) { + spin = true; + } else if (args[i].equals("-n")) { + noTriangulate = true; + } else if (args[i].equals("-t")) { + noStripify = true; + } else if (args[i].equals("-c")) { + if (i < args.length - 1) { + creaseAngle = (new Double(args[++i])).doubleValue(); + } else usage(); + } else { + usage(); + } + } else { + try { + if ((args[i].indexOf("file:") == 0) || + (args[i].indexOf("http") == 0)) { + filename = new URL(args[i]); + } + else if (args[i].charAt(0) != '/') { + filename = new URL("file:./" + args[i]); + } + else { + filename = new URL("file:" + args[i]); + } + } + catch (MalformedURLException e) { + System.err.println(e); + System.exit(1); + } + } + } + } + init(); + } + + public static void main(String[] args) { + new ConfigObjLoad(args); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/README.txt b/src/classes/org/jdesktop/j3d/examples/configured_universe/README.txt new file mode 100644 index 0000000..fd2af8e --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/README.txt @@ -0,0 +1,142 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +This directory contains a simple example application that demonstrates the +ConfiguredUniverse utility class available in the com.sun.j3d.utils.universe +package. J3DFly, available separately, is a fully featured application that +also uses ConfiguredUniverse. + +ConfiguredUniverse is an extension of SimpleUniverse that can set up an +interactive viewing environment based upon the contents of a site-specific +configuration file. This is useful when an application needs to run without +change across a broad range of viewing configurations and locally available +input and audio devices. InputDevice implementations can be instantiated by +ConfiguredUniverse and their Sensors can be retrieved by applications along +with the names bound to them in the configuration file. + +Supported viewing configurations include windows on conventional desktops, +stereo-enabled views, fullscreen immersive displays on single or multiple +screens, and virtual reality installations such as cave and head-mounted +displays incorporating 6-degree-of-freedom sensor devices. + +The ConfigObjLoad application is a modified version of the ObjLoad example +program which uses the ConfiguredUniverse utility instead of SimpleUniverse. +It also differs in the following other respects: + + It is an application and cannot be run in a browser. ConfiguredUniverse + creates a JFrame, JPanel, and Canvas3D itself for each screen and is + oriented towards multiple fullscreen viewing environments, although + conventional windowed displays are also supported. The components + created are easily accessable so applications can still incorporate them + into their own user interfaces. + + The configuration file to load is specified by the j3d.configURL + property. If one is not specified, it will load the file j3d1x1-window + in this directory. + + Alternative custom view platform behaviors other than OrbitBehavior can + be used by specifying the behavior in the configuration file. + + It can retrieve a 6DOF Sensor specified in the configuration file and + use it to demonstrate the Mouse6DPointerBehavior class. + + Typing a "q" or the Escape key will terminate the example program. This + is useful for fullscreen configurations. + +To load a specific configuration file, set the j3d.configURL property on the +command line: + + java -Dj3d.configURL= ConfigObjLoad + +For example, to load j3d1x2-rot30 in the current directory, run + + java -Dj3d.configURL=file:j3d1x2-rot30 ConfigObjLoad + +This directory includes the following sample configuration files. Normally +a configuration file is site-specific but many of these can used as-is. +Others may need customization for screen sizes, available input devices, and +PhysicalBody parameters. + + j3d1x1: single fullscreen desktop configuration. + + j3d1x1-behavior: single fullscreen desktop configuration with a + configurable view platform behavior. + + j3d1x1-stereo: single fullscreen desktop configuration with stereo + viewing. + + j3d1x1-vr: single fullscreen desktop configuration with stereo viewing, + head tracker, and 6DOF mouse. + + j3d1x1-window: single screen windowed desktop configuration. + + j3d1x2-flat: dual-screen flat desktop configuration. + + j3d1x2-rot30: dual-screen desktop configuration with each screen rotated + toward the other by 30 degrees about Y. + + j3d1x3-cave: 3-projector configuration with screens to the left, front, + and right of the user. + + j3d1x3-cave-vr: 3-projector configuration with screens to the left, + front, and right of the user. Includes head tracking and stereo + viewing. + + j3d1x3-rot45: 3-screen desktop configuration with left and right screens + angled by 45 degrees from the center screen. + + j3d2x2-flat: 4-screen projector configuration arranged in a 2x2 power + wall. + +Note: JDK 1.4 or newer is required when configuring multiple screens if the +X11 Xinerama extension is being used to create a single virtual screen. +This is due to a limitation of the getScreenDevices() method in the JDK 1.3 +version of GraphicsConfiguration which returns only a single GraphicsDevice +from a virtual screen. ConfiguredUniverse will report this condition as an +error in specifying more screens than are available. + +Also: Graphics performance may be degraded in some environments when using a +virtual screen device. See the description of the j3d.disableXinerama +property for possible performance improvements when using Xinerama. + diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1 b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1 new file mode 100644 index 0000000..41173e3 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1 @@ -0,0 +1,98 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for a single fullscreen desktop configuration. + * + ************************************************************************ + */ + +// Create a new screen object and associate it with a logical name and a +// number. This number is used as an index to retrieve the AWT GraphicsDevice +// from the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen center 0) + +// Create a fullscreen window +// +(ScreenAttribute center WindowSize NoBorderFullScreen) + +// Set the available image area for the full screen. This is important when an +// explicit ScreenScale view attribute is defined for precise scaling between +// objects in the virtual world and their projections into the physical world. +// The defaults are 0.365 meters for width and 0.292 meters for height. +// +(ScreenAttribute center PhysicalScreenWidth 0.360) +(ScreenAttribute center PhysicalScreenHeight 0.288) + +// Set the TrackerBaseToImagePlate transform for this screen. The coexistence +// to tracker base transform is identity by default, so the tracker base origin +// and orientation will also set the origin and orientation of coexistence +// coordinates in the physical world. This is the primary purpose of setting +// this transform when neither head tracking nor multiple screens are being +// used. +// +// The tracker base and center of coexistence are set here to the middle of the +// screen's image plate. Their basis vectors are aligned with the image plate +// basis vectors. The physical eyepoint position will be set relative to +// coexistence coordinates below. +// +(ScreenAttribute center TrackerBaseToImagePlate + (Translate 0.180 0.144 0.000)) + +// Create a view using the defined screen. +// +(NewView view0) +(ViewAttribute view0 Screen center) + +// Set the eyepoint relative to coexistence coordinates. Here it is set 45cm +// toward the user along +Z. Skewed projections can be created by offsetting +// the eyepoint along X and/or Y. +// +(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45)) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior new file mode 100644 index 0000000..d291913 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-behavior @@ -0,0 +1,149 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for single fullscreen desktop configuration. + * A view platform behavior is created and configured here as well. + * + ************************************************************************ + */ + +// Create a new screen object and associate it with a logical name and a +// number. This number is used as an index to retrieve the AWT GraphicsDevice +// from the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen center 0) + +// Create a fullscreen window +// +(ScreenAttribute center WindowSize NoBorderFullScreen) + +// Set the available image area for the full screen. +// +(ScreenAttribute center PhysicalScreenWidth 0.360) +(ScreenAttribute center PhysicalScreenHeight 0.288) + +// Set the TrackerBaseToImagePlate transform for this screen. The coexistence +// to tracker base transform is identity by default, so the tracker base origin +// and orientation will also set the origin and orientation of coexistence +// coordinates in the physical world. This is the primary purpose of setting +// this transform when neither head tracking nor multiple screens are being +// used. +// +// The tracker base and center of coexistence are set here to the middle of the +// screen's image plate. Their basis vectors are aligned with the image plate +// basis vectors. The physical eyepoint position will be set relative to +// coexistence coordinates below. +// +(ScreenAttribute center TrackerBaseToImagePlate + (Translate 0.180 0.144 0.000)) + +// Create a view using the defined screen. +// +(NewView view0) +(ViewAttribute view0 Screen center) + +// Set the eyepoint relative to coexistence coordinates. Here it is set 45cm +// toward the user along +Z. Skewed projections can be set by by offsetting +// the eyepoint along X and Y. +// +(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45)) + +// Create a view platform behavior. Here we use OrbitBehavior, although any +// concrete subclass of the abstract ViewPlatformBehavior with a parameterless +// constructor could be used. The logical name to assign to this behavior is +// specified by the 2nd argument to the NewViewPlatformBehavior command, while +// the 3rd argument is the name of the ViewPlatformBehavior subclass. It is +// instantiated through introspection. +// +// Attributes defined by the abstract ViewPlatformBehavior superclass itself +// can be set directly with the ViewPlatformBehaviorAttribute command. The +// details of the subclass implementation are not known to ConfiguredUniverse, +// so any configuration information needed by such a subclass is set by the +// ViewPlatformBehaviorProperty command. The property name specified by that +// command is taken to be a method name of the subclass and invoked through +// introspection. +// +// View platform behaviors often need sensors or canvases as event sources to +// drive the behavior action. An implementation of ViewPlatformBehavior always +// gets the current ViewingPlatform through the setViewingPlatform() method. +// The canvases used by the ViewingPlatform can be retrieved by calling its +// getViewers() method and then calling each Viewer's getCanvas3Ds() +// method. Sensors can be retrived by calling the ViewingPlatform method +// getUniverse(), checking to see if the returned SimpleUniverse is a +// ConfiguredUniverse, and then calling its getNamedSensors() method. +// +(NewViewPlatformBehavior vpb com.sun.j3d.utils.behaviors.vp.OrbitBehavior) + +// Set the scheduling bounds to be a BoundingSphere with its center at +// (0.0 0.0 0.0) and a radius of 100 meters. +// +(ViewPlatformBehaviorAttribute vpb SchedulingBounds + (BoundingSphere (0.0 0.0 0.0) 100.0)) + +// Set properties specific to OrbitBehavior. All arguments following the +// method name are wrapped and passed to the specified method as an array of +// Objects. Strings "true" and "false" get turned into Boolean, and number +// strings get turned into Double. Constructs such as (0.0 1.0 2.0) and +// ((0.0 1.0 2.0 0.5) (3.0 4.0 5.0 1.0) (6.0 7.0 8.0 0.0)) get converted to +// Point3d and Matrix4d respectively. Note that last row of a Matrix4d doesn't +// need to be specified; it is implicitly (0.0 0.0 0.0 1.0). +// +// The REVERSE_ALL flags are usually passed to the OrbitBehavior constructor. +// Since it is being instantiated with its parameterless constructor the +// reverse flags are set here explicitly. +// +(ViewPlatformBehaviorProperty vpb ReverseTranslate true) +(ViewPlatformBehaviorProperty vpb ReverseRotate true) +(ViewPlatformBehaviorProperty vpb ReverseZoom true) + +// Create a new view platform and set the view platform behavior. +// +(NewViewPlatform vp) +(ViewPlatformAttribute vp ViewPlatformBehavior vpb) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo new file mode 100644 index 0000000..3db4070 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-stereo @@ -0,0 +1,113 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for single fullscreen stereo desktop + * configuration with no head tracking. + * + ************************************************************************ + */ + +// Create a new screen object and associate it with a logical name and a +// number. This number is used as an index to retrieve the AWT GraphicsDevice +// from the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen center 0) + +// Create a fullscreen window +// +(ScreenAttribute center WindowSize NoBorderFullScreen) + +// Set the available image area for the full screen. +// +(ScreenAttribute center PhysicalScreenWidth 0.360) +(ScreenAttribute center PhysicalScreenHeight 0.288) + +// Set the TrackerBaseToImagePlate transform for this screen. The coexistence +// to tracker base transform is identity by default, so the tracker base origin +// and orientation will also set the origin and orientation of coexistence +// coordinates in the physical world. This is the primary purpose of setting +// this transform when neither head tracking nor multiple screens are being +// used. +// +// The tracker base and center of coexistence are set here to the middle of the +// screen's image plate. Their basis vectors are aligned with the image plate +// basis vectors. The physical eyepoint position will be set relative to +// coexistence coordinates below. +// +(ScreenAttribute center TrackerBaseToImagePlate + (Translate 0.180 0.144 0.000)) + +// Define the physical body. +// +// The head origin is halfway between the eyes, with X extending to the right, +// Y up, and positive Z extending into the skull. +// +(NewPhysicalBody SiteUser) + +// Set the interpupilary distance. This sets the LeftEyePosition and +// RightEyePosition to offsets of half this distance along both directions of +// the X axis. +// +(PhysicalBodyAttribute SiteUser StereoEyeSeparation 0.066) + +// Create a view using the defined screen and physical body. +// +(NewView view0) +(ViewAttribute view0 Screen center) +(ViewAttribute view0 PhysicalBody SiteUser) + +// Set the eyepoint relative to coexistence coordinates. Here it is set 45cm +// toward the user along +Z. +// +(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45)) + +// Enable stereo viewing. +// +(ViewAttribute view0 StereoEnable true) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr new file mode 100644 index 0000000..587f481 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-vr @@ -0,0 +1,212 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for a single screen stereo desktop display + * using a head tracker and 6DOF mouse. + * + ************************************************************************ + */ + +// Configure the head tracker. The NewDevice command binds a logical name +// (the 2nd argument) to an InputDevice implementation whose class name is +// specified in the 3rd argument. The InputDevice implementation for a head +// tracker must generate position and orientation data relative to a fixed +// frame of reference in the physical world, the "tracker base" of the Java +// 3D view model. +// +// The InputDevice is instantiated through introspection of the class name. +// Available InputDevice implementations are site-specific, so substitute +// the class name in a NewDevice command below with one that is available at +// the local site. +// +// Note that properties are used to configure an InputDevice instead of +// attributes. The details of an InputDevice implementation are not known to +// ConfiguredUniverse, so the property name is invoked as a method through +// introspection. The example properties below must be replaced with the ones +// needed, if any, by specific InputDevice implementations. +// +// All property arguments following the method name are wrapped and passed to +// the specified method as an array of Objects. Strings "true" and "false" +// get wrapped into Boolean, and number strings get wrapped into Double. +// Construct such as (0.0 1.0 2.0) and ((0.0 1.0 2.0 0.5) (3.0 4.0 5.0 1.0) +// (6.0 7.0 8.0 0.0)) get converted to Point3d and Matrix4d respectively. +// Note that last row of a Matrix4d doesn't need to be specified; it is +// implicitly (0.0 0.0 0.0 1.0). +// +(NewDevice glasses LogitechRedBarron) +(DeviceProperty glasses SerialPort "/dev/ttya") // Unix paths need quoting. +(DeviceProperty glasses ReceiverBaseline 0.1450) +(DeviceProperty glasses ReceiverLeftLeg 0.0875) +(DeviceProperty glasses ReceiverHeight 0.0470) +(DeviceProperty glasses ReceiverTopOffset 0.0000) + +// Configure an InputDevice to use for a 6 degree of freedom mouse if +// required. In some implementations the same InputDevice instance can be +// used both for head tracking and multiple peripheral sensing devices. +// This example assumes an implementation that requires multiple instances, +// one for each sensor, sharing the same physical hardware used for the +// tracker base. In either case all the sensors must generate position and +// orientation relative to the same fixed tracker base frame of reference. +// +(NewDevice wand LogitechRedBarron) +(DeviceProperty wand SerialPort "/dev/ttyb") +(DeviceProperty wand ReceiverBaseline 0.0700) +(DeviceProperty wand ReceiverLeftLeg 0.0625) +(DeviceProperty wand ReceiverHeight 0.0510) +(DeviceProperty wand ReceiverTopOffset 0.0000) + +// Create logical names for the available sensors in the specified input +// devices. The last argument is the sensor's index in the input device. +// +(NewSensor head glasses 0) +(NewSensor mouse6d wand 0) + +// Set the 6DOF mouse sensor hotspot in the local sensor coordinate system. +// The hotspot is simply the "active" point relative to the sensor origin +// which interacts with the virtual world, such as the point used for picking +// or grabbing an object. Its interpretation is up to the sensor behavior. +// +// It is set here to 10 centimeters from the base to allow reaching into the +// screen without bumping the device into the glass, and to prevent the device +// itself from obscuring the pointer echo. +// +(SensorAttribute mouse6d Hotspot (0.0 0.0 -0.10)) + + +// Create a new screen object and associate it with a logical name and a +// number. This number is used as an index to retrieve the AWT GraphicsDevice +// from the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen center 0) + +// Set the actual available image area. This measured as 0.350 meters in +// width and 0.245 meters in height for the monitor in the sample setup when +// running in stereo resolution. +// +(ScreenAttribute center PhysicalScreenWidth 0.350) +(ScreenAttribute center PhysicalScreenHeight 0.245) +(ScreenAttribute center WindowSize NoBorderFullScreen) + +// Set the TrackerBaseToImagePlate transform for this screen. This transforms +// points in tracker base coordinates to image plate coordinates. +// +// For this sample setup the tracker base is leaning at 50 degrees about its +// X-axis over the top edge of the monitor. The middle of the tracker base +// (its origin) is offset by (0.175, 0.345, 0.020) from the lower left +// corner of the screen (origin of the image plate). +// +(ScreenAttribute center TrackerBaseToImagePlate + (RotateTranslate (Rotate 50.000 0.000 0.000) + (Translate 0.175 0.345 0.020))) + + +// Create a physical environment. This contains the available input devices, +// audio devices, and sensors, and defines the coexistence coordinate system. +// +(NewPhysicalEnvironment SampleSite) + +// Register the input devices defined in this file. +// +(PhysicalEnvironmentAttribute SampleSite InputDevice glasses) +(PhysicalEnvironmentAttribute SampleSite InputDevice wand) + +// Register the sensor which will drive head tracking. +// +(PhysicalEnvironmentAttribute SampleSite HeadTracker head) + +// Define coexistence coordinates. +// +// Coexistence coordinates are defined relative to the tracker base to simplify +// calibration measurements, just as the tracker base is used as the common +// reference frame for the TrackerBaseToImagePlate calibration. +// +// Here the coexistence origin is set to the middle of the center screen, using +// the same basis vectors as its image plate. This will put the tracker base +// origin at (0.0 0.220 0.020) relative to the coexistence origin along its +// basis vectors. +// +(PhysicalEnvironmentAttribute SampleSite CoexistenceToTrackerBase + (TranslateRotate (Translate 0.0 -0.220 -0.020) + (Rotate -50.0 0.0 0.0))) + +// Define the physical body. +// +// The head origin is halfway between the eyes, with X extending to the right, +// Y up, and positive Z extending into the skull. +// +(NewPhysicalBody SiteUser) + +// Set the interpupilary distance. This sets the LeftEyePosition and +// RightEyePosition to offsets of half this distance along both directions of +// the X axis. +// +(PhysicalBodyAttribute SiteUser StereoEyeSeparation 0.066) + +// Define the position and orientation of the head relative to the tracker +// mounted on the head. +// +(PhysicalBodyAttribute SiteUser HeadToHeadTracker ((1.0 0.0 0.0 0.000) + (0.0 1.0 0.0 0.020) + (0.0 0.0 1.0 0.018))) + + +// Create a view using the defined screens, PhysicalEnvironment, and +// PhysicalBody. +// +(NewView view0) +(ViewAttribute view0 Screen center) +(ViewAttribute view0 PhysicalEnvironment SampleSite) +(ViewAttribute view0 PhysicalBody SiteUser) + +// Enable stereo viewing. Enable head tracking to get the position of the eyes +// with respect to coexistence. +// +(ViewAttribute view0 StereoEnable true) +(ViewAttribute view0 TrackingEnable True) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window new file mode 100644 index 0000000..eec0e31 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x1-window @@ -0,0 +1,89 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for a conventional single screen, windowed + * desktop configuration. + * + ************************************************************************ + */ + +// Create a new screen object and associate it with a logical name and a +// number. This number is used as an index to retrieve the AWT GraphicsDevice +// from the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen center 0) + +// Create a 700x700 pixel window on the screen. +// +(ScreenAttribute center WindowSize (700.0 700.0)) + +// Create a view using the defined screen. +// +(NewView view0) +(ViewAttribute view0 Screen center) + +// ConfiguredUniverse is oriented toward multi-screen viewing environments, so +// it sets the following attributes to those listed. For a conventional window +// on a single screen desktop configuration we need to set them back to their +// normal defaults. +// +// View.windowEyePointPolicy RELATIVE_TO_COEXISTENCE +// View.windowMovementPolicy VIRTUAL_WORLD +// View.windowResizePolicy VIRTUAL_WORLD +// View.coexistenceCenteringEnable false +// ViewPlatform.viewAttachPolicy NOMINAL_SCREEN +// +(ViewAttribute view0 WindowEyepointPolicy RELATIVE_TO_FIELD_OF_VIEW) +(ViewAttribute view0 WindowMovementPolicy PHYSICAL_WORLD) +(ViewAttribute view0 WindowResizePolicy PHYSICAL_WORLD) +(ViewAttribute view0 CoexistenceCenteringEnable true) + +(NewViewPlatform vp) +(ViewPlatformAttribute vp ViewAttachPolicy NOMINAL_HEAD) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat new file mode 100644 index 0000000..667ea52 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-flat @@ -0,0 +1,134 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for dual-screen (flat) desktop configuration + * with no head tracking. + * + ************************************************************************ + */ + +// Create new screen objects and associate them with logical names and numbers. +// These numbers are used as indices to retrieve the AWT GraphicsDevice from +// the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen left 0) +(NewScreen right 1) + +// Set the screen dimensions. +// +(ScreenAttribute left PhysicalScreenWidth 0.360) +(ScreenAttribute left PhysicalScreenHeight 0.288) + +(ScreenAttribute right PhysicalScreenWidth 0.360) +(ScreenAttribute right PhysicalScreenHeight 0.288) + +// Specify full screen windows. +// +(ScreenAttribute left WindowSize NoBorderFullScreen) +(ScreenAttribute right WindowSize NoBorderFullScreen) + +// Set the TrackerBaseToImagePlate transforms for these screens. This +// transforms points in tracker base coordinates to each screen's image plate +// coordinates, where the origin of the image plate is defined to be the lower +// left corner of the screen with X increasing to the right, Y increasing to +// the top, and Z increasing away from the screen. +// +// Without head or sensor tracking the tracker base is still needed as a fixed +// frame of reference for describing the orientation and position of each +// screen to the others. The coexistence to tracker base transform is set to +// identity by default, so the tracker base origin and orientation will also +// set the origin and orientation of coexistence coordinates in the physical +// world. +// +// The tracker base and center of coexistence is set here to the middle of the +// edge shared by the two screens. +// +(ScreenAttribute left TrackerBaseToImagePlate + (Translate 0.360 0.144 0.0)) +(ScreenAttribute right TrackerBaseToImagePlate + (Translate 0.000 0.144 0.0)) + +// Sometimes it is desirable to include the bevels in between the monitors in +// the TrackerBaseToImagePlate transforms, so that the abutting bevels obscure +// the view of the virtual world instead of stretching it out between the +// monitors. For a bevel width of 4.5 cm on each monitor, the above commands +// would become the following: +// +// (ScreenAttribute left TrackerBaseToImagePlate +// (Translate 0.405 0.144 0.0)) +// (ScreenAttribute right TrackerBaseToImagePlate +// (Translate -0.045 0.144 0.0)) +// +// Conversely, a similar technique may be used to include overlap between the +// screens. This is useful for projection systems which use edge blending +// to provide seamless integration between screens. + + +// Create a view using the defined screens. +// +(NewView view0) +(ViewAttribute view0 Screen left) +(ViewAttribute view0 Screen right) + +// Set the eyepoint relative to coexistence coordinates. Here it is set 45cm +// toward the user along Z, extending out from the midpoint of the edge shared +// by the two screens. This will create the appropriate skewed projection +// frustums for each image plate. +// +// If a planar display surface is all that is required, the same effect could +// be achieved in a virtual screen enviroment such as Xinerama by simply +// creating a canvas that spans both screens. In some display environments the +// use of a canvas that spans multiple physical screens may cause significant +// performance degradation, however. +// +// See j3d1x2-rot30 for an example of a non-planar configuration that cannot be +// achieved through a single canvas spanning both screens. +// +(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45)) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30 b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30 new file mode 100644 index 0000000..68f4a6e --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x2-rot30 @@ -0,0 +1,99 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for a dual-screen desktop configuration + * with each screen rotated toward the other by 30 degrees about Y from + * planar. The inside angle between them is 120 degrees. + * + ************************************************************************ + */ + +// Create new screen objects and associate them with logical names and numbers. +// These numbers are used as indices to retrieve the AWT GraphicsDevice from +// the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen left 0) +(NewScreen right 1) + +// Set the available image areas for full screens. +// +(ScreenAttribute left PhysicalScreenWidth 0.360) +(ScreenAttribute left PhysicalScreenHeight 0.288) + +(ScreenAttribute right PhysicalScreenWidth 0.360) +(ScreenAttribute right PhysicalScreenHeight 0.288) + +// Specify full screen windows. +// +(ScreenAttribute left WindowSize NoBorderFullScreen) +(ScreenAttribute right WindowSize NoBorderFullScreen) + +// Set the TrackerBaseToImagePlate transforms for these screens. +// +// The tracker base is set here to the middle of the edge shared by the two +// screens. Each screen is rotated 30 degrees toward the other about the +// tracker base +Y axis, so that the tracker base +Z is centered between the +// two screens. +// +(ScreenAttribute left TrackerBaseToImagePlate + (RotateTranslate (Rotate 0.000 -30.000 0.0) + (Translate 0.360 0.144 0.0))) + +(ScreenAttribute right TrackerBaseToImagePlate + (RotateTranslate (Rotate 0.000 30.000 0.0) + (Translate 0.000 0.144 0.0))) + + +// Create a view using the defined screens. +// +(NewView view0) +(ViewAttribute view0 Screen left) +(ViewAttribute view0 Screen right) +(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.45)) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave new file mode 100644 index 0000000..afc532c --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave @@ -0,0 +1,171 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for a cave environment. This cave + * consists of 3 projectors with 3 screens to the left, front, and right + * of the user, all at 90 degrees to each other. + * + * The projectors in the VirtualPortal sample site are actually turned + * on their sides to get more height. Screen 0 is rotated 90 degrees + * counter-clockwise, while screens 1 and 2 are rotated 90 degrees + * clockwise. + * + ************************************************************************ + */ + +// Create new screen objects and associate them with logical names and numbers. +// These numbers are used as indices to retrieve the AWT GraphicsDevice from +// the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen left 0) +(NewScreen center 1) +(NewScreen right 2) + + +// Set the available image areas as well as their positition and orientation +// relative to the tracker base. Although this config file doesn't enable +// head tracking, the tracker base is still needed as a point of reference to +// describe the position and orientation of the screens relative to the +// environment. +// +// From the orientation of a user standing within this VirtualPortal site and +// facing the center screen, the tracker base is along the vertical midline of +// the screen, 0.248 meters down from the top edge, and 1.340 meters in front +// of it. The tracker base is oriented so that its +X axis points to the left, +// its +Y axis points toward the screen, and its +Z axis points toward the +// floor. +// +(ScreenAttribute left PhysicalScreenWidth 2.480) +(ScreenAttribute left PhysicalScreenHeight 1.705) +(ScreenAttribute left WindowSize NoBorderFullScreen) +(ScreenAttribute left TrackerBaseToImagePlate + (( 0.0 0.0 -1.0 2.230) + ( 0.0 -1.0 0.0 1.340) + (-1.0 0.0 0.0 0.885))) + +(ScreenAttribute center PhysicalScreenWidth 2.485) +(ScreenAttribute center PhysicalScreenHeight 1.745) +(ScreenAttribute center WindowSize NoBorderFullScreen) +(ScreenAttribute center TrackerBaseToImagePlate + (( 0.0 0.0 1.0 0.248) + (-1.0 0.0 0.0 0.885) + ( 0.0 -1.0 0.0 1.340))) + +(ScreenAttribute right PhysicalScreenWidth 2.480) +(ScreenAttribute right PhysicalScreenHeight 1.775) +(ScreenAttribute right WindowSize NoBorderFullScreen) +(ScreenAttribute right TrackerBaseToImagePlate + (( 0.0 0.0 1.0 0.2488) + ( 0.0 -1.0 0.0 1.340) + ( 1.0 0.0 0.0 0.860))) + +// Set the location of the center of coexistence relative to the tracker base. +// Here it set to the center of the center screen. This config file will set +// the location of the user's eyes relative to this point. The default view +// attach policy of NOMINAL_SCREEN used by ConfiguredUniverse will place the +// origin of the view platform in coexistence coordinates at the center of +// coexistence. +// +(NewPhysicalEnvironment VirtualPortal) +(PhysicalEnvironmentAttribute VirtualPortal + CoexistenceToTrackerBase + ((-1.0 0.0 0.0 0.000) + ( 0.0 0.0 -1.0 1.340) + ( 0.0 -1.0 0.0 0.994))) + +// The above center of coexistence is appropriate for the sample geometry +// files available in the programs/examples directory. Often a more +// immersive point of view is required for larger virtual worlds. This can be +// achieved by placing the center of coexistence closer to the nominal position +// of the user's head, so that the view platform origin in coexistence +// coordinates will map there as well. +// +// Here we set the location of the center of coexistence 0.5 meters along the +// tracker base +Z axis, 1.737 meters from the floor (about 5 ft 8.4 inches). +// +// (PhysicalEnvironmentAttribute VirtualPortal +// CoexistenceToTrackerBase +// ((-1.0 0.0 0.0 0.0) +// ( 0.0 0.0 -1.0 0.0) +// ( 0.0 -1.0 0.0 0.5))) + + +// Now define the view. +// +(NewView view0) +(ViewAttribute view0 Screen left) +(ViewAttribute view0 Screen center) +(ViewAttribute view0 Screen right) +(ViewAttribute view0 PhysicalEnvironment VirtualPortal) + +// Set the user eye position in the display environment. It is set here to +// 1.340 meters back from the center screen (directly under the tracker), and +// 1.737 meters from the floor (about 5 ft 8.4 inches). +// +(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.494 1.340)) + +// Here is an alternative center eye position to use with the immersive +// coexistence coordinate system defined in comments above. +// +// (ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.0)) + +// Set the screen scale. This is scale factor from virtual to physical +// coordinates. +// +(ViewAttribute view0 ScreenScalePolicy SCALE_SCREEN_SIZE) + +// Alternative for explict scaling. +// +// (ViewAttribute view0 ScreenScalePolicy SCALE_EXPLICIT) +// (ViewAttribute view0 ScreenScale 5.00) + +// No stereo viewing for this configuration. +// +(ViewAttribute view0 StereoEnable False) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr new file mode 100644 index 0000000..029decf --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-cave-vr @@ -0,0 +1,222 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for a cave environment with head tracking and + * stereo viewing. This cave consists of 3 projectors with 3 screens to the + * left, front, and right of the user, all at 90 degrees to each other. + * + * The projectors in the VirtualPortal sample site are actually turned + * on their sides to get more height. Screen 0 is rotated 90 degrees + * counter-clockwise, while screens 1 and 2 are rotated 90 degrees + * clockwise. + * + ************************************************************************ + */ + +// Configure the head tracker. The NewDevice command binds a logical name +// (the 2nd argument) to an InputDevice implementation whose class name is +// specified in the 3rd argument. The InputDevice implementation for a head +// tracker must generate position and orientation data relative to a fixed +// frame of reference in the physical world, the "tracker base" of the Java +// 3D view model. +// +// The InputDevice is instantiated through introspection of the class name. +// Available InputDevice implementations are site-specific, so substitute +// the class name in a NewDevice command below with one that is available at +// the local site. +// +// Note that properties are used to configure an InputDevice instead of +// attributes. The details of an InputDevice implementation are not known to +// ConfiguredUniverse, so the property name is invoked as a method through +// introspection. The example properties below must be replaced with the ones +// needed, if any, by specific InputDevice implementations. All arguments +// following the method name are wrapped and passed to the specified method as +// an array of Objects. +// +// All property arguments following the method name are wrapped and passed to +// the specified method as an array of Objects. Strings "true" and "false" +// get wrapped into Boolean, and number strings get wrapped into Double. +// Construct such as (0.0 1.0 2.0) and ((0.0 1.0 2.0 0.5) (3.0 4.0 5.0 1.0) +// (6.0 7.0 8.0 0.0)) get converted to Point3d and Matrix4d respectively. +// Note that last row of a Matrix4d doesn't need to be specified; it is +// implicitly (0.0 0.0 0.0 1.0). +// +(NewDevice glasses LogitechRedBarron) +(DeviceProperty glasses SerialPort "/dev/ttya") // Unix paths need quoting. +(DeviceProperty glasses TransmitterBaseline 0.4600) +(DeviceProperty glasses TransmitterLeftLeg 0.4400) +(DeviceProperty glasses TransmitterCalibrationDistance 0.4120) + +// Create a logical name for the head tracker sensor. The last argument is +// the sensor's index in the input device. +// +(NewSensor head glasses 0) + +// Create new screen objects and associate them with logical names and numbers. +// These numbers are used as indices to retrieve the AWT GraphicsDevice from +// the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen left 0) +(NewScreen center 1) +(NewScreen right 2) + + +// Set the available image areas as well as their positition and orientation +// relative to the tracker base. From the orientation of a user standing +// within this VirtualPortal site and facing the center screen, the tracker +// base is along the vertical midline of the screen, 0.248 meters down from +// the top edge, and 1.340 meters in front of it. The tracker base is +// oriented so that its +X axis points to the left, its +Y axis points toward +// the screen, and its +Z axis points toward the floor. +// +(ScreenAttribute left PhysicalScreenWidth 2.480) +(ScreenAttribute left PhysicalScreenHeight 1.705) +(ScreenAttribute left WindowSize NoBorderFullScreen) +(ScreenAttribute left TrackerBaseToImagePlate + (( 0.0 0.0 -1.0 2.230) + ( 0.0 -1.0 0.0 1.340) + (-1.0 0.0 0.0 0.885))) + +(ScreenAttribute center PhysicalScreenWidth 2.485) +(ScreenAttribute center PhysicalScreenHeight 1.745) +(ScreenAttribute center WindowSize NoBorderFullScreen) +(ScreenAttribute center TrackerBaseToImagePlate + (( 0.0 0.0 1.0 0.248) + (-1.0 0.0 0.0 0.885) + ( 0.0 -1.0 0.0 1.340))) + +(ScreenAttribute right PhysicalScreenWidth 2.480) +(ScreenAttribute right PhysicalScreenHeight 1.775) +(ScreenAttribute right WindowSize NoBorderFullScreen) +(ScreenAttribute right TrackerBaseToImagePlate + (( 0.0 0.0 1.0 0.2488) + ( 0.0 -1.0 0.0 1.340) + ( 1.0 0.0 0.0 0.860))) + +// Create a physical environment. This contains the available input devices, +// audio devices, and sensors, and defines the coexistence coordinate system +// for mapping between the virtual and physical worlds. +// +(NewPhysicalEnvironment VirtualPortal) + +// Register the input device defined in this file and the sensor which will +// drive head tracking. +// +(PhysicalEnvironmentAttribute VirtualPortal InputDevice glasses) +(PhysicalEnvironmentAttribute VirtualPortal HeadTracker head) + +// Set the location of the center of coexistence relative to the tracker base. +// Here it set to the center of the center screen. The default view attach +// policy of NOMINAL_SCREEN used by ConfiguredUniverse will place the origin of +// the view platform in coexistence coordinates at the center of coexistence. +// +(PhysicalEnvironmentAttribute VirtualPortal + CoexistenceToTrackerBase + ((-1.0 0.0 0.0 0.000) + ( 0.0 0.0 -1.0 1.340) + ( 0.0 -1.0 0.0 0.994))) + +// The above center of coexistence is appropriate for the sample geometry +// files available in the programs/examples directory. Often a more +// immersive point of view is required for larger virtual worlds. This can be +// achieved by placing the center of coexistence closer to the nominal position +// of the user's head, so that the view platform origin in coexistence +// coordinates will map there as well. +// +// Here we set the location of the center of coexistence 0.5 meters along the +// tracker base +Z axis, 1.737 meters from the floor (about 5 ft 8.4 inches). +// +// (PhysicalEnvironmentAttribute VirtualPortal +// CoexistenceToTrackerBase +// ((-1.0 0.0 0.0 0.0) +// ( 0.0 0.0 -1.0 0.0) +// ( 0.0 -1.0 0.0 0.5))) + + +// Define the physical body. +// +// The head origin is halfway between the eyes, with X extending to the right, +// Y up, and positive Z extending into the skull. +// +(NewPhysicalBody LabRat) +(PhysicalBodyAttribute LabRat StereoEyeSeparation .07) + +// Define the position and orientation of the head relative to the tracker +// mounted on the head. +// +(PhysicalBodyAttribute LabRat HeadToHeadTracker + ((-1.0 0.0 0.0 0.00) + ( 0.0 0.0 -1.0 0.05) + ( 0.0 -1.0 0.0 0.11))) +// Now define the view. +// +(NewView view0) +(ViewAttribute view0 Screen left) +(ViewAttribute view0 Screen center) +(ViewAttribute view0 Screen right) +(ViewAttribute view0 PhysicalBody LabRat) +(ViewAttribute view0 PhysicalEnvironment VirtualPortal) + +// Set the screen scale. This is scale factor from virtual to physical +// coordinates. +// +(ViewAttribute view0 ScreenScalePolicy SCALE_SCREEN_SIZE) + +// Alternative for explict scaling. +// +//(ViewAttribute view0 ScreenScalePolicy SCALE_EXPLICIT) +//(ViewAttribute view0 ScreenScale 5.00) + +// Enable stereo viewing. Enable head tracking to get the position of the eyes +// with respect to coexistence. Boolean values may be specified as either +// true, True, false, or False. +// +(ViewAttribute view0 StereoEnable true) +(ViewAttribute view0 TrackingEnable True) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45 b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45 new file mode 100644 index 0000000..d221e74 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d1x3-rot45 @@ -0,0 +1,110 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for 3 screens. Left and right screens are + * rotated 45 degrees from the center screen. + * + ************************************************************************ + */ + +// Create new screen objects and associate them with logical names and numbers. +// These numbers are used as indices to retrieve the AWT GraphicsDevice from +// the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen left 0) +(NewScreen center 1) +(NewScreen right 2) + +// Set the available image areas for full screens. +// +(ScreenAttribute left PhysicalScreenWidth 0.360) +(ScreenAttribute left PhysicalScreenHeight 0.288) + +(ScreenAttribute center PhysicalScreenWidth 0.360) +(ScreenAttribute center PhysicalScreenHeight 0.288) + +(ScreenAttribute right PhysicalScreenWidth 0.360) +(ScreenAttribute right PhysicalScreenHeight 0.288) + +// Specify full screen windows. +// +(ScreenAttribute left WindowSize NoBorderFullScreen) +(ScreenAttribute center WindowSize NoBorderFullScreen) +(ScreenAttribute right WindowSize NoBorderFullScreen) + +// Set the TrackerBaseToImagePlate transforms for these screens. +// +// The tracker base and center of coexistence are set here to the middle of the +// center screen. The basis vectors are aligned with the center screen image +// plate. The left and right screens are rotated 45 degrees toward each other +// about their shared edges with the center screen. +// +(ScreenAttribute center TrackerBaseToImagePlate + (Translate 0.180000 0.144000 0.000000)) + +// cos(45) * 0.360 * 0.5 = 0.127279; 0.360 + 0.127279 = 0.487279 +(ScreenAttribute left TrackerBaseToImagePlate + (RotateTranslate + (Rotate 0.000000 -45.000000 0.000000) + (Translate 0.487279 0.144000 0.127279))) + +// cos(45) * 0.360 * 0.5 = 0.127279 +(ScreenAttribute right TrackerBaseToImagePlate + (RotateTranslate + (Rotate 0.000000 45.000000 0.000000) + (Translate -0.127279 0.144000 0.127279))) + +// Create a view using the defined screens. +// +(NewView view0) +(ViewAttribute view0 Screen left) +(ViewAttribute view0 Screen center) +(ViewAttribute view0 Screen right) +(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 0.5)) diff --git a/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat new file mode 100644 index 0000000..46df9a3 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/configured_universe/j3d2x2-flat @@ -0,0 +1,135 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +/* + ************************************************************************ + * + * Java 3D configuration file for 4 screen projection configuration + * arranged in a 2x2 power wall. + * + ************************************************************************ + */ + +// Create new screen objects and associate them with logical names and numbers. +// These numbers are used as indices to retrieve the AWT GraphicsDevice from +// the array that GraphicsEnvironment.getScreenDevices() returns. +// +// NOTE: The GraphicsDevice order in the array is specific to the local +// site and display system. +// +(NewScreen topleft 0) +(NewScreen topright 1) +(NewScreen bottomleft 3) +(NewScreen bottomright 2) + +// Set the available image areas for full screens. This is important when +// precise scaling between objects in the virtual world and their projections +// into the physical world is desired through use of explicit ScreenScale view +// attributes. The defaults are 0.365 meters for width and 0.292 meters for +// height. +// +(ScreenAttribute topleft PhysicalScreenWidth 0.912) +(ScreenAttribute topleft PhysicalScreenHeight 0.680) + +(ScreenAttribute topright PhysicalScreenWidth 0.912) +(ScreenAttribute topright PhysicalScreenHeight 0.680) + +(ScreenAttribute bottomleft PhysicalScreenWidth 0.912) +(ScreenAttribute bottomleft PhysicalScreenHeight 0.685) + +(ScreenAttribute bottomright PhysicalScreenWidth 0.912) +(ScreenAttribute bottomright PhysicalScreenHeight 0.685) + + +// Specify full screen windows. +// +(ScreenAttribute topleft WindowSize NoBorderFullScreen) +(ScreenAttribute topright WindowSize NoBorderFullScreen) +(ScreenAttribute bottomleft WindowSize NoBorderFullScreen) +(ScreenAttribute bottomright WindowSize NoBorderFullScreen) + +// Set the TrackerBaseToImagePlate transforms for these screens. This +// transforms points in tracker base coordinates to each screen's image plate +// coordinates, where the origin of the image plate is defined to be the lower +// left corner of the screen with X increasing to the right, Y increasing to +// the top, and Z increasing away from the screen. +// +// Without head or sensor tracking the tracker base is still needed as a point +// of reference for describing the orientation and position of each screen to +// the others. The coexistence to tracker base transform is set to identity by +// default, so the tracker base origin and orientation will also set the origin +// and orientation of coexistence coordinates in the physical world. +// +// The tracker base and center of coexistence are set here to the center of the +// 2x2 array with its basis vectors aligned to image plate coordinates. +// +(ScreenAttribute topleft TrackerBaseToImagePlate + (Translate 0.912 0.000 0.0)) +(ScreenAttribute topright TrackerBaseToImagePlate + (Translate 0.000 0.000 0.0)) +(ScreenAttribute bottomleft TrackerBaseToImagePlate + (Translate 0.912 0.685 0.0)) +(ScreenAttribute bottomright TrackerBaseToImagePlate + (Translate 0.000 0.685 0.0)) + +// Create a view using the defined screens. +// +(NewView view0) +(ViewAttribute view0 Screen topleft) +(ViewAttribute view0 Screen topright) +(ViewAttribute view0 Screen bottomleft) +(ViewAttribute view0 Screen bottomright) + +// Set the screen scale. This is scale factor from virtual to physical +// coordinates. The default policy of SCALE_SCREEN_SIZE doesn't work well here +// since in the 2x2 arrangement the individual screens are too small. The +// explicit scale factor below assumes a normalized range of object coordinates +// of [-1.0 .. +1.0]. +// +(ViewAttribute view0 ScreenScalePolicy SCALE_EXPLICIT) +(ViewAttribute view0 ScreenScale 0.912) + +// Set the user eye position in the display environment. +// +(ViewAttribute view0 CenterEyeInCoexistence (0.0 0.0 1.0)) diff --git a/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form b/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form new file mode 100644 index 0000000..b7d1376 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.form @@ -0,0 +1,217 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java b/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java new file mode 100644 index 0000000..8485823 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/depth_func/DepthFuncTest.java @@ -0,0 +1,359 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.depth_func; + +import javax.media.j3d.*; + + +/** + *The goal of that example is to show the use of different ZBuffer comparison modes. + */ +public class DepthFuncTest extends javax.swing.JFrame +{ + + RenderFrame rf; + + /** + * Creates new form DepthFuncTest + */ + public DepthFuncTest(){ + initComponents(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //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); + } + // //GEN-END:initComponents + + private void rotatingComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_rotatingComboBoxActionPerformed + {//GEN-HEADEREND:event_rotatingComboBoxActionPerformed + String selectedItem = rotatingComboBox.getSelectedItem().toString(); // how to avoid a cast and all that goes with it. (lazyness) + int mode = RenderingAttributes.ROP_COPY; + if ( "CLEAR".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_CLEAR; + } + else if ( "AND".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_AND; + } + else if ( "AND_REVERSE".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_AND_REVERSE; + } + else if ( "COPY".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_COPY; + } + else if ( "AND_INVERTED".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_AND_INVERTED; + } + else if ( "NOOP".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_NOOP; + } + else if ( "XOR".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_XOR; + } + else if ( "OR".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_OR; + } + else if ( "NOR".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_NOR; + } + else if ( "EQUIV".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_EQUIV; + } + else if ( "INVERT".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_INVERT; + } + else if ( "OR_REVERSE".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_OR_REVERSE; + } + else if ( "COPY_INVERTED".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_COPY_INVERTED; + } + else if ( "OR_INVERTED".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_OR_INVERTED; + } + else if ( "NAND".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_NAND; + } + else if ( "SET".equals(selectedItem) ) + { + mode = RenderingAttributes.ROP_SET; + } + else + { + System.out.println("oops. wrong mode in ROP combo: "+selectedItem); + } + rf.setRotatingObjectROPMode( mode ); + }//GEN-LAST:event_rotatingComboBoxActionPerformed + + private void shadedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_shadedCheckBoxActionPerformed + rf.setStaticObjectDBWriteStatus( shadedCheckBox.isSelected() ); + }//GEN-LAST:event_shadedCheckBoxActionPerformed + + private void wfCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_wfCheckBoxActionPerformed + rf.setStaticWFObjectDBWriteStatus( wfCheckBox.isSelected() ); + }//GEN-LAST:event_wfCheckBoxActionPerformed + + private void shadedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_shadedComboBoxActionPerformed + int func = RenderingAttributes.LESS_OR_EQUAL; + String selectedItem = shadedComboBox.getSelectedItem().toString(); // how to avoid a cast and all that goes with it. (lazyness) + rf.setStaticObjectTestFunc( getID( selectedItem ) ); + }//GEN-LAST:event_shadedComboBoxActionPerformed + + private void normalComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_normalComboBoxActionPerformed + int func = RenderingAttributes.LESS_OR_EQUAL; + String selectedItem = normalComboBox.getSelectedItem().toString(); // how to avoid a cast and all that goes with it. (lazyness) + rf.setStaticWFObjectTestFunc( getID( selectedItem ) ); + }//GEN-LAST:event_normalComboBoxActionPerformed + + int getID( String selectedItem ) + { + int func = RenderingAttributes.LESS_OR_EQUAL; + if ( "LESS_OR_EQUAL".equals(selectedItem) ) + { + func = RenderingAttributes.LESS_OR_EQUAL; + } + else if ( "NEVER".equals(selectedItem) ) + { + func = RenderingAttributes.NEVER; + } + else if ( "ALWAYS".equals(selectedItem) ) + { + func = RenderingAttributes.ALWAYS; + } + else if ( "GREATER".equals(selectedItem) ) + { + func = RenderingAttributes.GREATER; + } + else if ( "GREATER_OR_EQUAL".equals(selectedItem) ) + { + func = RenderingAttributes.GREATER_OR_EQUAL; + } + else if ( "LESS".equals(selectedItem) ) + { + func = RenderingAttributes.LESS; + } + else if ( "EQUAL".equals(selectedItem) ) + { + func = RenderingAttributes.EQUAL; + } + else if ( "NOT_EQUAL".equals(selectedItem) ) + { + func = RenderingAttributes.NOT_EQUAL; + } + return func; + } + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + DepthFuncTest dpt = new DepthFuncTest(); + dpt.rf = new RenderFrame( dpt ); + dpt.setVisible(true); + dpt.rf.setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JComboBox normalComboBox; + private javax.swing.JComboBox rotatingComboBox; + private javax.swing.JCheckBox shadedCheckBox; + private javax.swing.JComboBox shadedComboBox; + private javax.swing.JCheckBox wfCheckBox; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.form b/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.form new file mode 100644 index 0000000..2edc4bb --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.form @@ -0,0 +1,25 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.java b/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.java new file mode 100644 index 0000000..5edc79d --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/depth_func/RenderFrame.java @@ -0,0 +1,292 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.depth_func; + +import com.sun.j3d.utils.behaviors.mouse.*; +import com.sun.j3d.utils.behaviors.vp.OrbitBehavior; +import java.awt.GraphicsConfiguration; +import javax.media.j3d.*; +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.geometry.*; +import javax.vecmath.*; + + +public class RenderFrame extends javax.swing.JFrame { + + DepthFuncTest dpt; + + SimpleUniverse su; + + RenderingAttributes staticWFBoxRA; + RenderingAttributes staticBoxRA; + + RenderingAttributes rotatingBoxRA; + + /** Creates new form RenderFrame */ + public RenderFrame( DepthFuncTest _dpt) { + dpt = _dpt; + initComponents(); + initUniverse(); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() + { + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("J3D frame"); + setBounds(400, 0, 640, 480); + } + // //GEN-END:initComponents + + void initUniverse() { + GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + su = new SimpleUniverse(c); + su.addBranchGraph( createScene() ); + c.getView().setMinimumFrameCycleTime( 10 ); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables + + BranchGroup createScene() { + BoundingSphere bounds = new BoundingSphere( new Point3d( 0.0, 0.0, 0.0 ), 100.0 ); + + BranchGroup globalBG = new BranchGroup(); + BranchGroup rotObjectBG = new BranchGroup(); + OrderedGroup staticObjectOG = new OrderedGroup(); + BranchGroup lampsBG = new BranchGroup(); + OrderedGroup oGroup = new OrderedGroup(); + TransformGroup staticBoxRotTG = new TransformGroup(); + staticBoxRotTG.addChild( staticObjectOG ); + TransformGroup objectsTGRot = new TransformGroup(); + TransformGroup objectsTGTrans = new TransformGroup(); + Transform3D objectsTGTransT3d = new Transform3D(); + objectsTGTransT3d.setTranslation( new Vector3f( 0.0f, 0.0f, -10.0f ) ); + objectsTGTrans.setTransform( objectsTGTransT3d ); + objectsTGRot.addChild( oGroup ); + objectsTGTrans.addChild( objectsTGRot ); + lampsBG.addChild( objectsTGTrans ); + + //adding a sphere as backgroung so there is something else than flat black, and cut cube removal as an other implication. (seeing through) + Appearance globalSphereAppearance = new Appearance(); + PolygonAttributes globalSpherePA = new PolygonAttributes(); + globalSpherePA.setCullFace( globalSpherePA.CULL_FRONT );// so that interior of the sphere is visible. + Material globalSphereMaterial = new Material(); + globalSphereMaterial.setEmissiveColor( .25f ,.3f ,.35f ); + globalSphereAppearance.setMaterial( globalSphereMaterial ); + globalSphereAppearance.setPolygonAttributes( globalSpherePA ); + Sphere globalSphere = new Sphere( 6.0f ); + globalSphere.setAppearance( globalSphereAppearance ); + globalSphere.setBounds( bounds ); + oGroup.addChild( globalSphere ); + + globalBG.addChild( lampsBG ); + + // adding lamps. + PointLight frontLamp = new PointLight( new Color3f( 1.0f, 1.0f, 1.0f ), new Point3f( 20, 20, 20 ), new Point3f( 0.0f, .0f, 0.f ) ); + lampsBG.addChild( frontLamp ); + frontLamp.setBounds( bounds ); + frontLamp.setInfluencingBounds( bounds ); + PointLight backLamp = new PointLight( new Color3f( 1.0f, .0f, .0f ), new Point3f( -20, -20, -20 ), new Point3f( 0.0f, .0f, 0.f ) ); + lampsBG.addChild( backLamp ); + backLamp.setBounds( bounds ); + backLamp.setInfluencingBounds( bounds ); + + //adding shapes. + { + //adding rotating and scaling cube + //doing the rotation + TransformGroup rotBoxTGRot = new TransformGroup(); + rotBoxTGRot.setCapability( rotBoxTGRot.ALLOW_TRANSFORM_WRITE ); + RotationInterpolator rotBoxRotInt = new RotationInterpolator( new Alpha( -1, 20000 ) , rotBoxTGRot ); + rotBoxRotInt.setSchedulingBounds( bounds ); + rotBoxRotInt.setBounds( bounds ); + + //doing the scaling + Transform3D scaleBoxt3d = new Transform3D(); + TransformGroup rotBoxTGScale = new TransformGroup(); + rotBoxTGScale.setCapability( rotBoxTGScale.ALLOW_TRANSFORM_WRITE ); + ScaleInterpolator rotBoxScaleInt = new ScaleInterpolator( new Alpha( -1, Alpha.INCREASING_ENABLE|Alpha.DECREASING_ENABLE, 0, 0, 3000, 1500, 0, 3000, 1500, 0 ) , rotBoxTGScale, new Transform3D(), 0.7f, 1.6f ); + rotBoxScaleInt.setSchedulingBounds( bounds ); + rotBoxScaleInt.setBounds( bounds ); + + Appearance rotBoxApp = new Appearance(); + Material rotBoxMat = new Material(); + rotBoxMat.setDiffuseColor( .4f, .4f, .4f ); + rotBoxApp.setMaterial( rotBoxMat ); + Box rotBox = new Box( 1.1f, 1.1f, 1.1f, rotBoxApp ); + rotBoxTGScale.addChild( rotBox ); + rotBoxTGRot.addChild( rotBoxTGScale ); + TransformGroup rotBoxTG = new TransformGroup(); + rotBoxTG.addChild( rotBoxTGRot ); + rotObjectBG.addChild( rotBoxTG ); + rotObjectBG.addChild( rotBoxScaleInt ); + rotObjectBG.addChild( rotBoxRotInt ); + rotBox.setBounds( bounds ); + + rotatingBoxRA = new RenderingAttributes(); + rotatingBoxRA.setRasterOpEnable( true ); + rotatingBoxRA.setCapability( staticBoxRA.ALLOW_RASTER_OP_WRITE ); +// rotatingBoxRA.setRasterOp( rotatingBoxRA.ROP_XOR ); + rotBoxApp.setRenderingAttributes( rotatingBoxRA ); + + + rotBox.setAppearance( rotBoxApp ); + } + + //adding static back face wireframe cube + { + Box staticWFBoxBack = new Box( ); + Appearance staticWFBoxApp = new Appearance(); + Material staticWFBoxMat = new Material(); + staticWFBoxMat.setDiffuseColor( 0.f, 0.f, 0.f ); + staticWFBoxMat.setEmissiveColor( 0.f, .4f, 0.f ); + staticWFBoxApp.setMaterial( staticWFBoxMat ); + PolygonAttributes staticWFBoxPABack = new PolygonAttributes( PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_FRONT, 0.0f ); + staticWFBoxApp.setPolygonAttributes( staticWFBoxPABack ); + staticWFBoxRA = new RenderingAttributes(); + staticWFBoxRA.setCapability( staticWFBoxRA.ALLOW_DEPTH_TEST_FUNCTION_WRITE ); + staticWFBoxRA.setCapability( staticWFBoxRA.ALLOW_DEPTH_ENABLE_WRITE ); + staticWFBoxRA.setDepthTestFunction( staticWFBoxRA.GREATER ); + staticWFBoxRA.setDepthBufferWriteEnable( false ); + staticWFBoxApp.setRenderingAttributes( staticWFBoxRA ); + staticWFBoxBack.setAppearance( staticWFBoxApp ); + staticWFBoxBack.setBounds( bounds ); + staticObjectOG.addChild( staticWFBoxBack ); + } + + //adding static front face wireframe cube + { + Box staticWFBox = new Box( ); + Appearance staticWFBoxApp = new Appearance(); + Material staticWFBoxMat = new Material(); + staticWFBoxMat.setDiffuseColor( 0.f, 0.f, 0.f ); + staticWFBoxMat.setEmissiveColor( 0.f, 1.f, 0.f ); + staticWFBoxApp.setMaterial( staticWFBoxMat ); + PolygonAttributes staticWFBoxPA = new PolygonAttributes( PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_BACK, 0.0f ); + staticWFBoxApp.setPolygonAttributes( staticWFBoxPA ); + staticWFBoxApp.setRenderingAttributes( staticWFBoxRA ); + staticWFBox.setAppearance( staticWFBoxApp ); + staticWFBox.setBounds( bounds ); + staticObjectOG.addChild( staticWFBox ); + } + + + {// rotating the static cubes + Transform3D boxt3d = new Transform3D(); + Transform3D tempt3d = new Transform3D(); + boxt3d.rotZ( Math.PI/4.0f ); + tempt3d.rotX( Math.PI/4.0f ); + boxt3d.mul( tempt3d ); + tempt3d.rotY( Math.PI/4.0f ); + boxt3d.mul( tempt3d ); + staticBoxRotTG.setTransform( boxt3d ); + } + + // adding static flat cube + { + Box staticBox = new Box( ); + staticBox.setBounds( bounds ); + Appearance boxApp = new Appearance(); + Material boxMat = new Material(); + boxMat.setDiffuseColor( .7f, .7f, .7f ); + boxApp.setMaterial( boxMat ); + staticBoxRA = new RenderingAttributes(); + staticBoxRA.setCapability( staticBoxRA.ALLOW_DEPTH_TEST_FUNCTION_WRITE ); + staticBoxRA.setCapability( staticBoxRA.ALLOW_DEPTH_ENABLE_WRITE ); + staticBoxRA.setDepthTestFunction( staticBoxRA.LESS ); + staticBoxRA.setDepthBufferWriteEnable( false ); + boxApp.setRenderingAttributes( staticBoxRA ); + staticBox.setAppearance( boxApp ); + staticObjectOG.addChild( staticBox ); + } + oGroup.addChild( rotObjectBG ); + oGroup.addChild( staticBoxRotTG ); + + //adding the mouse rotate behavior to the group of cubes. + MouseRotate behavior = new MouseRotate(); + behavior.setTransformGroup( objectsTGRot ); + objectsTGRot.addChild( behavior ); + objectsTGRot.setCapability( objectsTGRot.ALLOW_TRANSFORM_READ ); + objectsTGRot.setCapability( objectsTGRot.ALLOW_TRANSFORM_WRITE ); + behavior.setSchedulingBounds(bounds); + return globalBG; + } + + public void setStaticWFObjectTestFunc( int func ) + { + staticWFBoxRA.setDepthTestFunction( func ); + } + + public void setStaticObjectTestFunc( int func ) + { + staticBoxRA.setDepthTestFunction( func ); + } + + public void setStaticWFObjectDBWriteStatus( boolean status ) + { + staticWFBoxRA.setDepthBufferWriteEnable( status ); + } + + public void setStaticObjectDBWriteStatus( boolean status ) + { + staticBoxRA.setDepthBufferWriteEnable( status ); + } + + public void setRotatingObjectROPMode( int mode ) + { + rotatingBoxRA.setRasterOp( mode ); + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java b/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java new file mode 100644 index 0000000..134a128 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortBehavior.java @@ -0,0 +1,194 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.distort_glyph; + +import java.util.Enumeration; + +import javax.media.j3d.Appearance; +import javax.media.j3d.Behavior; +import javax.media.j3d.GeometryArray; +import javax.media.j3d.Shape3D; +import javax.media.j3d.Transform3D; +import javax.media.j3d.WakeupCondition; +import javax.media.j3d.WakeupCriterion; +import javax.media.j3d.WakeupOnElapsedFrames; +import javax.media.j3d.WakeupOnElapsedTime; + +import javax.vecmath.Vector3f; + +public class DistortBehavior extends Behavior { + // the wake up condition for the behavior + protected WakeupCondition m_InitialWakeupCondition = null; + protected WakeupCondition m_FrameWakeupCondition = null; + + // the GeometryArray for the Shape3D that we are modifying + protected Shape3D m_Shape3D = null; + protected GeometryArray m_GeometryArray = null; + + protected float[] m_CoordinateArray = null; + protected float[] m_OriginalCoordinateArray = null; + protected Appearance m_Appearance = null; + + protected int m_nElapsedTime = 0; + protected int m_nNumFrames = 0; + protected int m_nFrameNumber = 0; + + private int frame = 0; + protected Vector3f m_Vector = null; + + public DistortBehavior(Shape3D shape3D, int nElapsedTime, int nNumFrames) { + // allocate a temporary vector + m_Vector = new Vector3f(); + + m_FrameWakeupCondition = new WakeupOnElapsedFrames(0); + + restart(shape3D, nElapsedTime, nNumFrames); + } + + public WakeupCondition restart(Shape3D shape3D, int nElapsedTime, int nNumFrames) { + m_Shape3D = shape3D; + m_nElapsedTime = nElapsedTime; + m_nNumFrames = nNumFrames; + m_nFrameNumber = 0; + + // create the WakeupCriterion for the behavior + m_InitialWakeupCondition = new WakeupOnElapsedTime(m_nElapsedTime); + + // save the GeometryArray that we are modifying + m_GeometryArray = (GeometryArray) m_Shape3D.getGeometry(); + + if (m_Shape3D.isLive() == false && m_Shape3D.isCompiled() == false) { + // set the capability bits that the behavior requires + m_Shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + m_Shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + + m_Shape3D.getAppearance().setCapability(Appearance.ALLOW_POINT_ATTRIBUTES_WRITE); + m_Shape3D.getAppearance().setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_WRITE); + m_Shape3D.getAppearance().setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE); + m_Shape3D.getAppearance().setCapability(Appearance.ALLOW_TEXTURE_WRITE); + + m_GeometryArray.setCapability(GeometryArray.ALLOW_COORDINATE_READ); + m_GeometryArray.setCapability(GeometryArray.ALLOW_COORDINATE_WRITE); + m_GeometryArray.setCapability(GeometryArray.ALLOW_COUNT_READ); + } + + // make a copy of the object's original appearance + m_Appearance = new Appearance(); + m_Appearance = (Appearance) m_Shape3D.getAppearance().cloneNodeComponent(true); + + // allocate an array for the model coordinates + m_CoordinateArray = new float[3 * m_GeometryArray.getVertexCount()]; + + // make a copy of the models original coordinates + m_OriginalCoordinateArray = new float[3 * m_GeometryArray.getVertexCount()]; + m_GeometryArray.getCoordinates(0, m_OriginalCoordinateArray); + + // start (or restart) the behavior + setEnable(true); + + return m_InitialWakeupCondition; + } + + public void initialize() { + // apply the initial WakeupCriterion + wakeupOn(m_InitialWakeupCondition); + } + + public void processStimulus(Enumeration criteria) { + while (criteria.hasMoreElements()) { + WakeupCriterion wakeUp = (WakeupCriterion) criteria.nextElement(); + + if (wakeUp instanceof WakeupOnElapsedTime) { + } else { + // we are mid explosion, modify the GeometryArray + m_nFrameNumber++; + frame++; + m_GeometryArray.getCoordinates(0, m_CoordinateArray); + + Transform3D t3 = new Transform3D(); + for (int n = 0; n < m_CoordinateArray.length; n += 3) { + m_Vector.x = m_OriginalCoordinateArray[n]; + m_Vector.y = m_OriginalCoordinateArray[n + 1]; + m_Vector.z = m_OriginalCoordinateArray[n + 2]; + + float spx = (float) (Math.sin(frame *3f / 500)); + float spy = (float) (Math.cos(frame *5f / 500)); + Vector3f v = new Vector3f(spx, spy, 0); + + float px = (m_Vector.x - v.x); + float py = (m_Vector.y - v.y); + float pz = (m_Vector.z - v.z); + float d = (float) Math.sqrt(px * px + py * py + pz * pz); + + + m_Vector.add(new Vector3f(-.25f, -.25f, -.25f)); + //m_Vector.scale(d); + + t3.rotZ(d); + t3.rotX(d*2); + t3.rotY(d); + t3.transform(m_Vector); + + m_CoordinateArray[n] = m_Vector.x; + m_CoordinateArray[n + 1] = m_Vector.y; + m_CoordinateArray[n + 2] = m_Vector.z; + + } + + // assign the new coordinates + m_GeometryArray.setCoordinates(0, m_CoordinateArray); + } + } + + if (m_nFrameNumber < m_nNumFrames) { + // assign the next WakeUpCondition, so we are notified again + wakeupOn(m_FrameWakeupCondition); + } else { + // restart + m_nFrameNumber = 0; + wakeupOn(m_FrameWakeupCondition); + } + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java b/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java new file mode 100644 index 0000000..afada2e --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/distort_glyph/DistortGlyphTest.java @@ -0,0 +1,210 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.distort_glyph; + +import java.applet.Applet; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; + +import javax.media.j3d.AmbientLight; +import javax.media.j3d.Appearance; +import javax.media.j3d.BoundingSphere; +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Canvas3D; +import javax.media.j3d.DirectionalLight; +import javax.media.j3d.Font3D; +import javax.media.j3d.FontExtrusion; +import javax.media.j3d.GeometryArray; +import javax.media.j3d.GraphicsConfigTemplate3D; +import javax.media.j3d.Light; +import javax.media.j3d.Material; +import javax.media.j3d.PointLight; +import javax.media.j3d.Shape3D; +import javax.media.j3d.TexCoordGeneration; +import javax.media.j3d.Texture; +import javax.media.j3d.TransformGroup; + +import javax.vecmath.Color3f; +import javax.vecmath.Point3d; +import javax.vecmath.Point3f; +import javax.vecmath.Vector3f; + +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.behaviors.mouse.MouseRotate; +import com.sun.j3d.utils.behaviors.mouse.MouseTranslate; +import com.sun.j3d.utils.behaviors.mouse.MouseZoom; +import com.sun.j3d.utils.image.TextureLoader; +import com.sun.j3d.utils.universe.SimpleUniverse; + +public class DistortGlyphTest extends Applet { + // get a nice graphics config + private static GraphicsConfiguration getGraphicsConfig() { + GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); + template.setSceneAntialiasing(GraphicsConfigTemplate3D.PREFERRED); + GraphicsConfiguration gcfg = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(template); + return gcfg; + } + + private void setupLights(BranchGroup root) { + // set up the BoundingSphere for all the lights + BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0); + + // Set up the ambient light + AmbientLight lightAmbient = new AmbientLight(new Color3f(0.37f, 0.37f, 0.37f)); + lightAmbient.setInfluencingBounds(bounds); + root.addChild(lightAmbient); + + // Set up the directional light + Vector3f lightDirection1 = new Vector3f(0.0f, 0.0f, -1.0f); + DirectionalLight lightDirectional1 = new DirectionalLight(new Color3f(1.00f, 0.10f, 0.00f), lightDirection1); + lightDirectional1.setInfluencingBounds(bounds); + lightDirectional1.setCapability(Light.ALLOW_STATE_WRITE); + root.addChild(lightDirectional1); + + Point3f lightPos1 = new Point3f(-4.0f, 8.0f, 16.0f); + Point3f lightAttenuation1 = new Point3f(1.0f, 0.0f, 0.0f); + PointLight pointLight1 = new PointLight(new Color3f(0.37f, 1.00f, 0.37f), lightPos1, lightAttenuation1); + pointLight1.setInfluencingBounds(bounds); + root.addChild(pointLight1); + + Point3f lightPos2 = new Point3f(-16.0f, 8.0f, 4.0f); + Point3f lightAttenuation2 = new Point3f(1.0f, 0.0f, 0.0f); + PointLight pointLight2 = new PointLight(new Color3f(0.37f, 0.37f, 1.00f), lightPos2, lightAttenuation2); + pointLight2.setInfluencingBounds(bounds); + root.addChild(pointLight2); + } + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + setupLights(objRoot); + + TransformGroup objTransform = new TransformGroup(); + objTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + + objRoot.addChild(objTransform); + + // setup a nice textured appearance + Appearance app = new Appearance(); + Color3f objColor = new Color3f(1.0f, 0.7f, 0.8f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + app.setMaterial(new Material(objColor, black, objColor, black, 80.0f)); + Texture txtr = new TextureLoader("gold.jpg",this).getTexture(); + app.setTexture(txtr); + TexCoordGeneration tcg = new TexCoordGeneration(TexCoordGeneration.SPHERE_MAP,TexCoordGeneration.TEXTURE_COORDINATE_2); + app.setTexCoordGeneration(tcg); + + // use a customized FontExtrusion object to control the depth of the text + java.awt.geom.GeneralPath gp = new java.awt.geom.GeneralPath(); + gp.moveTo(0, 0); + gp.lineTo(.01f, .01f); + gp.lineTo(.2f, .01f); + gp.lineTo(.21f, 0f); + FontExtrusion fontEx = new FontExtrusion(gp); + + // our glyph + Font fnt = new Font("dialog", Font.BOLD, 1); + Font3D f3d = new Font3D(fnt, .001, fontEx); + GeometryArray geom = f3d.getGlyphGeometry('A'); + Shape3D shape = new Shape3D(geom, app); + objTransform.addChild(shape); + + // the DistortBehavior + DistortBehavior eb = new DistortBehavior(shape, 1000, 1000); + eb.setSchedulingBounds(new BoundingSphere()); + objTransform.addChild(eb); + + MouseRotate myMouseRotate = new MouseRotate(); + myMouseRotate.setTransformGroup(objTransform); + myMouseRotate.setSchedulingBounds(new BoundingSphere()); + objRoot.addChild(myMouseRotate); + + MouseTranslate myMouseTranslate = new MouseTranslate(); + myMouseTranslate.setTransformGroup(objTransform); + myMouseTranslate.setSchedulingBounds(new BoundingSphere()); + objRoot.addChild(myMouseTranslate); + + MouseZoom myMouseZoom = new MouseZoom(); + myMouseZoom.setTransformGroup(objTransform); + myMouseZoom.setSchedulingBounds(new BoundingSphere()); + objRoot.addChild(myMouseZoom); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + // Create a simple scene and attach it to the virtual universe + public DistortGlyphTest() { + //setLayout(new BorderLayout()); + GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); + + Canvas3D canvas3D = new Canvas3D(getGraphicsConfig()); + canvas3D.setBounds(0, 0, 800, 600); + add("Center", canvas3D); + + BranchGroup scene = createSceneGraph(); + + // SimpleUniverse is a Convenience Utility class + SimpleUniverse simpleU = new SimpleUniverse(canvas3D); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + simpleU.getViewingPlatform().setNominalViewingTransform(); + + simpleU.addBranchGraph(scene); + } + + // The following allows this to be run as an application + // as well as an applet + public static void main(String[] args) { + Frame frame = new MainFrame(new DistortGlyphTest(), 800, 600); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/BigCube.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/BigCube.java new file mode 100644 index 0000000..9937c62 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/BigCube.java @@ -0,0 +1,140 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.four_by_four; + +import java.applet.Applet; +import java.awt.event.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/** + * Class BigCube + * + * Description: Creates the "big" cube used to mark the computer's + * position. + * + * Version: 1.0 + */ +public class BigCube extends Object { + + private Shape3D shape3D; + + private static final float[] verts = { + // Front Face + 5.0f, -5.0f, 5.0f, 5.0f, 5.0f, 5.0f, + -5.0f, 5.0f, 5.0f, -5.0f, -5.0f, 5.0f, + // Back Face + -5.0f, -5.0f, -5.0f, -5.0f, 5.0f, -5.0f, + 5.0f, 5.0f, -5.0f, 5.0f, -5.0f, -5.0f, + // Right Face + 5.0f, -5.0f, -5.0f, 5.0f, 5.0f, -5.0f, + 5.0f, 5.0f, 5.0f, 5.0f, -5.0f, 5.0f, + // Left Face + -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, 5.0f, + -5.0f, 5.0f, -5.0f, -5.0f, -5.0f, -5.0f, + // Top Face + 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, -5.0f, + -5.0f, 5.0f, -5.0f, -5.0f, 5.0f, 5.0f, + // Bottom Face + -5.0f, -5.0f, 5.0f, -5.0f, -5.0f, -5.0f, + 5.0f, -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, + }; + + private static final float[] normals = { + // Front Face + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + // Back Face + 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, + // Right Face + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + // Left Face + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + // Top Face + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + // Bottom Face + 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + }; + + public BigCube(Appearance appearance) { + + QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES | + QuadArray.NORMALS ); + quadArray.setCoordinates(0, verts); + quadArray.setNormals(0, normals); + + shape3D = new Shape3D(quadArray, appearance); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + } + + public BigCube(Appearance appearance, float size) { + + QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES | + QuadArray.NORMALS ); + + for (int i=0; i<72; i++) verts[i] *= size; + + quadArray.setCoordinates(0, verts); + quadArray.setNormals(0, normals); + + shape3D = new Shape3D(quadArray, appearance); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + } + + public Shape3D getChild() { + return shape3D; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/Board.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/Board.java new file mode 100644 index 0000000..53aa71e --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/Board.java @@ -0,0 +1,2312 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.four_by_four; + +import java.awt.*; + +/** + * Class: Board + * + * Description: Handles all logic with respect to play. Also renders + * the 2D window. + * + * Version: 1.1 + * + */ +class Board { + + final static int UNOCCUPIED = 0; + final static int HUMAN = 1; + final static int MACHINE = 2; + final static int END = 3; + + private int[] moves; + private int[] occupied; + private int[][] combinations; + private int[][] outside_four; + private int[][] inside_four; + private int[][] faces; + private int[][] pos_to_comb; + private int[][] best_picks; + private int num_points; + private int num_balls; + private int num_polygons; + private int num_pt_indexes; + private int num_normal_indexes; + private int pt_start; + private int color_index; + private int width; + private int height; + private int center_x; + private int center_y; + private int player; + private int skill_level; + private int outside_four_index; + private int inside_four_index; + private int face_index; + private int nmoves; + private int current_face; + private int min = 1000; + private int max = 0; + private long[] sort_array; + private long time; + private long beg_time; + private long end_time; + private Color[] color_ramp; + private Color background; + private Color label_color; + private Color red; + private Color blue; + private Color white; + private Color gray; + private Color yellow; + private double max_dist; + private FourByFour panel; + private boolean debug; + private boolean outside_four_flag; + private boolean inside_four_flag; + private boolean face_flag; + private boolean label_flag; + private boolean block_chair_flag; + private boolean undoFlag; + private boolean[] highlight; + private int block_chair_next_move; + private int block_chair_face; + private Positions positions; + private Canvas2D canvas; + + Board (FourByFour panel, Positions positions, int width, int height) { + + // Set the debug state. + debug = false; + + // Store arguments + this.width = width; + this.height = height; + this.panel = panel; + this.positions = positions; + + // Initialize flags + label_flag = false; + outside_four_flag = false; + inside_four_flag = false; + block_chair_flag = false; + undoFlag = false; + + // Total number of board positions. + num_points = 64; + + // Allocate the logic arrays. + moves = new int[64]; + occupied = new int[64]; + combinations = new int[76][7]; + outside_four = new int[18][6]; + inside_four = new int[18][6]; + faces = new int[18][18]; + pos_to_comb = new int[64][8]; + best_picks = new int[64][8]; + highlight = new boolean[18]; + + // Initialize the logic arrays. + init_combinations(); + init_faces(); + init_outside_four(); + init_inside_four(); + + // Set the player with the first move. + player = HUMAN; + + // Set the default skill level. + skill_level = 4; + + // Initialize the number of moves. + nmoves = 0; + + // Define colors + background = new Color(13, 13, 51); + red = new Color(230, 26, 51); + blue = new Color(51, 51, 230); + white = new Color(255, 255, 255); + gray = new Color(240, 240, 240); + yellow = new Color(240, 240, 0); + + // Record the start time + beg_time = System.currentTimeMillis(); + } + + public void setCanvas(Canvas2D canvas) { + this.canvas = canvas; + } + + public void init_combinations () { + + // The combination array contains all possible winning combinations. + // + // Each combination has the following format: + // + // combinations[x][0] = status: 0 = no player has selected positons in this row + // -1 = both players have men in this row + // 1 to 4 = number of positions occupied by player + // + // combinations[x][1] = player who owns this row (valid only if status = 1-4) + // combinations[x][2] = postion that define the row + // combinations[x][3] = postion that define the row + // combinations[x][4] = postion that define the row + // combinations[x][5] = postion that define the row + + // Horizontal, Z + + combinations[ 0][0] = 0; combinations[ 1][0] = 0; combinations[ 2][0] = 0; combinations[ 3][0] = 0; + combinations[ 0][1] = 0; combinations[ 1][1] = 0; combinations[ 2][1] = 0; combinations[ 3][1] = 0; + combinations[ 0][2] = 0; combinations[ 1][2] = 4; combinations[ 2][2] = 8; combinations[ 3][2] = 12; + combinations[ 0][3] = 1; combinations[ 1][3] = 5; combinations[ 2][3] = 9; combinations[ 3][3] = 13; + combinations[ 0][4] = 2; combinations[ 1][4] = 6; combinations[ 2][4] = 10; combinations[ 3][4] = 14; + combinations[ 0][5] = 3; combinations[ 1][5] = 7; combinations[ 2][5] = 11; combinations[ 3][5] = 15; + + combinations[ 4][0] = 0; combinations[ 5][0] = 0; combinations[ 6][0] = 0; combinations[ 7][0] = 0; + combinations[ 4][1] = 0; combinations[ 5][1] = 0; combinations[ 6][1] = 0; combinations[ 7][1] = 0; + combinations[ 4][2] = 16; combinations[ 5][2] = 20; combinations[ 6][2] = 24; combinations[ 7][2] = 28; + combinations[ 4][3] = 17; combinations[ 5][3] = 21; combinations[ 6][3] = 25; combinations[ 7][3] = 29; + combinations[ 4][4] = 18; combinations[ 5][4] = 22; combinations[ 6][4] = 26; combinations[ 7][4] = 30; + combinations[ 4][5] = 19; combinations[ 5][5] = 23; combinations[ 6][5] = 27; combinations[ 7][5] = 31; + + combinations[ 8][0] = 0; combinations[ 9][0] = 0; combinations[10][0] = 0; combinations[11][0] = 0; + combinations[ 8][1] = 0; combinations[ 9][1] = 0; combinations[10][1] = 0; combinations[11][1] = 0; + combinations[ 8][2] = 32; combinations[ 9][2] = 36; combinations[10][2] = 40; combinations[11][2] = 44; + combinations[ 8][3] = 33; combinations[ 9][3] = 37; combinations[10][3] = 41; combinations[11][3] = 45; + combinations[ 8][4] = 34; combinations[ 9][4] = 38; combinations[10][4] = 42; combinations[11][4] = 46; + combinations[ 8][5] = 35; combinations[ 9][5] = 39; combinations[10][5] = 43; combinations[11][5] = 47; + + combinations[12][0] = 0; combinations[13][0] = 0; combinations[14][0] = 0; combinations[15][0] = 0; + combinations[12][1] = 0; combinations[13][1] = 0; combinations[14][1] = 0; combinations[15][1] = 0; + combinations[12][2] = 48; combinations[13][2] = 52; combinations[14][2] = 56; combinations[15][2] = 60; + combinations[12][3] = 49; combinations[13][3] = 53; combinations[14][3] = 57; combinations[15][3] = 61; + combinations[12][4] = 50; combinations[13][4] = 54; combinations[14][4] = 58; combinations[15][4] = 62; + combinations[12][5] = 51; combinations[13][5] = 55; combinations[14][5] = 59; combinations[15][5] = 63; + + // Vertical, Z + + combinations[16][0] = 0; combinations[17][0] = 0; combinations[18][0] = 0; combinations[19][0] = 0; + combinations[16][1] = 0; combinations[17][1] = 0; combinations[18][1] = 0; combinations[19][1] = 0; + combinations[16][2] = 0; combinations[17][2] = 1; combinations[18][2] = 2; combinations[19][2] = 3; + combinations[16][3] = 4; combinations[17][3] = 5; combinations[18][3] = 6; combinations[19][3] = 7; + combinations[16][4] = 8; combinations[17][4] = 9; combinations[18][4] = 10; combinations[19][4] = 11; + combinations[16][5] = 12; combinations[17][5] = 13; combinations[18][5] = 14; combinations[19][5] = 15; + + combinations[20][0] = 0; combinations[21][0] = 0; combinations[22][0] = 0; combinations[23][0] = 0; + combinations[20][1] = 0; combinations[21][1] = 0; combinations[22][1] = 0; combinations[23][1] = 0; + combinations[20][2] = 16; combinations[21][2] = 17; combinations[22][2] = 18; combinations[23][2] = 19; + combinations[20][3] = 20; combinations[21][3] = 21; combinations[22][3] = 22; combinations[23][3] = 23; + combinations[20][4] = 24; combinations[21][4] = 25; combinations[22][4] = 26; combinations[23][4] = 27; + combinations[20][5] = 28; combinations[21][5] = 29; combinations[22][5] = 30; combinations[23][5] = 31; + + combinations[24][0] = 0; combinations[25][0] = 0; combinations[26][0] = 0; combinations[27][0] = 0; + combinations[24][1] = 0; combinations[25][1] = 0; combinations[26][1] = 0; combinations[27][1] = 0; + combinations[24][2] = 32; combinations[25][2] = 33; combinations[26][2] = 34; combinations[27][2] = 35; + combinations[24][3] = 36; combinations[25][3] = 37; combinations[26][3] = 38; combinations[27][3] = 39; + combinations[24][4] = 40; combinations[25][4] = 41; combinations[26][4] = 42; combinations[27][4] = 43; + combinations[24][5] = 44; combinations[25][5] = 45; combinations[26][5] = 46; combinations[27][5] = 47; + + combinations[28][0] = 0; combinations[29][0] = 0; combinations[30][0] = 0; combinations[31][0] = 0; + combinations[28][1] = 0; combinations[29][1] = 0; combinations[30][1] = 0; combinations[31][1] = 0; + combinations[28][2] = 48; combinations[29][2] = 49; combinations[30][2] = 50; combinations[31][2] = 51; + combinations[28][3] = 52; combinations[29][3] = 53; combinations[30][3] = 54; combinations[31][3] = 55; + combinations[28][4] = 56; combinations[29][4] = 57; combinations[30][4] = 58; combinations[31][4] = 59; + combinations[28][5] = 60; combinations[29][5] = 61; combinations[30][5] = 62; combinations[31][5] = 63; + + // Diagonal, Z + + combinations[32][0] = 0; combinations[33][0] = 0; combinations[34][0] = 0; combinations[35][0] = 0; + combinations[32][1] = 0; combinations[33][1] = 0; combinations[34][1] = 0; combinations[35][1] = 0; + combinations[32][2] = 0; combinations[33][2] = 16; combinations[34][2] = 32; combinations[35][2] = 48; + combinations[32][3] = 5; combinations[33][3] = 21; combinations[34][3] = 37; combinations[35][3] = 53; + combinations[32][4] = 10; combinations[33][4] = 26; combinations[34][4] = 42; combinations[35][4] = 58; + combinations[32][5] = 15; combinations[33][5] = 31; combinations[34][5] = 47; combinations[35][5] = 63; + + combinations[36][0] = 0; combinations[37][0] = 0; combinations[38][0] = 0; combinations[39][0] = 0; + combinations[36][1] = 0; combinations[37][1] = 0; combinations[38][1] = 0; combinations[39][1] = 0; + combinations[36][2] = 3; combinations[37][2] = 19; combinations[38][2] = 35; combinations[39][2] = 51; + combinations[36][3] = 6; combinations[37][3] = 22; combinations[38][3] = 38; combinations[39][3] = 54; + combinations[36][4] = 9; combinations[37][4] = 25; combinations[38][4] = 41; combinations[39][4] = 57; + combinations[36][5] = 12; combinations[37][5] = 28; combinations[38][5] = 44; combinations[39][5] = 60; + + // Horizontal, X + + combinations[40][0] = 0; combinations[41][0] = 0; combinations[42][0] = 0; combinations[43][0] = 0; + combinations[40][1] = 0; combinations[41][1] = 0; combinations[42][1] = 0; combinations[43][1] = 0; + combinations[40][2] = 51; combinations[41][2] = 55; combinations[42][2] = 59; combinations[43][2] = 63; + combinations[40][3] = 35; combinations[41][3] = 39; combinations[42][3] = 43; combinations[43][3] = 47; + combinations[40][4] = 19; combinations[41][4] = 23; combinations[42][4] = 27; combinations[43][4] = 31; + combinations[40][5] = 3; combinations[41][5] = 7; combinations[42][5] = 11; combinations[43][5] = 15; + + combinations[44][0] = 0; combinations[45][0] = 0; combinations[46][0] = 0; combinations[47][0] = 0; + combinations[44][1] = 0; combinations[45][1] = 0; combinations[46][1] = 0; combinations[47][1] = 0; + combinations[44][2] = 50; combinations[45][2] = 54; combinations[46][2] = 58; combinations[47][2] = 62; + combinations[44][3] = 34; combinations[45][3] = 38; combinations[46][3] = 42; combinations[47][3] = 46; + combinations[44][4] = 18; combinations[45][4] = 22; combinations[46][4] = 26; combinations[47][4] = 30; + combinations[44][5] = 2; combinations[45][5] = 6; combinations[46][5] = 10; combinations[47][5] = 14; + + combinations[48][0] = 0; combinations[49][0] = 0; combinations[50][0] = 0; combinations[51][0] = 0; + combinations[48][1] = 0; combinations[49][1] = 0; combinations[50][1] = 0; combinations[51][1] = 0; + combinations[48][2] = 49; combinations[49][2] = 53; combinations[50][2] = 57; combinations[51][2] = 61; + combinations[48][3] = 33; combinations[49][3] = 37; combinations[50][3] = 41; combinations[51][3] = 45; + combinations[48][4] = 17; combinations[49][4] = 21; combinations[50][4] = 25; combinations[51][4] = 29; + combinations[48][5] = 1; combinations[49][5] = 5; combinations[50][5] = 9; combinations[51][5] = 13; + + combinations[52][0] = 0; combinations[53][0] = 0; combinations[54][0] = 0; combinations[55][0] = 0; + combinations[52][1] = 0; combinations[53][1] = 0; combinations[54][1] = 0; combinations[55][1] = 0; + combinations[52][2] = 48; combinations[53][2] = 52; combinations[54][2] = 56; combinations[55][2] = 60; + combinations[52][3] = 32; combinations[53][3] = 36; combinations[54][3] = 40; combinations[55][3] = 44; + combinations[52][4] = 16; combinations[53][4] = 20; combinations[54][4] = 24; combinations[55][4] = 28; + combinations[52][5] = 0; combinations[53][5] = 4; combinations[54][5] = 8; combinations[55][5] = 12; + + // Diagonal, X + + combinations[56][0] = 0; combinations[57][0] = 0; combinations[58][0] = 0; combinations[59][0] = 0; + combinations[56][1] = 0; combinations[57][1] = 0; combinations[58][1] = 0; combinations[59][1] = 0; + combinations[56][2] = 51; combinations[57][2] = 50; combinations[58][2] = 49; combinations[59][2] = 48; + combinations[56][3] = 39; combinations[57][3] = 38; combinations[58][3] = 37; combinations[59][3] = 36; + combinations[56][4] = 27; combinations[57][4] = 26; combinations[58][4] = 25; combinations[59][4] = 24; + combinations[56][5] = 15; combinations[57][5] = 14; combinations[58][5] = 13; combinations[59][5] = 12; + + combinations[60][0] = 0; combinations[61][0] = 0; combinations[62][0] = 0; combinations[63][0] = 0; + combinations[60][1] = 0; combinations[61][1] = 0; combinations[62][1] = 0; combinations[63][1] = 0; + combinations[60][2] = 3; combinations[61][2] = 2; combinations[62][2] = 1; combinations[63][2] = 0; + combinations[60][3] = 23; combinations[61][3] = 22; combinations[62][3] = 21; combinations[63][3] = 20; + combinations[60][4] = 43; combinations[61][4] = 42; combinations[62][4] = 41; combinations[63][4] = 40; + combinations[60][5] = 63; combinations[61][5] = 62; combinations[62][5] = 61; combinations[63][5] = 60; + + // Diagonal, Y + + combinations[64][0] = 0; combinations[65][0] = 0; combinations[66][0] = 0; combinations[67][0] = 0; + combinations[64][1] = 0; combinations[65][1] = 0; combinations[66][1] = 0; combinations[67][1] = 0; + combinations[64][2] = 63; combinations[65][2] = 59; combinations[66][2] = 55; combinations[67][2] = 51; + combinations[64][3] = 46; combinations[65][3] = 42; combinations[66][3] = 38; combinations[67][3] = 34; + combinations[64][4] = 29; combinations[65][4] = 25; combinations[66][4] = 21; combinations[67][4] = 17; + combinations[64][5] = 12; combinations[65][5] = 8; combinations[66][5] = 4; combinations[67][5] = 0; + + combinations[68][0] = 0; combinations[69][0] = 0; combinations[70][0] = 0; combinations[71][0] = 0; + combinations[68][1] = 0; combinations[69][1] = 0; combinations[70][1] = 0; combinations[71][1] = 0; + combinations[68][2] = 15; combinations[69][2] = 11; combinations[70][2] = 7; combinations[71][2] = 3; + combinations[68][3] = 30; combinations[69][3] = 26; combinations[70][3] = 22; combinations[71][3] = 18; + combinations[68][4] = 45; combinations[69][4] = 41; combinations[70][4] = 37; combinations[71][4] = 33; + combinations[68][5] = 60; combinations[69][5] = 56; combinations[70][5] = 52; combinations[71][5] = 48; + + // Corner to Corner + + combinations[72][0] = 0; combinations[73][0] = 0; combinations[74][0] = 0; combinations[75][0] = 0; + combinations[72][1] = 0; combinations[73][1] = 0; combinations[74][1] = 0; combinations[75][1] = 0; + combinations[72][2] = 0; combinations[73][2] = 3; combinations[74][2] = 12; combinations[75][2] = 15; + combinations[72][3] = 21; combinations[73][3] = 22; combinations[74][3] = 25; combinations[75][3] = 26; + combinations[72][4] = 42; combinations[73][4] = 41; combinations[74][4] = 38; combinations[75][4] = 37; + combinations[72][5] = 63; combinations[73][5] = 60; combinations[74][5] = 51; combinations[75][5] = 48; + + // Initialize the combination flags to zero. + for (int i=0; i<76; i++) + combinations[i][6] = 0; + + // Set up the pos_to_comb array to point to every winning combination that a given + // position may have. + setup_pos_to_comb(); + + // Set up the best_picks array. + update_best_picks(); + } + + + /** + * Initialize the "outside four" array. + */ + public void init_outside_four() { + for (int i=0; i<18; i++) { + outside_four[i][0] = 0; + outside_four[i][1] = 0; + outside_four[i][2] = faces[i][ 2]; + outside_four[i][3] = faces[i][ 5]; + outside_four[i][4] = faces[i][14]; + outside_four[i][5] = faces[i][17]; + } + } + + + /** + * Initialize the "inside four" array. + */ + public void init_inside_four() { + for (int i=0; i<18; i++) { + inside_four[i][0] = 0; + inside_four[i][1] = 0; + inside_four[i][2] = faces[i][ 7]; + inside_four[i][3] = faces[i][ 8]; + inside_four[i][4] = faces[i][11]; + inside_four[i][5] = faces[i][12]; + } + } + + /** + * Initialize the "faces" array. + */ + public void init_faces () { + + faces[ 0][ 0] = 0; + faces[ 0][ 1] = 0; + faces[ 0][ 2] = 12; faces[ 0][ 6] = 13; faces[ 0][10] = 14; faces[ 0][14] = 15; + faces[ 0][ 3] = 8; faces[ 0][ 7] = 9; faces[ 0][11] = 10; faces[ 0][15] = 11; + faces[ 0][ 4] = 4; faces[ 0][ 8] = 5; faces[ 0][12] = 6; faces[ 0][16] = 7; + faces[ 0][ 5] = 0; faces[ 0][ 9] = 1; faces[ 0][13] = 2; faces[ 0][17] = 3; + + faces[ 1][ 0] = 0; + faces[ 1][ 1] = 0; + faces[ 1][ 2] = 28; faces[ 1][ 6] = 29; faces[ 1][10] = 30; faces[ 1][14] = 31; + faces[ 1][ 3] = 24; faces[ 1][ 7] = 25; faces[ 1][11] = 26; faces[ 1][15] = 27; + faces[ 1][ 4] = 20; faces[ 1][ 8] = 21; faces[ 1][12] = 22; faces[ 1][16] = 23; + faces[ 1][ 5] = 16; faces[ 1][ 9] = 17; faces[ 1][13] = 18; faces[ 1][17] = 19; + + faces[ 2][ 0] = 0; + faces[ 2][ 1] = 0; + faces[ 2][ 2] = 44; faces[ 2][ 6] = 45; faces[ 2][10] = 46; faces[ 2][14] = 47; + faces[ 2][ 3] = 40; faces[ 2][ 7] = 41; faces[ 2][11] = 42; faces[ 2][15] = 43; + faces[ 2][ 4] = 36; faces[ 2][ 8] = 37; faces[ 2][12] = 38; faces[ 2][16] = 39; + faces[ 2][ 5] = 32; faces[ 2][ 9] = 33; faces[ 2][13] = 34; faces[ 2][17] = 35; + + faces[ 3][ 0] = 0; + faces[ 3][ 1] = 0; + faces[ 3][ 2] = 60; faces[ 3][ 6] = 61; faces[ 3][10] = 62; faces[ 3][14] = 63; + faces[ 3][ 3] = 56; faces[ 3][ 7] = 57; faces[ 3][11] = 58; faces[ 3][15] = 59; + faces[ 3][ 4] = 52; faces[ 3][ 8] = 53; faces[ 3][12] = 54; faces[ 3][16] = 55; + faces[ 3][ 5] = 48; faces[ 3][ 9] = 49; faces[ 3][13] = 50; faces[ 3][17] = 51; + + faces[ 4][ 0] = 0; + faces[ 4][ 1] = 0; + faces[ 4][ 2] = 12; faces[ 4][ 6] = 28; faces[ 4][10] = 44; faces[ 4][14] = 60; + faces[ 4][ 3] = 8; faces[ 4][ 7] = 24; faces[ 4][11] = 40; faces[ 4][15] = 56; + faces[ 4][ 4] = 4; faces[ 4][ 8] = 20; faces[ 4][12] = 36; faces[ 4][16] = 52; + faces[ 4][ 5] = 0; faces[ 4][ 9] = 16; faces[ 4][13] = 32; faces[ 4][17] = 48; + + faces[ 5][ 0] = 0; + faces[ 5][ 1] = 0; + faces[ 5][ 2] = 13; faces[ 5][ 6] = 29; faces[ 5][10] = 45; faces[ 5][14] = 61; + faces[ 5][ 3] = 9; faces[ 5][ 7] = 25; faces[ 5][11] = 41; faces[ 5][15] = 57; + faces[ 5][ 4] = 5; faces[ 5][ 8] = 21; faces[ 5][12] = 37; faces[ 5][16] = 53; + faces[ 5][ 5] = 1; faces[ 5][ 9] = 17; faces[ 5][13] = 33; faces[ 5][17] = 49; + + faces[ 6][ 0] = 0; + faces[ 6][ 1] = 0; + faces[ 6][ 2] = 14; faces[ 6][ 6] = 30; faces[ 6][10] = 46; faces[ 6][14] = 62; + faces[ 6][ 3] = 10; faces[ 6][ 7] = 26; faces[ 6][11] = 42; faces[ 6][15] = 58; + faces[ 6][ 4] = 6; faces[ 6][ 8] = 22; faces[ 6][12] = 38; faces[ 6][16] = 54; + faces[ 6][ 5] = 2; faces[ 6][ 9] = 18; faces[ 6][13] = 34; faces[ 6][17] = 50; + + faces[ 7][ 0] = 0; + faces[ 7][ 1] = 0; + faces[ 7][ 2] = 15; faces[ 7][ 6] = 31; faces[ 7][10] = 47; faces[ 7][14] = 63; + faces[ 7][ 3] = 11; faces[ 7][ 7] = 27; faces[ 7][11] = 43; faces[ 7][15] = 59; + faces[ 7][ 4] = 7; faces[ 7][ 8] = 23; faces[ 7][12] = 39; faces[ 7][16] = 55; + faces[ 7][ 5] = 3; faces[ 7][ 9] = 19; faces[ 7][13] = 35; faces[ 7][17] = 51; + + faces[ 8][ 0] = 0; + faces[ 8][ 1] = 0; + faces[ 8][ 2] = 12; faces[ 8][ 6] = 28; faces[ 8][10] = 44; faces[ 8][14] = 60; + faces[ 8][ 3] = 13; faces[ 8][ 7] = 29; faces[ 8][11] = 45; faces[ 8][15] = 61; + faces[ 8][ 4] = 14; faces[ 8][ 8] = 30; faces[ 8][12] = 46; faces[ 8][16] = 62; + faces[ 8][ 5] = 15; faces[ 8][ 9] = 31; faces[ 8][13] = 47; faces[ 8][17] = 63; + + faces[ 9][ 0] = 0; + faces[ 9][ 1] = 0; + faces[ 9][ 2] = 8; faces[ 9][ 6] = 24; faces[ 9][10] = 40; faces[ 9][14] = 56; + faces[ 9][ 3] = 9; faces[ 9][ 7] = 25; faces[ 9][11] = 41; faces[ 9][15] = 57; + faces[ 9][ 4] = 10; faces[ 9][ 8] = 26; faces[ 9][12] = 42; faces[ 9][16] = 58; + faces[ 9][ 5] = 11; faces[ 9][ 9] = 27; faces[ 9][13] = 43; faces[ 9][17] = 59; + + faces[10][ 0] = 0; + faces[10][ 1] = 0; + faces[10][ 2] = 4; faces[10][ 6] = 20; faces[10][10] = 36; faces[10][14] = 52; + faces[10][ 3] = 5; faces[10][ 7] = 21; faces[10][11] = 37; faces[10][15] = 53; + faces[10][ 4] = 6; faces[10][ 8] = 22; faces[10][12] = 38; faces[10][16] = 54; + faces[10][ 5] = 7; faces[10][ 9] = 23; faces[10][13] = 39; faces[10][17] = 55; + + faces[11][ 0] = 0; + faces[11][ 1] = 0; + faces[11][ 2] = 0; faces[11][ 6] = 16; faces[11][10] = 32; faces[11][14] = 48; + faces[11][ 3] = 1; faces[11][ 7] = 17; faces[11][11] = 33; faces[11][15] = 49; + faces[11][ 4] = 2; faces[11][ 8] = 18; faces[11][12] = 34; faces[11][16] = 50; + faces[11][ 5] = 3; faces[11][ 9] = 19; faces[11][13] = 35; faces[11][17] = 51; + + faces[12][ 0] = 0; + faces[12][ 1] = 0; + faces[12][ 2] = 12; faces[12][ 6] = 13; faces[12][10] = 14; faces[12][14] = 15; + faces[12][ 3] = 24; faces[12][ 7] = 25; faces[12][11] = 26; faces[12][15] = 27; + faces[12][ 4] = 36; faces[12][ 8] = 37; faces[12][12] = 38; faces[12][16] = 39; + faces[12][ 5] = 48; faces[12][ 9] = 49; faces[12][13] = 50; faces[12][17] = 51; + + faces[13][ 0] = 0; + faces[13][ 1] = 0; + faces[13][ 2] = 0; faces[13][ 6] = 1; faces[13][10] = 2; faces[13][14] = 3; + faces[13][ 3] = 20; faces[13][ 7] = 21; faces[13][11] = 22; faces[13][15] = 23; + faces[13][ 4] = 40; faces[13][ 8] = 41; faces[13][12] = 42; faces[13][16] = 43; + faces[13][ 5] = 60; faces[13][ 9] = 61; faces[13][13] = 62; faces[13][17] = 63; + + faces[14][ 0] = 0; + faces[14][ 1] = 0; + faces[14][ 2] = 12; faces[14][ 6] = 28; faces[14][10] = 44; faces[14][14] = 60; + faces[14][ 3] = 9; faces[14][ 7] = 25; faces[14][11] = 41; faces[14][15] = 57; + faces[14][ 4] = 6; faces[14][ 8] = 22; faces[14][12] = 38; faces[14][16] = 54; + faces[14][ 5] = 3; faces[14][ 9] = 19; faces[14][13] = 35; faces[14][17] = 51; + + faces[15][ 0] = 0; + faces[15][ 1] = 0; + faces[15][ 2] = 15; faces[15][ 6] = 31; faces[15][10] = 47; faces[15][14] = 63; + faces[15][ 3] = 10; faces[15][ 7] = 26; faces[15][11] = 42; faces[15][15] = 58; + faces[15][ 4] = 5; faces[15][ 8] = 21; faces[15][12] = 37; faces[15][16] = 53; + faces[15][ 5] = 0; faces[15][ 9] = 16; faces[15][13] = 32; faces[15][17] = 48; + + faces[16][ 0] = 0; + faces[16][ 1] = 0; + faces[16][ 2] = 12; faces[16][ 6] = 29; faces[16][10] = 46; faces[16][14] = 63; + faces[16][ 3] = 8; faces[16][ 7] = 25; faces[16][11] = 42; faces[16][15] = 59; + faces[16][ 4] = 4; faces[16][ 8] = 21; faces[16][12] = 38; faces[16][16] = 55; + faces[16][ 5] = 0; faces[16][ 9] = 17; faces[16][13] = 34; faces[16][17] = 51; + + faces[17][ 0] = 0; + faces[17][ 1] = 0; + faces[17][ 2] = 15; faces[17][ 6] = 30; faces[17][10] = 45; faces[17][14] = 60; + faces[17][ 3] = 11; faces[17][ 7] = 26; faces[17][11] = 41; faces[17][15] = 56; + faces[17][ 4] = 7; faces[17][ 8] = 22; faces[17][12] = 37; faces[17][16] = 52; + faces[17][ 5] = 3; faces[17][ 9] = 18; faces[17][13] = 33; faces[17][17] = 48; + } + + /** + * Render the current face set in the 2D window. + */ + public void render2D(Graphics gc) { + + gc.setColor(background); + gc.fillRect(0, 0, width, height); + + int id; + int x, y; + + float begX; + float begY; + + for (int l=0; l<3; l++) { + begY = 28.0f + l*(5.f*23.3f); + for (int k=0; k<6; k++) { + begX = 11.65f + k*(5.f*11.65f); + int count = 0; + int face = l*6+k; + for (int i=0; i<4; i++) { + for (int j=0; j<4; j++) { + x = (int)begX + i*12; + y = (int)begY + j*12; + id = faces[face][count+2]; + if (occupied[id] == HUMAN) { + x -= 2; + y -= 2; + gc.setColor(red); + gc.fillRect(x, y, 5, 5); + } + else if (occupied[id] == MACHINE) { + x -= 2; + y -= 2; + gc.setColor(blue); + gc.fillRect(x, y, 5, 5); + } + else { + x -= 1; + y -= 1; + gc.setColor(gray); + gc.fillRect(x, y, 2, 2); + } + if (highlight[face]) { + gc.setColor(yellow); + positions.setHighlight(faces[face][count+2]); + } + count++; + } + } + if (highlight[face]) + gc.setColor(yellow); + else + gc.setColor(white); + if ((face+1)<10) + gc.drawString("Face "+(face+1), (int)begX-2, (int)begY+60); + else + gc.drawString("Face "+(face+1), (int)begX-4, (int)begY+60); + } + } + } + + /** + * Determine what position has been selected in the 2D window. + */ + public void checkSelection2D(int x, int y, int player) { + + int id; + int posX, posY; + + float begX; + float begY; + + for (int l=0; l<3; l++) { + begY = 28.0f + l*(5.f*23.3f); + for (int k=0; k<6; k++) { + begX = 11.65f + k*(5.f*11.65f); + int count = 0; + int face = l*6+k; + for (int i=0; i<4; i++) { + for (int j=0; j<4; j++) { + posX = (int)begX + i*12; + posY = (int)begY + j*12; + if (x > posX-4 && x < posX+4 && + y > posY-4 && y < posY+4) { + + id = faces[face][count+2]; + + if (occupied[id] == UNOCCUPIED) { + positions.set(id, player); + selection(id, player); + canvas.repaint(); + } + return; + } + count++; + } + } + if ((x > begX-4 && x < begX+40) && + (y > begY+45 && y < begY+60) ) { + + count = 0; + for (int i=0; i<4; i++) { + for (int j=0; j<4; j++) { + if (highlight[face]) + positions.clearHighlight(faces[face][count+2]); + count++; + } + } + if (highlight[face]) + highlight[face] = false; + else + highlight[face] = true; + canvas.repaint(); + } + } + } + + } + + + /** + * Record the player's move. + */ + public void selection(int pos, int player) { + + int num_combinations; + int comb; + + this.player = player; + + if (player == HUMAN) { + + // If position is already occupied, return. + if (occupied[pos] != 0) return; + + // Mark the position as HUMAN. + occupied[pos] = HUMAN; + + // Update the logic arrays. + this.player = update_logic_arrays(pos); + + // Have the computer determine its move. + choose_move(); + } + } + + + /** + * Determine the computer's move. + */ + public void choose_move () { + + if (player == MACHINE) { + + // Babe in the woods. + if (skill_level == 0) { + if (!block_winning_move()) { + if (!pick_7()) { + if (!check_outside_four()) { + pick_best_position(); + } + } + } + } + + // Walk and chew gum. + else if (skill_level == 1) { + if (!block_winning_move()) { + if (!block_intersecting_rows()) { + if (!block_inside_four()) { + if (!block_outside_four()) { + pick_best_position(); + } + } + } + } + } + + // Jeopordy contestant. + else if (skill_level == 2) { + if (!block_winning_move()) { + if (!block_intersecting_rows()) { + if (!block_inside_four()) { + if (!block_outside_four()) { + if (!pick_7()) { + pick_best_position(); + } + } + } + } + } + } + + // Rocket scientist. + else if (skill_level == 3) { + if (!block_winning_move()) { + if (!block_intersecting_rows()) { + if (!block_chair_move()) { + if (!check_face_three()) { + if (!block_central_four()) { + if (!block_inside_four()) { + if (!block_outside_four()) { + if (!take_inside_four()) { + if (!take_outside_four()) { + if (!pick_7()) { + if (!check_outside_four()) { + pick_best_position(); + } + } + } + } + } + } + } + } + } + } + } + } + + // Be afraid, be very afraid. + else if (skill_level == 4) { + if (!block_winning_move()) { + if (!block_intersecting_rows()) { + if (!block_chair_move()) { + if (!block_walk_move()) { + if (!block_central_four()) { + if (!block_inside_four()) { + if (!block_outside_four()) { + if (!check_face_three()) { + if (!check_intersecting_rows2()) { + if (!take_inside_four()) { + if (!take_outside_four()) { + if (!pick_7()) { + if (!check_outside_four()) { + pick_best_position(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + + /** + * Check for a winning move. + */ + public boolean block_winning_move() { + + // Loop through each combination and see if any player occupies + // three positions. If so, take the last remaining position. + int pos; + for (int i=0; i<76; i++) { + if (combinations[i][0] == 3) { + for (int j=2; j<6; j++) { + pos = combinations[i][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_winning_move: true"); + return true; + } + } + } + } + if (debug) System.out.println("check_winning_move: false"); + return false; + } + + + /** + * Block outside four + */ + public boolean block_outside_four() { + + int pos; + int index = 0; + int max = 0; + + // Block the opponent, if necessary. + for (int i=0; i<18; i++) { + if (outside_four[i][0] > 0 && + outside_four[i][1] == HUMAN) { + if(outside_four[i][0] > max) { + index = i; + max = outside_four[i][0]; + } + } + } + + if (max > 0) { + for (int j=2; j<6; j++) { + pos = outside_four[index][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_outside_four: true"); + return true; + } + } + } + + if (debug) System.out.println("block_outside_four: false"); + return false; + } + + + /** + * Block central four + */ + public boolean block_central_four() { + + int pos; + int index = 0; + int max = 0; + + // Block the opponent, if necessary. + for (int i=1; i<3; i++) { + if (inside_four[i][0] > 0 && + inside_four[i][1] == HUMAN) { + if(inside_four[i][0] > max) { + index = i; + max = inside_four[i][0]; + } + } + } + + if (max > 0) { + for (int j=2; j<6; j++) { + pos = inside_four[index][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_central_four: true"); + return true; + } + } + } + + if (debug) System.out.println("block_central_four: false"); + return false; + } + + /** + * Check each face for a forced win. + */ + public boolean check_face_three() { + + int pos; + int index = 0; + int human = 0; + int machine = 0; + + // Block the opponent from a forced win. + for (int i=0; i<18; i++) { + if (outside_four[i][0] == -1) { + human = 0; + machine = 0; + for (int j=2; j<6; j++) { + if (occupied[outside_four[i][j]] == MACHINE) + machine++; + else if (occupied[outside_four[i][j]] == HUMAN) + human++; + } + if (debug) System.out.println("machine = " + machine); + if (debug) System.out.println("human = " + human); + if (human == 3 && machine == 1) { + if (debug) System.out.println("human == 3 && machine == 1"); + for (int j=2; j<18; j++) { + pos = faces[i][j]; + if (occupied[pos] == 0) { + for (int k=0; k<76; k++) { + if (combinations[i][0] == 2 & + combinations[i][1] == HUMAN) { + for (int l=0; l<4; l++) { + if (combinations[i][l] == pos) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_face_three: true"); + return true; + } + } + } + } + } + } + } + } + } + + if (debug) System.out.println("check_face_three: false"); + return false; + } + + + + /** + * Block inside four + */ + public boolean block_inside_four() { + + int pos; + int index = 0; + int max = 0; + + // Block the opponent, if necessary. + for (int i=0; i<18; i++) { + if (inside_four[i][0] > 0 && + inside_four[i][1] == HUMAN) { + if(inside_four[i][0] > max) { + index = i; + max = inside_four[i][0]; + } + } + } + + if (max > 0) { + for (int j=2; j<6; j++) { + pos = inside_four[index][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_inside_four: true"); + return true; + } + } + } + + if (debug) System.out.println("block_inside_four: false"); + return false; + } + + + public boolean block_chair_move() { + + int pos; + + int ncorners = 0; // Number of corners owned by human + int corner = 0; // Corner owned by machine + + if (debug) System.out.println("inside block_chair_move"); + + // Loop through all of the faces. + for(int i=0; i<18; i++) { + + // Determine which corners the human owns. + if (occupied[faces[i][2]] == HUMAN) + ncorners++; + else if (occupied[faces[i][2]] == MACHINE) + corner = 2; + if (occupied[faces[i][5]] == HUMAN) + ncorners++; + else if (occupied[faces[i][5]] == MACHINE) + corner = 5; + if (occupied[faces[i][14]] == HUMAN) + ncorners++; + else if (occupied[faces[i][14]] == MACHINE) + corner = 14; + if (occupied[faces[i][17]] == HUMAN) + ncorners++; + else if (occupied[faces[i][17]] == MACHINE) + corner = 17; + + // If the human owns three corners, continue with the search. + if (ncorners == 3) { + if (corner == 2) { + if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][ 9]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][ 9]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 4]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][16]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + else if (corner == 5) { + if (occupied[faces[i][ 9]] == HUMAN && occupied[faces[i][ 6]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][10]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][13]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][10]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 4]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][ 7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + else if (corner == 14) { + if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][ 9]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][ 9]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][3]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][12]] == 0 && occupied[faces[i][15]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 6]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 9]] == 0 && + occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + else if (corner == 17) { + if (occupied[faces[i][ 9]] == HUMAN && occupied[faces[i][ 6]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][10]] == 0 && occupied[faces[i][11]] == 0) { + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][13]] == HUMAN && occupied[faces[i][ 6]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][10]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][15]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + } + ncorners = 0; + corner = -1; + } + if (debug) System.out.println("block_chair_move: false"); + return false; + } + + public boolean block_walk_move() { + + int pos; + + if (debug) System.out.println("inside block_walk_move"); + + // Loop through all of the faces. + for(int i=0; i<18; i++) { + + // Look for a matching pattern. + if (occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][14]] == HUMAN && + occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][15]] == HUMAN && + occupied[faces[i][ 6]] == 0 && occupied[faces[i][10]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][11]] == 0) { + + if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 9]] == 0) { + pos = faces[i][6]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][13]] == 0) { + pos = faces[i][10]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][14]] == HUMAN && occupied[faces[i][17]] == HUMAN && + occupied[faces[i][10]] == HUMAN && occupied[faces[i][13]] == HUMAN && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + + if (occupied[faces[i][7]] == HUMAN && occupied[faces[i][3]] == 0) { + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if (occupied[faces[i][8]] == HUMAN && occupied[faces[i][4]] == 0) { + pos = faces[i][16]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][16]] == HUMAN && + occupied[faces[i][ 5]] == HUMAN && occupied[faces[i][17]] == HUMAN && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][ 9]] == 0 && occupied[faces[i][13]] == 0) { + + if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][10]] == 0) { + pos = faces[i][18]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if (occupied[faces[i][7]] == HUMAN && occupied[faces[i][6]] == 0) { + pos = faces[i][9]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 9]] == HUMAN && + occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][ 5]] == HUMAN && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][ 3]] == 0 && occupied[faces[i][ 4]] == 0) { + + if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][15]] == 0) { + pos = faces[i][3]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][16]] == 0) { + pos = faces[i][4]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][14]] == HUMAN && + occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][16]] == HUMAN && + occupied[faces[i][ 6]] == 0 && occupied[faces[i][10]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0) { + + if ((occupied[faces[i][7]] == HUMAN && occupied[faces[i][9]] == 0) || + (occupied[faces[i][9]] == HUMAN && occupied[faces[i][7]] == 0) ) { + pos = faces[i][6]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][13]] == 0) || + (occupied[faces[i][13]] == HUMAN && occupied[faces[i][11]] == 0) ) { + pos = faces[i][10]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][14]] == HUMAN && occupied[faces[i][17]] == HUMAN && + occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 9]] == HUMAN && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0) { + + if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0) || + (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][11]] == 0) ) { + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if ((occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 4]] == 0) || + (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][12]] == 0) ) { + pos = faces[i][16]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][15]] == HUMAN && + occupied[faces[i][ 5]] == HUMAN && occupied[faces[i][17]] == HUMAN && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][ 9]] == 0 && occupied[faces[i][13]] == 0) { + + if ((occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 8]] == 0) || + (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 6]] == 0) ) { + pos = faces[i][9]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if ((occupied[faces[i][10]] == HUMAN && occupied[faces[i][12]] == 0) || + (occupied[faces[i][12]] == HUMAN && occupied[faces[i][10]] == 0) ) { + pos = faces[i][13]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][13]] == HUMAN && + occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][ 5]] == HUMAN && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][ 3]] == 0 && occupied[faces[i][ 4]] == 0) { + + if ((occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][15]] == 0) || + (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 7]] == 0) ) { + pos = faces[i][3]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if ((occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][16]] == 0) || + (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 8]] == 0) ) { + pos = faces[i][4]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + } + + if (debug) System.out.println("block_walk_move: false"); + return false; + } + + public boolean check_chair_move() { + + int pos; + + // If the "block chair flag" is set, all we need to do is + // block the winning path... + if (block_chair_flag) { + pos = faces[block_chair_face][block_chair_next_move]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: march"); + return true; + } + + int ncorners = 0; // Number of corners owned by human + int corner = 0; // Corner owned by machine + + // Loop through all of the faces. + for(int i=0; i<18; i++) { + + // Determine which corners the human owns. + if (faces[i][ 2] == HUMAN) + ncorners++; + else + corner = 2; + if (faces[i][ 5] == HUMAN) + ncorners++; + else + corner = 5; + if (faces[i][14] == HUMAN) + ncorners++; + else + corner = 14; + if (faces[i][17] == HUMAN) + ncorners++; + else + corner = 17; + + // If the human owns three corners, continue with the search. + if (ncorners == 3) { + if (corner == 2) { + if (faces[i][ 3] == HUMAN && faces[i][ 7] == 0 && + faces[i][ 8] == 0 && faces[i][11] == 0 && + faces[i][15] == 0 && faces[i][16] == 0) { + block_chair_flag = true; + block_chair_next_move = 11; + block_chair_face = i; + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (faces[i][ 4] == HUMAN && faces[i][ 8] == 0 && + faces[i][11] == 0 && faces[i][12] == 0 && + faces[i][15] == 0 && faces[i][16] == 0) { + block_chair_flag = true; + block_chair_next_move = 16; + block_chair_face = i; + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + else if (corner == 5) { + block_chair_flag = true; + block_chair_next_move = 11; + block_chair_face = i; + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_face_three: true"); + return true; + } + else if (corner == 14) { + block_chair_flag = true; + block_chair_next_move = 11; + block_chair_face = i; + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_face_three: true"); + return true; + } + else if (corner == 17) { + block_chair_flag = true; + block_chair_next_move = 11; + block_chair_face = i; + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_face_three: true"); + return true; + } + } + } + return false; + } + + /** + * Take inside four + */ + public boolean take_inside_four() { + + int pos = 0; + boolean found = false; + + if (occupied[21] == 0) { + found = true; + pos = 21; + } + else if (occupied[22] == 0) { + found = true; + pos = 22; + } + else if (occupied[25] == 0) { + found = true; + pos = 25; + } + else if (occupied[26] == 0) { + found = true; + pos = 26; + } + else if (occupied[37] == 0) { + found = true; + pos = 37; + } + else if (occupied[38] == 0) { + found = true; + pos = 38; + } + else if (occupied[41] == 0) { + found = true; + pos = 41; + } + else if (occupied[42] == 0) { + found = true; + pos = 42; + } + + if (found) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("take_inside_four: true"); + return true; + } + + if (debug) System.out.println("take_inside_four: false"); + return false; + } + + + /** + * Check occupancy of outside four. + */ + public boolean check_outside_four() { + + int pos = 0; + + // Finish off the four corner combination. + if (outside_four_flag) { + if (occupied[faces[face_index][7]] == 0) { + pos = faces[face_index][7]; + } + else if (occupied[faces[face_index][6]] == 0) { + pos = faces[face_index][6]; + } + + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a four corner combination. + for (int i=0; i<18; i++) { + if (outside_four[i][0] == 4 && + outside_four[i][1] == MACHINE) { + if (faces[i][0] > 0 && + faces[i][1] == MACHINE) { + if (occupied[faces[i][8]] == 0) { + pos = faces[i][8]; + outside_four_flag = true; + face_index = i; + } + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_outside_four: true"); + return true; + } + } + } + } + + // Take the corners, if available. + for (int i=0; i<18; i++) { + if (outside_four[i][0] > 0 && + outside_four[i][1] == MACHINE) { + if (faces[i][0] > 0 && + faces[i][1] == MACHINE) { + for (int j=2; j<6; j++) { + pos = outside_four[i][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_outside_four: true"); + return true; + } + } + } + } + } + + // Look for an "outside four" combination in a face in which the + // opponent holds no positions. + for (int i=0; i<18; i++) { + if (outside_four[i][0] == 0 || (outside_four[i][0] > 0 && + outside_four[i][1] == MACHINE)) { + + if (outside_four[i][1] == MACHINE) + outside_four_flag = true; + for (int j=2; j<6; j++) { + pos = outside_four[i][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_outside_four: true"); + return true; + } + } + } + } + + if (debug) System.out.println("check_outside_four: false"); + return false; + } + + + /** + * Take outside four + */ + public boolean take_outside_four() { + + int pos = 0; + boolean found = false; + + if (occupied[0] == 0) { + found = true; + pos = 0; + } + else if (occupied[3] == 0) { + found = true; + pos = 3; + } + else if (occupied[12] == 0) { + found = true; + pos = 12; + } + else if (occupied[15] == 0) { + found = true; + pos = 15; + } + else if (occupied[48] == 0) { + found = true; + pos = 48; + } + else if (occupied[51] == 0) { + found = true; + pos = 51; + } + else if (occupied[60] == 0) { + found = true; + pos = 60; + } + else if (occupied[63] == 0) { + found = true; + pos = 63; + } + + if (found) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("take_outside_four: true"); + return true; + } + + if (debug) System.out.println("take_outside_four: false"); + return false; + } + + + /** + * Check for a forced win by intersecting rows. Block + * if necessary. + */ + public boolean block_intersecting_rows() { + + int pos; + + // Loop through each row and check for rows that have two + // positions occupied by the human and two positions which are empty. + // Make sure that none of the empty positions in this row intersect + // with another row that also contains two positions held by the human. + // If so, block the row by taking the position at the intersection + // of these two row. + + // Loop through each row. + for (int i=0; i<76; i++) { + + // Look for a row that has two positions held by the human. + if (combinations[i][0] == 2 && combinations[i][1] == HUMAN) { + + if (debug) + System.out.println(" row " + i + "has 2 positions occupied by the human"); + + // Mark this row with a flag. + combinations[i][6] = 1; + + // Check each position in the row. + for (int j=2; j<6; j++) { + + // Look for the empty positions in the row. + pos = combinations[i][j]; + if (occupied[pos] == 0) { + + // Loop through the rows again. + for (int k=0; k<76; k++) { + + if (debug) System.out.println(" row " + k); + + // Look for another row that has two positions held + // by the human (and which is unmarked.) modified + if (combinations[k][0] == 2 && + combinations[k][1] == HUMAN && + combinations[k][6] == 0) { + + if (debug) + System.out.println("found an intersecting row: row " + k); + + // Check the positions in this row and see if + // any match the position we're looking for. If + // we find a match, grab the position and return. + for (int l=2; l<6; l++) { + if (pos == combinations[k][l]) { + combinations[i][6] = 0; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_intersecting_rows: true"); + return true; + } + } + } + } + } + } + + // Unmark the combination before moving on. + combinations[i][6] = 0; + } + + } + if (debug) System.out.println("block_intersecting_rows: false"); + return false; + } + + /** + * Check for a forced win by intersecting rows. Block + * if necessary. + */ + public boolean check_intersecting_rows2() { + + int pos; + + // Loop through each row and check for rows that have two + // positions occupied by the human and two positions which are empty. + // Make sure that none of the empty positions in this row intersect + // with another row that also contains two positions held by the human. + // If so, block the row by taking the position at the intersection + // of these two row. + + // Loop through each row. + for (int i=0; i<76; i++) { + + // Look for a row that has two positions held by the human. + if (combinations[i][0] == 2 && combinations[i][1] == HUMAN) { + + if (debug) { + System.out.println(" row " + i + "has 2 positions occupied by the human"); + } + + // Mark this row with a flag. + combinations[i][6] = 1; + + // Check each position in the row. + for (int j=2; j<6; j++) { + + // Look for the empty positions in the row. + pos = combinations[i][j]; + if (occupied[pos] == 0) { + + // Loop through the rows again. + for (int k=0; k<76; k++) { + + if (debug) System.out.println(" row " + k); + + // Look for another row that has two positions held + // by the human (and which is unmarked.) modified + if (combinations[k][0] == 1 && + combinations[k][1] == HUMAN && + combinations[k][6] == 0) { + + if (debug) + System.out.println("found an intersecting row: row " + k); + + // Check the positions in this row and see if + // any match the position we're looking for. If + // we find a match, grab the position and return. + for (int l=2; l<6; l++) { + if (pos == combinations[k][l]) { + combinations[i][6] = 0; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_intersecting_rows: true"); + return true; + } + } + } + } + } + } + + // Unmark the combination before moving on. + combinations[i][6] = 0; + } + + } + if (debug) System.out.println("check_intersecting_rows: false"); + return false; + } + + + /** + * Check for a forced win by intersecting rows. Block + * if necessary. + */ + public boolean check_for_two() { + + int pos; + + // Loop through the rows. + for (int i=0; i<76; i++) { + + // Look for a row that has two positions held + // by the human (and which is unmarked.) + if (combinations[i][0] == 2 && + combinations[i][1] == HUMAN && + combinations[i][6] == 0) { + + // Take the first available spot. + for (int j=2; j<6; j++) { + pos = combinations[i][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_for_two: true"); + return true; + } + } + + } + } + if (debug) System.out.println("check_for_two: false"); + return false; + } + + public void undo_move() { + + // Return if no moves are recorded + if (nmoves == 0) return; + + // Set the undo flag + undoFlag = true; + + // Undo the last two moves + positions.clear(moves[--nmoves]); + positions.clear(moves[--nmoves]); + + // Undo the winner flag in the positions object + positions.noWinner(); + + // Repaint the 2D canvas. + canvas.repaint(); + + // Reset the inside/outside flags + inside_four_flag = false; + outside_four_flag = false; + block_chair_flag = false; + + // Reset the board + for (int i=0; i<64; i++) { + occupied[i] = 0; + } + + // Reset the inside/outside arrays + for (int i=0; i<18; i++) { + inside_four[i][0] = 0; + inside_four[i][1] = 0; + outside_four[i][0] = 0; + outside_four[i][1] = 0; + } + + // Reset the faces array + for (int i=0; i<18; i++) { + faces[i][0] = 0; + faces[i][1] = 0; + } + + // Reset the combinations array + for (int i=0; i<76; i++) { + combinations[i][0] = 0; + combinations[i][1] = 0; + } + + if (nmoves == 0) { + undoFlag = false; + player = HUMAN; + return; + } + + // Update the logic arrays + int pos; + player = HUMAN; + for (int i=0; i + +Drag the mouse in the window + + + +
+
+If you were using a Java-capable browser, +you would see "FourByFour" instead of this paragraph. +
+
+
+ + diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.java new file mode 100644 index 0000000..744086c --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour.java @@ -0,0 +1,886 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.four_by_four; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.net.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import com.sun.j3d.utils.universe.SimpleUniverse; +import com.sun.j3d.utils.applet.MainFrame; + +/** + * Class FourByFour + * + * Description: High level class for the game FourByFour + * + * Version: 1.2 + * + */ +public class FourByFour extends Applet implements ActionListener { + + String host; // Host from which this applet came from + int port; // Port number for writing high scores + Image backbuffer2D; // Backbuffer image used for 2D double buffering + int width, height; // Size of the graphics window in pixels + int score; // Final game score + int level_weight; // Weighting factor for skill level + int move_weight; // Weighting factor for number of moves to win + int time_weight; // Weighting factor for amount of time it took to win + int skill_level; // Skill level, 0 - 4 + Canvas2D canvas2D; // 2D rendering canvas + Canvas3D canvas3D; // 3D rendering canvas + Board board; // Game board object + Panel b_container; // Container to hold the buttons + Panel c_container; // Container to hold the canvas + Panel l_container; // Container to hold the labels + Panel skill_panel; // Panel to hold skill levels + Panel instruct_panel; // Panel to hold instructions + Panel winner_panel; // Panel to hold winner announcement + Panel high_panel; // Panel to hold high scores + Button instruct_button; // Instructions button + Button new_button; // New Game button + Button skill_button; // Skill Level button + Button high_button; // High Scores button + Button undo_button; // Undo Move button + Label skill_label; // Label on skill panel + Label winner_label; // Label on winner panel + Label winner_score_label; // Score label on winner panel + Label winner_name_label; // Name label on winner panel + Label winner_top_label; // Top 20 label on winner panel + Label high_label; // High score label + Label high_places[]; // Labels to hold places + Label high_names[]; // Labels to hold names + Label high_scores[]; // Labels to hold scores + TextArea instruct_text; // TextArea object that holds instructions + TextArea high_text; // TextArea object that holds top 20 scores + TextField winner_name; // TextField object that holds winner's name + Button instruct_return_button; // Return button for instruction panel + Button skill_return_button; // Return button for skill level panel + Button winner_return_button; // Return button for winner panel + Button high_return_button; // Return button for high scores panel + CheckboxGroup group; // CheckboxGroup object for skill level panel + InputStream inStream; // Input stream for reading instructions and high scores + OutputStream outStream; // Output stream for writing high scores + static boolean appletFlag = true; // Applet flag + boolean winner_flag = false; // Winner flag + byte text[]; // Temporary storage area for reading instructions file + byte outText[]; // Temporary storage area for writing high scores file + String textString; // Storage area for instructions + String scoresString; // String used for writing high scores file + int places[]; // Storage area for high score places + int scores[]; // Storage area for high score scores + String names[]; // Storage area for high score names + Positions positions; // Positions object, used to render player positions + + private SimpleUniverse universe = null; + + /** + * Initialization + */ + public void init() { + + // Set the port number. + port = 4111; + + // Set the graphics window size. + width = 350; + height = 350; + + // Set the weighting factors used for scoring. + level_weight = 1311; + move_weight = 111; + time_weight = 1000; + + // Create the "base" color for the AWT components. + setBackground(new Color(200, 200, 200)); + + // Read the instructions file. + if (appletFlag) { + + // Get the host from which this applet came. + host = getCodeBase().getHost(); + + try { + inStream = new BufferedInputStream + (new URL(getCodeBase(), "instructions.txt").openStream(), 8192); + text = new byte[5000]; + int character = inStream.read(); + int count = 0; + while (character != -1) { + text[count++] = (byte) character; + character = inStream.read(); + } + textString = new String(text); + inStream.close(); + } + catch(Exception e) { + System.out.println("Error: " + e.toString()); + } + } + else { + + try { + inStream = new BufferedInputStream + (new FileInputStream("instructions.txt")); + text = new byte[5000]; + int character = inStream.read(); + int count = 0; + while (character != -1) { + text[count++] = (byte) character; + character = inStream.read(); + } + textString = new String(text); + inStream.close(); + } + catch(Exception e) { + System.out.println("Error: " + e.toString()); + } + } + + // Read the high-scores file. + places = new int[20]; + scores = new int[20]; + names = new String[20]; + if (appletFlag) { + try { + inStream = new BufferedInputStream + (new URL(getCodeBase(), "scores.txt").openStream(), 8192); + Reader read = new BufferedReader(new InputStreamReader(inStream)); + StreamTokenizer st = new StreamTokenizer(read); + st.whitespaceChars(32,44); + st.eolIsSignificant(false); + + int count = 0; + int token = st.nextToken(); + boolean scoreFlag = true; + String string; + while (count<20) { + places[count] = (int) st.nval; + string = new String(""); + token = st.nextToken(); + while (token == StreamTokenizer.TT_WORD) { + string += st.sval; + string += " "; + token = st.nextToken(); + } + names[count] = string; + scores[count] = (int) st.nval; + token = st.nextToken(); + count++; + } + inStream.close(); + } + catch(Exception e) { + System.out.println("Error: " + e.toString()); + } + } + else { + try { + inStream = new BufferedInputStream + (new FileInputStream("scores.txt")); + Reader read = new BufferedReader(new InputStreamReader(inStream)); + StreamTokenizer st = new StreamTokenizer(read); + st.whitespaceChars(32,44); + st.eolIsSignificant(false); + + int count = 0; + int token = st.nextToken(); + boolean scoreFlag = true; + String string; + while (count<20) { + places[count] = (int) st.nval; + string = new String(""); + token = st.nextToken(); + while (token == StreamTokenizer.TT_WORD) { + string += st.sval; + string += " "; + token = st.nextToken(); + } + names[count] = string; + scores[count] = (int) st.nval; + token = st.nextToken(); + count++; + } + inStream.close(); + } + catch(Exception e) { + System.out.println("Error: " + e.toString()); + } + } + + // The positions object sets up the switch nodes which + // control the rendering of the player's positions. + positions = new Positions(); + + // Create the game board object which is responsible + // for keeping track of the moves on the game board + // and determining what move the computer should make. + board = new Board(this, positions, width, height); + positions.setBoard(board); + + // Create a 2D graphics canvas. + canvas2D = new Canvas2D(board); + canvas2D.setSize(width, height); + canvas2D.setLocation(width+10, 5); + canvas2D.addMouseListener(canvas2D); + board.setCanvas(canvas2D); + + // Create the 2D backbuffer + backbuffer2D = createImage(width, height); + canvas2D.setBuffer(backbuffer2D); + + // Create a 3D graphics canvas. + canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + canvas3D.setSize(width, height); + canvas3D.setLocation(5, 5); + + // Create the scene branchgroup. + BranchGroup scene3D = createScene3D(); + + // Create a universe with the Java3D universe utility. + universe = new SimpleUniverse(canvas3D); + universe.addBranchGraph(scene3D); + + // Use parallel projection. + View view = universe.getViewer().getView(); + view.setProjectionPolicy(View.PARALLEL_PROJECTION); + + // Set the universe Transform3D object. + TransformGroup tg = + universe.getViewingPlatform().getViewPlatformTransform(); + Transform3D transform = new Transform3D(); + transform.set(65.f, new Vector3f(0.0f, 0.0f, 400.0f)); + tg.setTransform(transform); + + // Create the canvas container. + c_container = new Panel(); + c_container.setSize(720, 360); + c_container.setLocation(0, 0); + c_container.setVisible(true); + c_container.setLayout(null); + add(c_container); + + // Add the 2D and 3D canvases to the container. + c_container.add(canvas2D); + c_container.add(canvas3D); + + // Turn off the layout manager, widgets will be sized + // and positioned explicitly. + setLayout(null); + + // Create the button container. + b_container = new Panel(); + b_container.setSize(720, 70); + b_container.setLocation(0, 360); + b_container.setVisible(true); + b_container.setLayout(null); + + // Create the buttons. + instruct_button = new Button("Instructions"); + instruct_button.setSize(135, 25); + instruct_button.setLocation(10, 10); + instruct_button.setVisible(true); + instruct_button.addActionListener(this); + + new_button = new Button("New Game"); + new_button.setSize(135, 25); + new_button.setLocation(150, 10); + new_button.setVisible(true); + new_button.addActionListener(this); + + undo_button = new Button("Undo Move"); + undo_button.setSize(135, 25); + undo_button.setLocation(290, 10); + undo_button.setVisible(true); + undo_button.addActionListener(this); + + skill_button = new Button("Skill Level"); + skill_button.setSize(135, 25); + skill_button.setLocation(430, 10); + skill_button.setVisible(true); + skill_button.addActionListener(this); + + high_button = new Button("High Scores"); + high_button.setSize(135, 25); + high_button.setLocation(570, 10); + high_button.setVisible(true); + high_button.addActionListener(this); + + b_container.add(new_button); + b_container.add(undo_button); + b_container.add(skill_button); + b_container.add(high_button); + b_container.add(instruct_button); + + // Add the button container to the applet. + add(b_container); + + // Create the "Skill Level" dialog box. + skill_panel = new Panel(); + skill_panel.setSize(400, 300); + skill_panel.setLocation(200, 20); + skill_panel.setLayout(null); + + skill_label = new Label("Pick your skill level:"); + skill_label.setSize(200, 25); + skill_label.setLocation(25, 20); + skill_label.setVisible(true); + skill_panel.add(skill_label); + + group = new CheckboxGroup(); + Checkbox skill_1 = new Checkbox("Babe in the Woods ", group, false); + Checkbox skill_2 = new Checkbox("Walk and Chew Gum ", group, false); + Checkbox skill_3 = new Checkbox("Jeopardy Contestant ", group, false); + Checkbox skill_4 = new Checkbox("Rocket Scientist ", group, false); + Checkbox skill_5 = new Checkbox("Be afraid, be very afraid", group, true); + skill_1.setSize(170, 25); + skill_1.setLocation(80, 60); + skill_1.setVisible(true); + skill_2.setSize(170, 25); + skill_2.setLocation(80, 100); + skill_2.setVisible(true); + skill_3.setSize(170, 25); + skill_3.setLocation(80, 140); + skill_3.setVisible(true); + skill_4.setSize(170, 25); + skill_4.setLocation(80, 180); + skill_4.setVisible(true); + skill_5.setSize(170, 25); + skill_5.setLocation(80, 220); + skill_5.setVisible(true); + skill_return_button = new Button("Return"); + skill_return_button.setSize(120, 25); + skill_return_button.setLocation(300, 370); + skill_return_button.setVisible(false); + skill_return_button.addActionListener(this); + skill_panel.add(skill_1); + skill_panel.add(skill_2); + skill_panel.add(skill_3); + skill_panel.add(skill_4); + skill_panel.add(skill_5); + skill_panel.setVisible(false); + add(skill_return_button); + add(skill_panel); + + // Create the "Instructions" panel. + instruct_return_button = new Button("Return"); + instruct_return_button.setLocation(300, 370); + instruct_return_button.setSize(120, 25); + instruct_return_button.setVisible(false); + instruct_return_button.addActionListener(this); + instruct_text = + new TextArea(textString, 100, 200, TextArea.SCROLLBARS_VERTICAL_ONLY); + instruct_text.setSize(715, 350); + instruct_text.setLocation(0, 0); + instruct_text.setVisible(false); + add(instruct_text); + + add(instruct_return_button); + + high_panel = new Panel(); + high_panel.setSize(715, 350); + high_panel.setLocation(0, 0); + high_panel.setVisible(false); + high_panel.setLayout(null); + + high_label = new Label("High Scores"); + high_label.setLocation(330, 5); + high_label.setSize(200, 30); + high_label.setVisible(true); + high_panel.add(high_label); + + high_places = new Label[20]; + high_names = new Label[20]; + high_scores = new Label[20]; + for (int i=0; i<20; i++) { + high_places[i] = new Label(Integer.toString(i+1)); + high_places[i].setSize(20, 30); + high_places[i].setVisible(true); + high_names[i] = new Label(names[i]); + high_names[i].setSize(150, 30); + high_names[i].setVisible(true); + high_scores[i] = new Label(Integer.toString(scores[i])); + high_scores[i].setSize(150, 30); + high_scores[i].setVisible(true); + if (i<10) { + high_places[i].setLocation(70, i*30+40); + high_names[i].setLocation(100, i*30+40); + high_scores[i].setLocation(260, i*30+40); + } + else { + high_places[i].setLocation(425, (i-10)*30+40); + high_names[i].setLocation(455, (i-10)*30+40); + high_scores[i].setLocation(615, (i-10)*30+40); + } + high_panel.add(high_places[i]); + high_panel.add(high_names[i]); + high_panel.add(high_scores[i]); + } + high_return_button = new Button("Return"); + high_return_button.setSize(120, 25); + high_return_button.setLocation(300, 370); + high_return_button.setVisible(false); + high_return_button.addActionListener(this); + add(high_return_button); + add(high_panel); + + // Create the "Winner" dialog box + winner_panel = new Panel(); + winner_panel.setLayout(null); + winner_panel.setSize(600, 500); + winner_panel.setLocation(0, 0); + winner_return_button = new Button("Return"); + winner_return_button.setSize(120, 25); + winner_return_button.setLocation(300, 360); + winner_return_button.addActionListener(this); + winner_panel.add(winner_return_button); + winner_label = new Label(""); + winner_label.setSize(200, 30); + winner_label.setLocation(270, 110); + winner_score_label = new Label(""); + winner_score_label.setSize(200, 30); + winner_top_label = new Label("You have a score in the top 20."); + winner_top_label.setSize(200, 25); + winner_top_label.setLocation(260, 185); + winner_top_label.setVisible(false); winner_name_label = new Label("Enter your name here:"); + winner_name_label.setSize(150, 25); + winner_name_label.setLocation(260, 210); + winner_name_label.setVisible(false); + winner_name = new TextField(""); + winner_name.setSize(200, 30); + winner_name.setLocation(260, 240); + winner_name.setVisible(false); + winner_panel.add(winner_label); + winner_panel.add(winner_score_label); + winner_panel.add(winner_top_label); + winner_panel.add(winner_name_label); + winner_panel.add(winner_name); + winner_panel.setVisible(false); + add(winner_panel); + } + + public void destroy() { + universe.cleanup(); + } + + /** + * Create the scenegraph for the 3D view. + */ + public BranchGroup createScene3D() { + + // Define colors + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f red = new Color3f(0.80f, 0.20f, 0.2f); + Color3f ambient = new Color3f(0.25f, 0.25f, 0.25f); + Color3f diffuse = new Color3f(0.7f, 0.7f, 0.7f); + Color3f specular = new Color3f(0.9f, 0.9f, 0.9f); + Color3f ambientRed = new Color3f(0.2f, 0.05f, 0.0f); + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + + // Create the branch group + BranchGroup branchGroup = new BranchGroup(); + + // Create the bounding leaf node + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 1000.0); + BoundingLeaf boundingLeaf = new BoundingLeaf(bounds); + branchGroup.addChild(boundingLeaf); + + // Create the background + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + branchGroup.addChild(bg); + + // Create the ambient light + AmbientLight ambLight = new AmbientLight(white); + ambLight.setInfluencingBounds(bounds); + branchGroup.addChild(ambLight); + + // Create the directional light + Vector3f dir = new Vector3f(-1.0f, -1.0f, -1.0f); + DirectionalLight dirLight = new DirectionalLight(white, dir); + dirLight.setInfluencingBounds(bounds); + branchGroup.addChild(dirLight); + + // Create the pole appearance + Material poleMaterial = + new Material(ambient, black, diffuse, specular, 110.f); + poleMaterial.setLightingEnable(true); + Appearance poleAppearance = new Appearance(); + poleAppearance.setMaterial(poleMaterial); + + // Create the transform group node + TransformGroup transformGroup = new TransformGroup(); + transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + branchGroup.addChild(transformGroup); + + // Create the poles + Poles poles = new Poles(poleAppearance); + transformGroup.addChild(poles.getChild()); + + // Add the position markers to the transform group + transformGroup.addChild(positions.getChild()); + + // Let the positions object know about the transform group + positions.setTransformGroup(transformGroup); + + // Create the mouse pick and drag behavior node + PickDragBehavior behavior = new PickDragBehavior(canvas2D, canvas3D, positions, + branchGroup, transformGroup); + behavior.setSchedulingBounds(bounds); + transformGroup.addChild(behavior); + + return branchGroup; + } + + public void actionPerformed (ActionEvent event) { + + Object target = event.getSource(); + + // Process the button events. + if (target == skill_return_button) { + skill_panel.setVisible(false); + skill_return_button.setVisible(false); + c_container.setVisible(true); + b_container.setVisible(true); + newGame(); + } + else if (target == winner_return_button) { + if (winner_flag) { + String name = winner_name.getText(); + String tmp_name = new String(""); + int tmp_score = 0; + boolean insert_flag = false; + winner_flag = false; + for (int i=0; i<20; i++) { + if (insert_flag) { + name = names[i]; + score = scores[i]; + names[i] = tmp_name; + scores[i] = tmp_score; + tmp_name = name; + tmp_score = score; + } + if (!insert_flag && score > scores[i]) { + tmp_name = names[i]; + tmp_score = scores[i]; + scores[i] = score; + names[i] = name; + insert_flag = true; + } + high_names[i].setText(names[i]); + high_scores[i].setText(Integer.toString(scores[i])); + } + scoresString = new String(""); + int place; + for (int i=0; i<20; i++) { + place = (int) places[i]; + scoresString += Integer.toString(place); + scoresString += "\t"; + scoresString += names[i]; + scoresString += " "; + scoresString += Integer.toString(scores[i]); + scoresString += "\n"; + } + + if (appletFlag) { + // Use this section of code when writing the high + // scores file back to a server. Requires the use + // of a deamon on the server to receive the socket + // connection. + // + // Create the output stream. + // try { + // Socket socket = new Socket(host, port); + // outStream = new BufferedOutputStream + // (socket.getOutputStream(), 8192); + // } + // catch(IOException ioe) { + // System.out.println("Error: " + ioe.toString()); + // } + // System.out.println("Output stream opened"); + // + // Write the scores to the file back on the server. + // outText = scoresString.getBytes(); + // try { + // outStream.write(outText); + // outStream.flush(); + // outStream.close(); + // outStream = null; + // } + // catch (IOException ioe) { + // System.out.println("Error: " + ioe.toString()); + // } + // System.out.println("Output stream written"); + + try { + OutputStreamWriter outFile = + new OutputStreamWriter(new FileOutputStream("scores.txt")); + outFile.write(scoresString); + outFile.flush(); + outFile.close(); + outFile = null; + } + catch (IOException ioe) { + System.out.println("Error: " + ioe.toString()); + } + catch (Exception e) { + System.out.println("Error: " + e.toString()); + } + } + else { + + try { + OutputStreamWriter outFile = + new OutputStreamWriter(new FileOutputStream("scores.txt")); + outFile.write(scoresString); + outFile.flush(); + outFile.close(); + outFile = null; + } + catch (IOException ioe) { + System.out.println("Error: " + ioe.toString()); + } + } + } + winner_panel.setVisible(false); + winner_return_button.setVisible(false); + winner_label.setVisible(false); + winner_score_label.setVisible(false); + winner_name_label.setVisible(false); + winner_top_label.setVisible(false); + winner_name.setVisible(false); + c_container.setVisible(true); + b_container.setVisible(true); + } + else if (target == high_return_button) { + high_return_button.setVisible(false); + high_panel.setVisible(false); + c_container.setVisible(true); + b_container.setVisible(true); + } + else if (target == instruct_return_button) { + instruct_text.setVisible(false); + instruct_return_button.setVisible(false); + instruct_text.repaint(); + c_container.setVisible(true); + b_container.setVisible(true); + } + else if (target == undo_button) { + board.undo_move(); + canvas2D.repaint(); + } + else if (target == instruct_button) { + c_container.setVisible(false); + b_container.setVisible(false); + instruct_text.setVisible(true); + instruct_return_button.setVisible(true); + } + else if (target == new_button) { + newGame(); + } + else if (target == skill_button) { + c_container.setVisible(false); + b_container.setVisible(false); + skill_panel.setVisible(true); + skill_return_button.setVisible(true); + } + else if (target == high_button) { + // Read the high scores file. + if (appletFlag) { + try { + inStream = new BufferedInputStream + (new URL(getCodeBase(), "scores.txt").openStream(), 8192); + Reader read = new BufferedReader(new InputStreamReader(inStream)); + StreamTokenizer st = new StreamTokenizer(read); + st.whitespaceChars(32,44); + st.eolIsSignificant(false); + + int count = 0; + int token = st.nextToken(); + boolean scoreFlag = true; + String string; + while (count<20) { + places[count] = (int) st.nval; + string = new String(""); + token = st.nextToken(); + while (token == StreamTokenizer.TT_WORD) { + string += st.sval; + string += " "; + token = st.nextToken(); + } + names[count] = string; + scores[count] = (int) st.nval; + token = st.nextToken(); + count++; + } + inStream.close(); + } + catch(Exception ioe) { + System.out.println("Error: " + ioe.toString()); + } + } + else { + try { + inStream = new BufferedInputStream + (new FileInputStream("scores.txt")); + Reader read = new BufferedReader(new InputStreamReader(inStream)); + StreamTokenizer st = new StreamTokenizer(read); + st.whitespaceChars(32,44); + st.eolIsSignificant(false); + + int count = 0; + int token = st.nextToken(); + boolean scoreFlag = true; + String string; + while (count<20) { + places[count] = (int) st.nval; + string = new String(""); + token = st.nextToken(); + while (token == StreamTokenizer.TT_WORD) { + string += st.sval; + string += " "; + token = st.nextToken(); + } + names[count] = string; + scores[count] = (int) st.nval; + token = st.nextToken(); + count++; + } + inStream.close(); + } + catch(Exception ioe) { + System.out.println("Error: " + ioe.toString()); + } + } + c_container.setVisible(false); + b_container.setVisible(false); + high_panel.setVisible(true); + high_return_button.setVisible(true); + } + + Checkbox box = group.getSelectedCheckbox(); + String label = box.getLabel(); + if (label.equals("Babe in the Woods ")) { + board.set_skill_level(0); + } + else if (label.equals("Walk and Chew Gum ")) { + board.set_skill_level(1); + } + else if (label.equals("Jeopardy Contestant ")) { + board.set_skill_level(2); + } + else if (label.equals("Rocket Scientist ")) { + board.set_skill_level(3); + } + else if (label.equals("Be afraid, be very afraid")) { + board.set_skill_level(4); + } + } + + public void newGame() { + board.newGame(); + canvas2D.repaint(); + } + + public void start() { + if (appletFlag) showStatus("FourByFour"); + } + + public void winner(int player, int level, int nmoves, long time) { + + if (player == 1) { + score = level * level_weight + + (66 - nmoves) * move_weight - + (int) Math.min(time * time_weight, 5000); + winner_label.setText("Game over, you win!"); + winner_label.setLocation(290, 90); + winner_score_label.setText("Score = " + score); + winner_score_label.setVisible(true); + winner_score_label.setLocation(315, 120); + if (score > scores[19]) { + winner_name_label.setVisible(true); + winner_top_label.setVisible(true); + winner_name.setVisible(true); + winner_flag = true; + } + } + else { + winner_label.setText("Game over, the computer wins!"); + winner_label.setLocation(250, 150); + } + c_container.setVisible(false); + b_container.setVisible(false); + winner_panel.setVisible(true); + winner_label.setVisible(true); + winner_return_button.setVisible(true); + repaint(); + } + + /** + * Inner class used to "kill" the window when running as + * an application. + */ + static class killAdapter extends WindowAdapter { + public void windowClosing(WindowEvent event) { + System.exit(0); + } + } + + /** + * Main method, only used when running as an application. + */ + public static void main(String[] args) { + FourByFour.appletFlag = false; + new MainFrame(new FourByFour(), 730, 450); + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour_plugin.html b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour_plugin.html new file mode 100644 index 0000000..55e1cf4 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/FourByFour_plugin.html @@ -0,0 +1,39 @@ + + +Drag the mouse in the window + + + + + + + + + + +</COMMENT> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see "FourByFour" instead of this paragraph. +<hr> +</blockquote> + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/ID.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/ID.java new file mode 100644 index 0000000..a9c43df --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/ID.java @@ -0,0 +1,61 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.four_by_four; + +class ID { + int id; + + public ID(int id) { + this.id = id; + } + + public int get() { + return id; + } + + public void set(int id) { + this.id = id; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java b/src/classes/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java new file mode 100644 index 0000000..e6348a2 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/four_by_four/PickDragBehavior.java @@ -0,0 +1,218 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.four_by_four; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import com.sun.j3d.utils.geometry.Sphere; + +/** + * Class: PickDragBehavior + * + * Description: Used to respond to mouse pick and drag events + * in the 3D window. + * + * Version: 1.0 + * + */ +public class PickDragBehavior extends Behavior { + + WakeupCriterion[] mouseEvents; + WakeupOr mouseCriterion; + int x, y; + int x_last, y_last; + double x_angle, y_angle; + double x_factor, y_factor; + Transform3D modelTrans; + Transform3D transformX; + Transform3D transformY; + TransformGroup transformGroup; + BranchGroup branchGroup; + Canvas2D canvas2D; + Canvas3D canvas3D; + Positions positions; + PickRay pickRay = new PickRay(); + SceneGraphPath sceneGraphPath[]; + Appearance highlight; + boolean parallel; + + PickDragBehavior(Canvas2D canvas2D, Canvas3D canvas3D, Positions positions, + BranchGroup branchGroup, TransformGroup transformGroup) { + + this.canvas2D = canvas2D; + this.canvas3D = canvas3D; + this.positions = positions; + this.branchGroup = branchGroup; + this.transformGroup = transformGroup; + + modelTrans = new Transform3D(); + transformX = new Transform3D(); + transformY = new Transform3D(); + + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f green = new Color3f(0.0f, 1.0f, 0.0f); + + highlight = new Appearance(); + highlight.setMaterial(new Material(green, black, green, white, 80.f)); + + parallel = true; + } + + public void initialize() { + x = 0; + y = 0; + x_last = 0; + y_last = 0; + x_angle = 0; + y_angle = 0; + x_factor = .02; + y_factor = .02; + + mouseEvents = new WakeupCriterion[2]; + mouseEvents[0] = new WakeupOnAWTEvent(MouseEvent.MOUSE_DRAGGED); + mouseEvents[1] = new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED); + mouseCriterion = new WakeupOr(mouseEvents); + wakeupOn (mouseCriterion); + } + + public void processStimulus (Enumeration criteria) { + WakeupCriterion wakeup; + AWTEvent[] event; + int id; + int dx, dy; + + while (criteria.hasMoreElements()) { + wakeup = (WakeupCriterion) criteria.nextElement(); + if (wakeup instanceof WakeupOnAWTEvent) { + event = ((WakeupOnAWTEvent)wakeup).getAWTEvent(); + for (int i=0; i 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. + * + *

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). + * + *

The frame counter can be set up to run for a fixed number of sampling + * intervals or to run indefinitely. The defaultis to run indefinitely. + */ + +public class FPSCounter extends Behavior { + // Wakeup condition - framecount = 0 -> wakeup on every frame + WakeupOnElapsedFrames FPSwakeup = new WakeupOnElapsedFrames(0); + + // Do calibration for these many millisec + private static final long testduration = 1000; + + // Report frame rate after every sampleduration milliseconds + private static final long sampleduration = 10000; + + // Flag to indicate that it is time to (re)calibrate + private boolean doCalibration = true; + + // Flag to indicate the counter has started + private boolean startup = true; + + // Wait for HotSpot compiler to perform optimizations + private boolean warmup = true; + + // Time to wait for HotSpot compiler to stabilize (in milliseconds) + private long warmupTime = 20000; + + // Counter for number of frames rendered + private int numframes = 0; + + // Report frame rate after maxframe number of frames have been rendered + private int maxframes = 1; + + // Variables to keep track of elapsed time + private long startuptime = 0; + private long currtime = 0; + private long lasttime = 0; + private long deltatime; + + // Run indefinitely or for a fixed duration + private boolean finiteLoop = false; + + // No. of sampling intervals to run for if not running indefinitely + private long maxLoops; + + // No. of sampling intervals run for so far + private long numLoops = 0; + + // Total number of frames rendered so far + private int sumFrames = 0; + + // Total time since last reporting of average frame rate + private long sumTimes = 0; + + // Counts no. of sampling intervals + private int loop = 0; + + // Average frame rate is reported after loopCount number of + // sampling intervals + private int loopCount = 5; + private double sumFps = 0.0; + + private String symbol[] = {"\\", "|", "|", "/", "-", "|", "-"}; + int index = 0; + private NumberFormat nf = null; + + public FPSCounter() { + setEnable(true); + nf = NumberFormat.getNumberInstance(); + } + + /** + * Called to init the behavior + */ + public void initialize() { + // Set the trigger for the behavior to wakeup on every frame rendered + wakeupOn(FPSwakeup); + } + + /** + * Called every time the behavior is activated + */ + public void processStimulus(java.util.Enumeration critera) { + // Apply calibration algorithm to determine number of frames to + // wait before computing frames per second. + // sampleduration = 10000 -> to run test, pass for 10 seconds. + + if (doCalibration) { // start calibration + if (startup) { + // Record time at which the behavior was first invoked + startuptime = System.currentTimeMillis(); + startup = false; + } + else if(warmup) { // Wait for the system to stabilize. + System.out.print("\rFPSCounter warming up..." + + symbol[(index++)%symbol.length]); + currtime = System.currentTimeMillis(); + deltatime = currtime - startuptime; + if(deltatime > warmupTime) { + // Done waiting for warmup + warmup = false; + lasttime = System.currentTimeMillis(); + System.out.println("\rFPSCounter warming up...Done"); + } + } + else { + numframes += 1; + // Wait till at least maxframe no. of frames have been rendered + if (numframes >= maxframes) { + currtime = System.currentTimeMillis(); + deltatime = currtime - lasttime; + // Do the calibration for testduration no. of millisecs + if (deltatime > testduration) { + // Compute total no. of frames rendered so far in the + // current sampling duration + maxframes = (int)Math.ceil((double)numframes * + ((double)sampleduration / + (double)deltatime)); + + // Done with calibration + doCalibration = false; + // reset the value for the measurement + numframes = 0; + lasttime = System.currentTimeMillis(); + } + else { + // Need to run the calibration routine for some more + // time. Increase the no. of frames to be rendered + maxframes *= 2; + } + } + } + } + else { // do the measurement + numframes += 1; + if (numframes >= maxframes) { + currtime = System.currentTimeMillis(); + deltatime = currtime - lasttime; + // time is in millisec, so multiply by 1000 to get frames/sec + double fps = (double)numframes / ((double)deltatime / 1000.0); + + System.out.println("Frame Rate : \n\tNo. of frames : " + + numframes + "\n\tTime : " + + ((double)deltatime / 1000.0) + + " sec." + "\n\tFrames/sec : " + nf.format(fps)); + + // Calculate average frame rate + sumFrames += numframes; + sumTimes += deltatime; + sumFps += fps; + loop++; + if (loop >= loopCount) { + double avgFps = (double)sumFrames*1000.0/(double)sumTimes; + double ravgFps = sumFps/(double)loopCount; + System.out.println("Aggregate frame rate " + + nf.format(avgFps) + " frames/sec"); + System.out.println("Average frame rate " + + nf.format(ravgFps) + " frames/sec"); + numLoops++; + if (finiteLoop && numLoops >= maxLoops) { + System.out.println("************** The End **************\n"); + setEnable(false); + } + loop = 0; + sumFps = 0; + } + numframes = 0; + lasttime = System.currentTimeMillis();; + } + } + // Set the trigger for the behavior + wakeupOn(FPSwakeup); + } + + /** + * The frame counter waits for some time before computing the + * frame rate. This allows the HotSpot compiler to perform + * initial optimizations. The amount of time to wait for is set + * by this method. The default is 20000 (20 sec) + * + * @param amount of time to wait for before computing frame rate + * (specified in milliseconds) + */ + public void setWarmupTime(long wt) { + warmupTime = wt; + } + + /** + * Sets the number of sampling intervals to wait for before computing + * the average frame rate. + * The default is 5. + * + * @param number of sampling intervals over which to compute frame rate. + * A value of 0 implies the average frame rate is computed over one + * sampling interval + */ + public void setLoopCount(int lc) { + loopCount = lc; + } + + /** + * This method sets the number of sampling intervals for which + * the frame counter should run. + * + * @param number of sampling intervals to run for + */ + public void setMaxLoops(int ml) { + maxLoops = ml; + finiteLoop = true; + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java b/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java new file mode 100644 index 0000000..f73be9d --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/fps_counter/FPSCounterDemo.java @@ -0,0 +1,221 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.fps_counter; + +import java.applet.Applet; +import java.awt.BorderLayout; +import java.awt.event.*; +import java.awt.GraphicsConfiguration; +import com.sun.j3d.utils.applet.JMainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import javax.swing.JOptionPane; + +/** This program demonstrates the use of the frames per second counter. + * The program displays a rotating cube and sets up the FPSCounter to compute + * the frame rate. The FPSCounter is set up with default values: + * - run indefinitely + * - 2 sec. warmup time + * - display average frame rate every fifth sampling interval. + * The default values can be changed through the command line + * arguments. Use FPSCounterDemo -h for help on the various arguments. + */ + +public class FPSCounterDemo extends Applet { + private SimpleUniverse u = null; + private FPSCounter fpsCounter = new FPSCounter(); + + BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create the TransformGroup node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at run time. Add it to + // the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple Shape3D node; add it to the scene graph. + objTrans.addChild(new ColorCube(0.4)); + + // Create a new Behavior object that will perform the + // desired operation on the specified transform and add + // it into the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, 4000); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), + 100.0); + rotator.setSchedulingBounds(bounds); + objRoot.addChild(rotator); + + // Create the Framecounter behavior + fpsCounter.setSchedulingBounds(bounds); + objRoot.addChild(fpsCounter); + + return objRoot; + } + + + public FPSCounterDemo(String args[]) { + } + + public FPSCounterDemo() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + + // Parse the command line to set the various parameters + + // Have Java 3D perform optimizations on this scene graph. + scene.compile(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + + JOptionPane.showMessageDialog(this, + ("This program measures the number of frames rendered per second.\n" + + "Note that the frame rate is limited by the refresh rate of the monitor.\n" + + "To get the true frame rate you need to disable vertical retrace.\n\n" + + "On Windows(tm) you do this through the Control Panel.\n\n" + + "On Solaris set the environment variable OGL_NO_VBLANK"), + "Frame Counter", + JOptionPane.INFORMATION_MESSAGE); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows FPSCounterDemo to be run as an application + // as well as an applet + // + public static void main(String[] args) { + FPSCounterDemo fp = new FPSCounterDemo(); + fp.parseArgs(args); + JMainFrame frame = new JMainFrame(fp, 256, 256); + } + + /** Parses the commandline for the various switches to set the FPSCounter + * variables. + * All arguments are of the form -name value. + * All -name arguments can be shortened to one character. All the value + * arguments take a number. The arguments accepted are : + *

    + *
  • warmupTime : Specifies amount of time the FPSCounter should wait + * for the HotSpotTM VM to perform + * initial optimizations. Specified in milliseconds
    + *
  • loopCount : Specifies the number of sampling intervals over which + * the FPSCounter should calculate the aggregate and average frame rate. + * Specified as a count.
    + *
  • 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.
    + *
  • help : Prints the accepted arguments.
    + *
+ */ + private void parseArgs(String args[]) { + for(int i = 0; i < args.length; i++) { + if(args[i].startsWith("-")) { + if(args[i].startsWith("w", 1)) { + i++; + System.out.println("Warmup time : " + args[i]); + int w = new Integer(args[i]).intValue(); + fpsCounter.setWarmupTime(w); + } + else if(args[i].startsWith("l", 1)) { + i++; + System.out.println("Loop count : " + args[i]); + int l = new Integer(args[i]).intValue(); + fpsCounter.setLoopCount(l); + } + else if(args[i].startsWith("m", 1)) { + i++; + System.out.println("Max Loop Count : " + args[i]); + int m = new Integer(args[i]).intValue(); + fpsCounter.setMaxLoops(m); + } + else if(args[i].startsWith("h", 1)) { + System.out.println("Usage : FPSCounterDemo [-name value]\n" + + "All arguments are of the form: -name value. All -name arguments can be\n" + + "shortened to one character. All the value arguments take a number. The\n" + + "arguments accepted are:\n\n" + + " -warmupTime : Specifies amount of time the FPSCounter should wait\n" + + " for the HotSpot(tm) VM to perform initial\n" + + " optimizations. Specified in milliseconds\n\n" + + " -loopCount : Specifies the number of sampling intervals over which\n" + + " the FPSCounter should calculate the aggregate and average\n" + + " frame rate. Specified as a count\n\n" + + " -maxLoops : Specifies that the FPSCounter should run for only these\n" + + " many sampling intervals. Specified as number. If this argument\n" + + " is not specified, the FPSCounter runs indefinitely.\n\n" + + " -help : Prints this message."); + } + } + } + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/gears/Gear.java b/src/classes/org/jdesktop/j3d/examples/gears/Gear.java new file mode 100644 index 0000000..fb1be1d --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/gears/Gear.java @@ -0,0 +1,399 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.gears; + +import java.lang.Math.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Gear extends javax.media.j3d.TransformGroup { + + // Specifiers determining whether to generate outward facing normals or + // inward facing normals. + static final int OutwardNormals = 1; + static final int InwardNormals = -1; + + // The number of teeth in the gear + int toothCount; + + // Gear start differential angle. All gears are constructed with the + // center of a tooth at Z-axis angle = 0. + double gearStartAngle; + // The Z-rotation angle to place the tooth center at theta = 0 + float toothTopCenterAngle; + // The Z-rotation angle to place the valley center at theta = 0 + float valleyCenterAngle; + // The angle about Z subtended by one tooth and its associated valley + float circularPitchAngle; + + // Increment angles + float toothValleyAngleIncrement; + + // Front and rear facing normals for the gear's body + final Vector3f frontNormal = new Vector3f(0.0f, 0.0f, -1.0f); + final Vector3f rearNormal = new Vector3f(0.0f, 0.0f, 1.0f); + + + Gear(int toothCount) { + this.toothCount = toothCount; + } + + void addBodyDisks(float shaftRadius, float bodyOuterRadius, + float thickness, Appearance look) { + int gearBodySegmentVertexCount; // #(segments) per tooth-unit + int gearBodyTotalVertexCount; // #(vertices) in a gear face + int gearBodyStripCount[] = new int[1]; // per strip (1) vertex count + + // A ray from the gear center, used in normal calculations + float xDirection, yDirection; + + // The x and y coordinates at each point of a facet and at each + // point on the gear: at the shaft, the root of the teeth, and + // the outer point of the teeth + float xRoot0, yRoot0, xShaft0, yShaft0; + float xRoot3, yRoot3, xShaft3, yShaft3; + float xRoot4, yRoot4, xShaft4, yShaft4; + + // Temporary variables for storing coordinates and vectors + Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f); + + // Gear start differential angle. All gears are constructed with the + // center of a tooth at Z-axis angle = 0. + double gearStartAngle = -1.0 * toothTopCenterAngle; + + // Temporaries that store start angle for each portion of tooth facet + double toothStartAngle, toothTopStartAngle, + toothDeclineStartAngle, toothValleyStartAngle, + nextToothStartAngle; + + Shape3D newShape; + int index; + + // The z coordinates for the body disks + final float frontZ = -0.5f * thickness; + final float rearZ = 0.5f * thickness; + + /* Construct the gear's front body (front facing torus disk) + * __2__ + * - | - 4 + * - /| /- + * / / | /| \ + * 0\ / | / / > + * \ / | / | > + * \ / | / / | + * \ / ____|/ | > + * \-- --__/ | + * 1 3 5 + * + */ + gearBodySegmentVertexCount = 4; + gearBodyTotalVertexCount = 2 + gearBodySegmentVertexCount * toothCount; + gearBodyStripCount[0] = gearBodyTotalVertexCount; + + TriangleStripArray frontGearBody + = new TriangleStripArray(gearBodyTotalVertexCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS, + gearBodyStripCount); + + xDirection = (float)Math.cos(gearStartAngle); + yDirection = (float)Math.sin(gearStartAngle); + xShaft0 = shaftRadius * xDirection; + yShaft0 = shaftRadius * yDirection; + xRoot0 = bodyOuterRadius * xDirection; + yRoot0 = bodyOuterRadius * yDirection; + + coordinate.set(xRoot0, yRoot0, frontZ); + frontGearBody.setCoordinate(0, coordinate); + frontGearBody.setNormal(0, frontNormal); + + coordinate.set(xShaft0, yShaft0, frontZ); + frontGearBody.setCoordinate(1, coordinate); + frontGearBody.setNormal(1, frontNormal); + + for(int count = 0; count < toothCount; count++) { + index = 2 + count * 4; + toothStartAngle + = gearStartAngle + circularPitchAngle * (double)count; + toothValleyStartAngle + = toothStartAngle + toothValleyAngleIncrement; + nextToothStartAngle = toothStartAngle + circularPitchAngle; + + xDirection = (float)Math.cos(toothValleyStartAngle); + yDirection = (float)Math.sin(toothValleyStartAngle); + xShaft3 = shaftRadius * xDirection; + yShaft3 = shaftRadius * yDirection; + xRoot3 = bodyOuterRadius * xDirection; + yRoot3 = bodyOuterRadius * yDirection; + + xDirection = (float)Math.cos(nextToothStartAngle); + yDirection = (float)Math.sin(nextToothStartAngle); + xShaft4 = shaftRadius * xDirection; + yShaft4 = shaftRadius * yDirection; + xRoot4 = bodyOuterRadius * xDirection; + yRoot4 = bodyOuterRadius * yDirection; + + coordinate.set(xRoot3, yRoot3, frontZ); + frontGearBody.setCoordinate(index, coordinate); + frontGearBody.setNormal(index, frontNormal); + + coordinate.set(xShaft3, yShaft3, frontZ); + frontGearBody.setCoordinate(index + 1, coordinate); + frontGearBody.setNormal(index + 1, frontNormal); + + coordinate.set(xRoot4, yRoot4, frontZ); + frontGearBody.setCoordinate(index + 2, coordinate); + frontGearBody.setNormal(index + 2, frontNormal); + + coordinate.set(xShaft4, yShaft4, frontZ); + frontGearBody.setCoordinate(index + 3, coordinate); + frontGearBody.setNormal(index + 3, frontNormal); + } + newShape = new Shape3D(frontGearBody, look); + this.addChild(newShape); + + // Construct the gear's rear body (rear facing torus disc) + TriangleStripArray rearGearBody + = new TriangleStripArray(gearBodyTotalVertexCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS, + gearBodyStripCount); + xDirection = (float)Math.cos(gearStartAngle); + yDirection = (float)Math.sin(gearStartAngle); + xShaft0 = shaftRadius * xDirection; + yShaft0 = shaftRadius * yDirection; + xRoot0 = bodyOuterRadius * xDirection; + yRoot0 = bodyOuterRadius * yDirection; + + coordinate.set(xShaft0, yShaft0, rearZ); + rearGearBody.setCoordinate(0, coordinate); + rearGearBody.setNormal(0, rearNormal); + + coordinate.set(xRoot0, yRoot0, rearZ); + rearGearBody.setCoordinate(1, coordinate); + rearGearBody.setNormal(1, rearNormal); + + for(int count = 0; count < toothCount; count++) { + index = 2 + count * 4; + toothStartAngle + = gearStartAngle + circularPitchAngle * (double)count; + toothValleyStartAngle + = toothStartAngle + toothValleyAngleIncrement; + nextToothStartAngle = toothStartAngle + circularPitchAngle; + + xDirection = (float)Math.cos(toothValleyStartAngle); + yDirection = (float)Math.sin(toothValleyStartAngle); + xShaft3 = shaftRadius * xDirection; + yShaft3 = shaftRadius * yDirection; + xRoot3 = bodyOuterRadius * xDirection; + yRoot3 = bodyOuterRadius * yDirection; + + xDirection = (float)Math.cos(nextToothStartAngle); + yDirection = (float)Math.sin(nextToothStartAngle); + xShaft4 = shaftRadius * xDirection; + yShaft4 = shaftRadius * yDirection; + xRoot4 = bodyOuterRadius * xDirection; + yRoot4 = bodyOuterRadius * yDirection; + + coordinate.set(xShaft3, yShaft3, rearZ); + rearGearBody.setCoordinate(index, coordinate); + rearGearBody.setNormal(index, rearNormal); + + coordinate.set(xRoot3, yRoot3, rearZ); + rearGearBody.setCoordinate(index + 1, coordinate); + rearGearBody.setNormal(index + 1, rearNormal); + + coordinate.set(xShaft4, yShaft4, rearZ); + rearGearBody.setCoordinate(index + 2, coordinate); + rearGearBody.setNormal(index + 2, rearNormal); + + coordinate.set(xRoot4, yRoot4, rearZ); + rearGearBody.setCoordinate(index + 3, coordinate); + rearGearBody.setNormal(index + 3, rearNormal); + + } + newShape = new Shape3D(rearGearBody, look); + this.addChild(newShape); + } + + void addCylinderSkins(float shaftRadius, float length, + int normalDirection, Appearance look) { + int insideShaftVertexCount; // #(vertices) for shaft + int insideShaftStripCount[] = new int[1]; // #(vertices) in strip/strip + double toothStartAngle, nextToothStartAngle, toothValleyStartAngle; + + // A ray from the gear center, used in normal calculations + float xDirection, yDirection; + + // The z coordinates for the body disks + final float frontZ = -0.5f * length; + final float rearZ = 0.5f * length; + + // Temporary variables for storing coordinates, points, and vectors + float xShaft3, yShaft3, xShaft4, yShaft4; + Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f); + Vector3f surfaceNormal = new Vector3f(); + + Shape3D newShape; + int index; + int firstIndex; + int secondIndex; + + + /* + * Construct gear's inside shaft cylinder + * First the tooth's up, flat outer, and down distances + * Second the tooth's flat inner distance + * + * Outward facing vertex order: + * 0_______2____4 + * | /| /| + * | / | / | + * | / | / | + * |/______|/___| + * 1 3 5 + * + * Inward facing vertex order: + * 1_______3____5 + * |\ |\ | + * | \ | \ | + * | \ | \ | + * |______\|___\| + * 0 2 4 + */ + insideShaftVertexCount = 4 * toothCount + 2; + insideShaftStripCount[0] = insideShaftVertexCount; + + TriangleStripArray insideShaft + = new TriangleStripArray(insideShaftVertexCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS, + insideShaftStripCount); + xShaft3 = shaftRadius * (float)Math.cos(gearStartAngle); + yShaft3 = shaftRadius * (float)Math.sin(gearStartAngle); + + if (normalDirection == OutwardNormals) { + surfaceNormal.set(1.0f, 0.0f, 0.0f); + firstIndex = 1; + secondIndex = 0; + } else { + surfaceNormal.set(-1.0f, 0.0f, 0.0f); + firstIndex = 0; + secondIndex = 1; + } + + // Coordinate labeled 0 in the strip + coordinate.set(shaftRadius, 0.0f, frontZ); + insideShaft.setCoordinate(firstIndex, coordinate); + insideShaft.setNormal(firstIndex, surfaceNormal); + + // Coordinate labeled 1 in the strip + coordinate.set(shaftRadius, 0.0f, rearZ); + insideShaft.setCoordinate(secondIndex, coordinate); + insideShaft.setNormal(secondIndex, surfaceNormal); + + for(int count = 0; count < toothCount; count++) { + index = 2 + count * 4; + + toothStartAngle = circularPitchAngle * (double)count; + toothValleyStartAngle + = toothStartAngle + toothValleyAngleIncrement; + nextToothStartAngle = toothStartAngle + circularPitchAngle; + + xDirection = (float)Math.cos(toothValleyStartAngle); + yDirection = (float)Math.sin(toothValleyStartAngle); + xShaft3 = shaftRadius * xDirection; + yShaft3 = shaftRadius * yDirection; + if (normalDirection == OutwardNormals) + surfaceNormal.set(xDirection, yDirection, 0.0f); + else + surfaceNormal.set(-xDirection, -yDirection, 0.0f); + + // Coordinate labeled 2 in the strip + coordinate.set(xShaft3, yShaft3, frontZ); + insideShaft.setCoordinate(index + firstIndex, coordinate); + insideShaft.setNormal(index + firstIndex, surfaceNormal); + + // Coordinate labeled 3 in the strip + coordinate.set(xShaft3, yShaft3, rearZ); + insideShaft.setCoordinate(index + secondIndex, coordinate); + insideShaft.setNormal(index + secondIndex, surfaceNormal); + + xDirection = (float)Math.cos(nextToothStartAngle); + yDirection = (float)Math.sin(nextToothStartAngle); + xShaft4 = shaftRadius * xDirection; + yShaft4 = shaftRadius * yDirection; + if (normalDirection == OutwardNormals) + surfaceNormal.set(xDirection, yDirection, 0.0f); + else + surfaceNormal.set(-xDirection, -yDirection, 0.0f); + + // Coordinate labeled 4 in the strip + coordinate.set(xShaft4, yShaft4, frontZ); + insideShaft.setCoordinate(index + 2 + firstIndex, coordinate); + insideShaft.setNormal(index + 2 + firstIndex, surfaceNormal); + + // Coordinate labeled 5 in the strip + coordinate.set(xShaft4, yShaft4, rearZ); + insideShaft.setCoordinate(index + 2 + secondIndex, coordinate); + insideShaft.setNormal(index + 2 + secondIndex, surfaceNormal); + + } + newShape = new Shape3D(insideShaft, look); + this.addChild(newShape); + } + + public float getToothTopCenterAngle() { + return toothTopCenterAngle; + } + + public float getValleyCenterAngle() { + return valleyCenterAngle; + } + + public float getCircularPitchAngle() { + return circularPitchAngle; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/gears/GearBox.java b/src/classes/org/jdesktop/j3d/examples/gears/GearBox.java new file mode 100644 index 0000000..a3b0a84 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/gears/GearBox.java @@ -0,0 +1,356 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.gears; + +import com.sun.j3d.utils.behaviors.mouse.*; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.lang.Integer; +import com.sun.j3d.utils.behaviors.vp.*; + +public class GearBox extends Applet { + + static final int defaultToothCount = 48; + private int toothCount; + private SimpleUniverse u = null; + + public BranchGroup createGearBox(int toothCount) { + Transform3D tempTransform = new Transform3D(); + + // Create the root of the branch graph + BranchGroup branchRoot = createBranchEnvironment(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + branchRoot.addChild(objScale); + + // Create an Appearance. + Appearance look = new Appearance(); + Color3f objColor = new Color3f(0.5f, 0.5f, 0.6f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + look.setMaterial(new Material(objColor, black, + objColor, white, 100.0f)); + + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup gearboxTrans = new TransformGroup(); + gearboxTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + gearboxTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objScale.addChild(gearboxTrans); + + // Create a bounds for the mouse behavior methods + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Define the shaft base information + int shaftCount = 4; + int secondsPerRevolution = 8000; + + // Create the Shaft(s) + Shaft shafts[] = new Shaft[shaftCount]; + TransformGroup shaftTGs[] = new TransformGroup[shaftCount]; + Alpha shaftAlphas[] = new Alpha[shaftCount]; + RotationInterpolator shaftRotors[] + = new RotationInterpolator[shaftCount]; + Transform3D shaftAxis[] = new Transform3D[shaftCount]; + + // Note: the following arrays we're incorporated to make changing + // the gearbox easier. + float shaftRatios[] = new float[shaftCount]; + shaftRatios[0] = 1.0f; + shaftRatios[1] = 0.5f; + shaftRatios[2] = 0.75f; + shaftRatios[3] = 5.0f; + + float shaftRadius[] = new float[shaftCount]; + shaftRadius[0] = 0.2f; + shaftRadius[1] = 0.2f; + shaftRadius[2] = 0.2f; + shaftRadius[3] = 0.2f; + + float shaftLength[] = new float[shaftCount]; + shaftLength[0] = 1.8f; + shaftLength[1] = 0.8f; + shaftLength[2] = 0.8f; + shaftLength[3] = 0.8f; + + float shaftDirection[] = new float[shaftCount]; + shaftDirection[0] = 1.0f; + shaftDirection[1] = -1.0f; + shaftDirection[2] = 1.0f; + shaftDirection[3] = -1.0f; + + Vector3d shaftPlacement[] = new Vector3d[shaftCount]; + shaftPlacement[0] = new Vector3d(-0.75, -0.9, 0.0); + shaftPlacement[1] = new Vector3d(0.75, -0.9, 0.0); + shaftPlacement[2] = new Vector3d(0.75, 0.35, 0.0); + shaftPlacement[3] = new Vector3d(-0.75, 0.60, -0.7); + + // Create the shafts. + for(int i = 0; i < shaftCount; i++) { + shafts[i] = new Shaft(shaftRadius[i], shaftLength[i], 25, look); + } + + // Create a transform group node for placing each shaft + for(int i = 0; i < shaftCount; i++) { + shaftTGs[i] = new TransformGroup(); + gearboxTrans.addChild(shaftTGs[i]); + shaftTGs[i].getTransform(tempTransform); + tempTransform.setTranslation(shaftPlacement[i]); + shaftTGs[i].setTransform(tempTransform); + shaftTGs[i].addChild(shafts[i]); + } + + // Add rotation interpolators to rotate the shaft in the appropriate + // direction and at the appropriate rate + for(int i = 0; i < shaftCount; i++) { + shaftAlphas[i] = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, + (long)(secondsPerRevolution + * shaftRatios[i]), + 0, 0, + 0, 0, 0); + shaftAxis[i] = new Transform3D(); + shaftAxis[i].rotX(Math.PI/2.0); + shaftRotors[i] + = new RotationInterpolator(shaftAlphas[i], shafts[i], + shaftAxis[i], + 0.0f, + shaftDirection[i] * + (float) Math.PI * 2.0f); + shaftRotors[i].setSchedulingBounds(bounds); + shaftTGs[i].addChild(shaftRotors[i]); + } + + // Define the gear base information. Again, these arrays exist to + // make the process of changing the GearBox via an editor faster + int gearCount = 5; + float valleyToCircularPitchRatio = .15f; + float pitchCircleRadius = 1.0f; + float addendum = 0.05f; + float dedendum = 0.05f; + float gearThickness = 0.3f; + float toothTipThickness = 0.27f; + + // Create an array of gears and their associated information + SpurGear gears[] = new SpurGear[gearCount]; + TransformGroup gearTGs[] = new TransformGroup[gearCount]; + + int gearShaft[] = new int[gearCount]; + gearShaft[0] = 0; + gearShaft[1] = 1; + gearShaft[2] = 2; + gearShaft[3] = 0; + gearShaft[4] = 3; + + float ratio[] = new float[gearCount]; + ratio[0] = 1.0f; + ratio[1] = 0.5f; + ratio[2] = 0.75f; + ratio[3] = 0.25f; + ratio[4] = 1.25f; + + Vector3d placement[] = new Vector3d[gearCount]; + placement[0] = new Vector3d(0.0, 0.0, 0.0); + placement[1] = new Vector3d(0.0, 0.0, 0.0); + placement[2] = new Vector3d(0.0, 0.0, 0.0); + placement[3] = new Vector3d(0.0, 0.0, -0.7); + placement[4] = new Vector3d(0.0, 0.0, 0.0); + + // Create the gears. + for(int i = 0; i < gearCount; i++) { + gears[i] + = new SpurGearThinBody(((int)((float)toothCount * ratio[i])), + pitchCircleRadius * ratio[i], + shaftRadius[0], + addendum, dedendum, + gearThickness, + toothTipThickness, + valleyToCircularPitchRatio, look); + } + + // Create a transform group node for arranging the gears on a shaft + // and attach the gear to its associated shaft + for(int i = 0; i < gearCount; i++) { + gearTGs[i] = new TransformGroup(); + gearTGs[i].getTransform(tempTransform); + tempTransform.rotZ((shaftDirection[gearShaft[i]] == -1.0) ? + gears[i].getCircularPitchAngle()/-2.0f : + 0.0f); + tempTransform.setTranslation(placement[i]); + gearTGs[i].setTransform(tempTransform); + gearTGs[i].addChild(gears[i]); + shafts[gearShaft[i]].addChild(gearTGs[i]); + } + + // Have Java 3D perform optimizations on this scene graph. + branchRoot.compile(); + + return branchRoot; + } + + BranchGroup createBranchEnvironment(){ + // Create the root of the branch graph + BranchGroup branchRoot = new BranchGroup(); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f); + Background bgNode = new Background(bgColor); + bgNode.setApplicationBounds(bounds); + branchRoot.addChild(bgNode); + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + branchRoot.addChild(ambientLightNode); + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f); + Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f); + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + branchRoot.addChild(light1); + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + branchRoot.addChild(light2); + + return branchRoot; + } + + public GearBox() { + this(defaultToothCount); + } + + public GearBox(int toothCount) { + this.toothCount = toothCount; + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create the gearbox and attach it to the virtual universe + BranchGroup scene = createGearBox(toothCount); + u = new SimpleUniverse(c); + + // add mouse behaviors to the ViewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + // add orbit behavior to the ViewingPlatform + OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows GearBox to be run as an application + // as well as an applet + // + public static void main(String[] args) { + int value; + + if (args.length > 1) { + System.out.println("Usage: java GearBox #teeth (LCD 4)"); + System.exit(0); + } else if (args.length == 0) { + new MainFrame(new GearBox(), 700, 700); + } else + { + try{ + value = Integer.parseInt(args[0]); + } catch (NumberFormatException e) { + System.out.println("Illegal integer specified"); + System.out.println("Usage: java GearBox #teeth (LCD 4)"); + value = 0; + System.exit(0); + } + if (value <= 0 | (value % 4) != 0) { + System.out.println("Integer not a positive multiple of 4"); + System.out.println("Usage: java GearBox #teeth (LCD 4)"); + System.exit(0); + } + new MainFrame(new GearBox(value), 700, 700); + } + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/gears/GearTest.java b/src/classes/org/jdesktop/j3d/examples/gears/GearTest.java new file mode 100644 index 0000000..29ecca9 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/gears/GearTest.java @@ -0,0 +1,208 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.gears; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class GearTest extends Applet { + + static final int defaultToothCount = 24; + + private int toothCount; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph(int toothCount) { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + Background bgNode = new Background(bgColor); + bgNode.setApplicationBounds(bounds); + objScale.addChild(bgNode); + + // Set up the global lights + Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f); + Color3f light2Color = new Color3f(0.3f, 0.3f, 0.4f); + Vector3f light2Direction = new Vector3f(-6.0f, -2.0f, -1.0f); + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); + + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + objScale.addChild(ambientLightNode); + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + objScale.addChild(light1); + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + objScale.addChild(light2); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(objTrans); + + // Create an Appearance. + Appearance look = new Appearance(); + Color3f objColor = new Color3f(0.5f, 0.5f, 0.6f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + look.setMaterial(new Material(objColor, black, objColor, white, 100.0f)); + + // Create a gear, add it to the scene graph. + // SpurGear gear = new SpurGear(toothCount, 1.0f, 0.2f, + SpurGear gear = new SpurGearThinBody(toothCount, 1.0f, 0.2f, + 0.05f, 0.05f, 0.3f, 0.28f, look); + objTrans.addChild(gear); + + // Create a new Behavior object that will rotate the object and + // add it into the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 8000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + + // Have Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public GearTest() { + this(defaultToothCount); + } + + public GearTest(int toothCount) { + this.toothCount = toothCount; + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(toothCount); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows GearTest to be run as an application + // as well as an applet + // + public static void main(String[] args) { + int value; + + if (args.length > 1) { + System.out.println("Usage: java GearTest [#teeth]"); + System.exit(0); + } else if (args.length == 0) { + new MainFrame(new GearTest(), 700, 700); + } else + { + try { + value = Integer.parseInt(args[0]); + } catch (NumberFormatException e) { + System.out.println("Illegal integer specified"); + System.out.println("Usage: java GearTest [#teeth]"); + value = 0; + System.exit(0); + } + if (value <= 0) { + System.out.println("Integer must be positive (> 0)"); + System.out.println("Usage: java GearBox [#teeth]"); + System.exit(0); + } + new MainFrame(new GearTest(value), 700, 700); + } + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/gears/Shaft.java b/src/classes/org/jdesktop/j3d/examples/gears/Shaft.java new file mode 100644 index 0000000..b02bf9e --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/gears/Shaft.java @@ -0,0 +1,198 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.gears; + +import java.lang.Math.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Shaft extends javax.media.j3d.TransformGroup { + + /** + * Construct a Shaft; + * @return a new shaft that with the specified radius centered about + * the origin an laying in the XY plane and of a specified length + * extending in the Z dimension + * @param radius radius of shaft + * @param length shaft length shaft extends from -length/2 to length/2 in + * the Z dimension + * @param segmentCount number of segments for the shaft face + * @param look the Appearance to associate with this shaft + */ + public Shaft(float radius, float length, int segmentCount, + Appearance look) { + // The direction of the ray from the shaft's center + float xDirection, yDirection; + float xShaft, yShaft; + + // The z coordinates for the shaft's faces (never change) + float frontZ = -0.5f * length; + float rearZ = 0.5f * length; + + int shaftFaceVertexCount; // #(vertices) per shaft face + int shaftFaceTotalVertexCount; // total #(vertices) in all teeth + int shaftFaceStripCount[] = new int[1]; // per shaft vertex count + int shaftVertexCount; // #(vertices) for shaft + int shaftStripCount[] = new int[1]; // #(vertices) in strip/strip + + // Front and rear facing normals for the shaft's faces + Vector3f frontNormal = new Vector3f(0.0f, 0.0f, -1.0f); + Vector3f rearNormal = new Vector3f(0.0f, 0.0f, 1.0f); + // Outward facing normal + Vector3f outNormal = new Vector3f(1.0f, 0.0f, 0.0f); + + // Temporary variables for storing coordinates and vectors + Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f); + Shape3D newShape; + + // The angle subtended by a single segment + double segmentAngle = 2.0 * Math.PI/segmentCount; + double tempAngle; + + // Allow this object to spin. etc. + this.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + + /* for the forward facing fan: + * ___3___ + * - | - + * / | \ + * 4/\ | /\2 + * / \ | / \ + * / \ | / \ + * : \ | / : + * |--------------- *----------------| + * 5 0 1 + * + * for backward facing fan exchange 1 with 5; 2 with 4, etc. + */ + + // Construct the shaft's front and rear face + shaftFaceVertexCount = segmentCount + 2; + shaftFaceStripCount[0] = shaftFaceVertexCount; + + TriangleFanArray frontShaftFace + = new TriangleFanArray(shaftFaceVertexCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS, + shaftFaceStripCount); + + TriangleFanArray rearShaftFace + = new TriangleFanArray(shaftFaceVertexCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS, + shaftFaceStripCount); + + coordinate.set(0.0f, 0.0f, frontZ); + frontShaftFace.setCoordinate(0, coordinate); + frontShaftFace.setNormal(0, frontNormal); + + coordinate.set(0.0f, 0.0f, rearZ); + rearShaftFace.setCoordinate(0, coordinate); + rearShaftFace.setNormal(0, rearNormal); + + for(int index = 1; index < segmentCount+2; index++) { + + tempAngle = segmentAngle * -(double)index; + coordinate.set(radius * (float)Math.cos(tempAngle), + radius * (float)Math.sin(tempAngle), + frontZ); + frontShaftFace.setCoordinate(index, coordinate); + frontShaftFace.setNormal(index, frontNormal); + + tempAngle = -tempAngle; + coordinate.set(radius * (float)Math.cos(tempAngle), + radius * (float)Math.sin(tempAngle), + rearZ); + rearShaftFace.setCoordinate(index, coordinate); + rearShaftFace.setNormal(index, rearNormal); + } + newShape = new Shape3D(frontShaftFace, look); + this.addChild(newShape); + newShape = new Shape3D(rearShaftFace, look); + this.addChild(newShape); + + // Construct shaft's outer skin (the cylinder body) + shaftVertexCount = 2 * segmentCount + 2; + shaftStripCount[0] = shaftVertexCount; + + TriangleStripArray shaft + = new TriangleStripArray(shaftVertexCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS, + shaftStripCount); + + outNormal.set(1.0f, 0.0f, 0.0f); + + coordinate.set(radius, 0.0f, rearZ); + shaft.setCoordinate(0, coordinate); + shaft.setNormal(0, outNormal); + + coordinate.set(radius, 0.0f, frontZ); + shaft.setCoordinate(1, coordinate); + shaft.setNormal(1, outNormal); + + for(int count = 0; count < segmentCount; count++) { + int index = 2 + count * 2; + + tempAngle = segmentAngle * (double)(count + 1); + xDirection = (float)Math.cos(tempAngle); + yDirection = (float)Math.sin(tempAngle); + xShaft = radius * xDirection; + yShaft = radius * yDirection; + outNormal.set(xDirection, yDirection, 0.0f); + + coordinate.set(xShaft, yShaft, rearZ); + shaft.setCoordinate(index, coordinate); + shaft.setNormal(index, outNormal); + + coordinate.set(xShaft, yShaft, frontZ); + shaft.setCoordinate(index + 1, coordinate); + shaft.setNormal(index + 1, outNormal); + } + newShape = new Shape3D(shaft, look); + this.addChild(newShape); + } +} + diff --git a/src/classes/org/jdesktop/j3d/examples/gears/SpurGear.java b/src/classes/org/jdesktop/j3d/examples/gears/SpurGear.java new file mode 100644 index 0000000..525a661 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/gears/SpurGear.java @@ -0,0 +1,558 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.gears; + +import java.lang.Math.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class SpurGear extends Gear { + + float toothTopAngleIncrement; + float toothDeclineAngleIncrement; + + float rootRadius; + float outsideRadius; + + //The angle subtended by the ascending or descending portion of a tooth + float circularToothEdgeAngle; + // The angle subtended by a flat (either a tooth top or a valley + // between teeth + float circularToothFlatAngle; + + /** + * internal constructor for SpurGear, used by subclasses to establish + * SpurGear's required state + * @return a new spur gear that contains sufficient information to + * continue building + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param toothToValleyAngleRatio the ratio of the angle subtended by the + * tooth to the angle subtended by the valley (must be <= .25) + */ + SpurGear(int toothCount, float pitchCircleRadius, + float addendum, float dedendum, float toothToValleyAngleRatio) { + + super(toothCount); + + // The angle about Z subtended by one tooth and its associated valley + circularPitchAngle = (float)(2.0 * Math.PI / (double)toothCount); + + // The angle subtended by a flat (either a tooth top or a valley + // between teeth + circularToothFlatAngle = circularPitchAngle * toothToValleyAngleRatio; + + //The angle subtended by the ascending or descending portion of a tooth + circularToothEdgeAngle = circularPitchAngle/2.0f - + circularToothFlatAngle; + + // Increment angles + toothTopAngleIncrement = circularToothEdgeAngle; + toothDeclineAngleIncrement + = toothTopAngleIncrement + circularToothFlatAngle; + toothValleyAngleIncrement + = toothDeclineAngleIncrement + circularToothEdgeAngle; + + // Differential angles for offsetting to the center of tooth's top + // and valley + toothTopCenterAngle + = toothTopAngleIncrement + circularToothFlatAngle/2.0f; + valleyCenterAngle + = toothValleyAngleIncrement + circularToothFlatAngle/2.0f; + + // Gear start differential angle. All gears are constructed with the + // center of a tooth at Z-axis angle = 0. + gearStartAngle = -1.0 * toothTopCenterAngle; + + // The radial distance to the root and top of the teeth, respectively + rootRadius = pitchCircleRadius - dedendum; + outsideRadius = pitchCircleRadius + addendum; + + // Allow this object to spin. etc. + this.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + } + + /** + * Construct a SpurGear; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + */ + public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius, + float addendum, float dedendum, float gearThickness) { + this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum, + gearThickness, gearThickness, 0.25f, null); + } + + /** + * Construct a SpurGear; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + * @param look the gear's appearance + */ + public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius, + float addendum, float dedendum, float gearThickness, + Appearance look) { + this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum, + gearThickness, gearThickness, 0.25f, look); + } + + /** + * Construct a SpurGear; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + * @param toothTipThickness thickness of the tip of the tooth + * @param look the gear's appearance + */ + public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius, + float addendum, float dedendum, float gearThickness, + float toothTipThickness, Appearance look) { + this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum, + gearThickness, toothTipThickness, 0.25f, look); + } + + /** + * Construct a SpurGear; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + * @param toothTipThickness thickness of the tip of the tooth + * @param toothToValleyAngleRatio the ratio of the angle subtended by the + * tooth to the angle subtended by the valley (must be <= .25) + * @param look the gear's appearance object + */ + public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius, + float addendum, float dedendum, float gearThickness, + float toothTipThickness, float toothToValleyAngleRatio, + Appearance look) { + + this(toothCount, pitchCircleRadius, addendum, dedendum, + toothToValleyAngleRatio); + + // Generate the gear's body disks + addBodyDisks(shaftRadius, rootRadius, gearThickness, look); + + // Generate the gear's interior shaft + addCylinderSkins(shaftRadius, gearThickness, InwardNormals, look); + + // Generate the gear's teeth + addTeeth(pitchCircleRadius, rootRadius, + outsideRadius, gearThickness, toothTipThickness, + toothToValleyAngleRatio, look); + } + + /** + * Construct a SpurGear's teeth by adding the teeth shape nodes + * @param pitchCircleRadius radius at center of teeth + * @param rootRadius distance from pitch circle to top of teeth + * @param outsideRadius distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + * @param toothTipThickness thickness of the tip of the tooth + * @param toothToValleyAngleRatio the ratio of the angle subtended by the + * tooth to the angle subtended by the valley (must be <= .25) + * @param look the gear's appearance object + */ + void addTeeth(float pitchCircleRadius, float rootRadius, + float outsideRadius, float gearThickness, + float toothTipThickness, float toothToValleyAngleRatio, + Appearance look) { + int index; + Shape3D newShape; + + // Temporaries that store start angle for each portion of tooth facet + double toothStartAngle, toothTopStartAngle, + toothDeclineStartAngle, toothValleyStartAngle, + nextToothStartAngle; + + // The x and y coordinates at each point of a facet and at each + // point on the gear: at the shaft, the root of the teeth, and + // the outer point of the teeth + float xRoot0, yRoot0; + float xOuter1, yOuter1; + float xOuter2, yOuter2; + float xRoot3, yRoot3; + float xRoot4, yRoot4; + + // The z coordinates for the gear + final float frontZ = -0.5f * gearThickness; + final float rearZ = 0.5f * gearThickness; + + // The z coordinates for the tooth tip of the gear + final float toothTipFrontZ = -0.5f * toothTipThickness; + final float toothTipRearZ = 0.5f * toothTipThickness; + + int toothFacetVertexCount; // #(vertices) per tooth facet + int toothFacetCount; // #(facets) per tooth + int toothFaceTotalVertexCount; // #(vertices) in all teeth + int toothFaceStripCount[] = new int[toothCount]; + // per tooth vertex count + int topVertexCount; // #(vertices) for teeth tops + int topStripCount[] = new int[1]; // #(vertices) in strip/strip + + // Front and rear facing normals for the teeth faces + Vector3f frontToothNormal = new Vector3f(0.0f, 0.0f, -1.0f); + Vector3f rearToothNormal = new Vector3f(0.0f, 0.0f, 1.0f); + + // Normals for teeth tops up incline, tooth top, and down incline + Vector3f leftNormal = new Vector3f(-1.0f, 0.0f, 0.0f); + Vector3f rightNormal = new Vector3f(1.0f, 0.0f, 0.0f); + Vector3f outNormal = new Vector3f(1.0f, 0.0f, 0.0f); + Vector3f inNormal = new Vector3f(-1.0f, 0.0f, 0.0f); + + // Temporary variables for storing coordinates and vectors + Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f); + Point3f tempCoordinate1 = new Point3f(0.0f, 0.0f, 0.0f); + Point3f tempCoordinate2 = new Point3f(0.0f, 0.0f, 0.0f); + Point3f tempCoordinate3 = new Point3f(0.0f, 0.0f, 0.0f); + Vector3f tempVector1 = new Vector3f(0.0f, 0.0f, 0.0f); + Vector3f tempVector2 = new Vector3f(0.0f, 0.0f, 0.0f); + + /* Construct the gear's front facing teeth facets + * 0______2 + * / /\ + * / / \ + * / / \ + * //___________\ + * 1 3 + */ + toothFacetVertexCount = 4; + toothFaceTotalVertexCount = toothFacetVertexCount * toothCount; + for(int i = 0; i < toothCount; i++) + toothFaceStripCount[i] = toothFacetVertexCount; + + TriangleStripArray frontGearTeeth + = new TriangleStripArray(toothFaceTotalVertexCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS, + toothFaceStripCount); + + for(int count = 0; count < toothCount; count++) { + index = count * toothFacetVertexCount; + + toothStartAngle + = gearStartAngle + circularPitchAngle * (double)count; + toothTopStartAngle = toothStartAngle + toothTopAngleIncrement; + toothDeclineStartAngle + = toothStartAngle + toothDeclineAngleIncrement; + toothValleyStartAngle + = toothStartAngle + toothValleyAngleIncrement; + + xRoot0 = rootRadius * (float)Math.cos(toothStartAngle); + yRoot0 = rootRadius * (float)Math.sin(toothStartAngle); + xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle); + yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle); + xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle); + yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle); + xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle); + yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle); + + tempCoordinate1.set(xRoot0, yRoot0, frontZ); + tempCoordinate2.set(xRoot3, yRoot3, frontZ); + tempVector1.sub(tempCoordinate2, tempCoordinate1); + + tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ); + tempVector2.sub(tempCoordinate2, tempCoordinate1); + + frontToothNormal.cross(tempVector1, tempVector2); + frontToothNormal.normalize(); + + coordinate.set(xOuter1, yOuter1, toothTipFrontZ); + frontGearTeeth.setCoordinate(index, coordinate); + frontGearTeeth.setNormal(index, frontToothNormal); + + coordinate.set(xRoot0, yRoot0, frontZ); + frontGearTeeth.setCoordinate(index + 1, coordinate); + frontGearTeeth.setNormal(index + 1, frontToothNormal); + + coordinate.set(xOuter2, yOuter2, toothTipFrontZ); + frontGearTeeth.setCoordinate(index + 2, coordinate); + frontGearTeeth.setNormal(index + 2, frontToothNormal); + + coordinate.set(xRoot3, yRoot3, frontZ); + frontGearTeeth.setCoordinate(index + 3, coordinate); + frontGearTeeth.setNormal(index + 3, frontToothNormal); + } + newShape = new Shape3D(frontGearTeeth, look); + this.addChild(newShape); + + /* Construct the gear's rear facing teeth facets (Using Quads) + * 1______2 + * / \ + * / \ + * / \ + * /____________\ + * 0 3 + */ + toothFacetVertexCount = 4; + toothFaceTotalVertexCount = toothFacetVertexCount * toothCount; + + QuadArray rearGearTeeth + = new QuadArray(toothCount * toothFacetVertexCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS); + + for(int count = 0; count < toothCount; count++) { + + index = count * toothFacetVertexCount; + toothStartAngle = + gearStartAngle + circularPitchAngle * (double)count; + toothTopStartAngle = toothStartAngle + toothTopAngleIncrement; + toothDeclineStartAngle + = toothStartAngle + toothDeclineAngleIncrement; + toothValleyStartAngle = toothStartAngle + toothValleyAngleIncrement; + + xRoot0 = rootRadius * (float)Math.cos(toothStartAngle); + yRoot0 = rootRadius * (float)Math.sin(toothStartAngle); + xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle); + yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle); + xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle); + yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle); + xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle); + yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle); + + tempCoordinate1.set(xRoot0, yRoot0, rearZ); + tempCoordinate2.set(xRoot3, yRoot3, rearZ); + tempVector1.sub(tempCoordinate2, tempCoordinate1); + tempCoordinate2.set(xOuter1, yOuter1, toothTipRearZ); + tempVector2.sub(tempCoordinate2, tempCoordinate1); + rearToothNormal.cross(tempVector2, tempVector1); + rearToothNormal.normalize(); + + coordinate.set(xRoot0, yRoot0, rearZ); + rearGearTeeth.setCoordinate(index, coordinate); + rearGearTeeth.setNormal(index, rearToothNormal); + + coordinate.set(xOuter1, yOuter1, toothTipRearZ); + rearGearTeeth.setCoordinate(index + 1, coordinate); + rearGearTeeth.setNormal(index + 1, rearToothNormal); + + coordinate.set(xOuter2, yOuter2, toothTipRearZ); + rearGearTeeth.setCoordinate(index + 2, coordinate); + rearGearTeeth.setNormal(index + 2, rearToothNormal); + + coordinate.set(xRoot3, yRoot3, rearZ); + rearGearTeeth.setCoordinate(index + 3, coordinate); + rearGearTeeth.setNormal(index + 3, rearToothNormal); + + } + newShape = new Shape3D(rearGearTeeth, look); + this.addChild(newShape); + + /* + * Construct the gear's top teeth faces (As seen from above) + * Root0 Outer1 Outer2 Root3 Root4 (RearZ) + * 0_______3 2_______5 4_______7 6_______9 + * |0 3| |4 7| |8 11| |12 15| + * | | | | | | | | + * | | | | | | | | + * |1_____2| |5_____6| |9____10| |13___14| + * 1 2 3 4 5 6 7 8 + * Root0 Outer1 Outer2 Root3 Root4 (FrontZ) + * + * Quad 0123 uses a left normal + * Quad 2345 uses an out normal + * Quad 4567 uses a right normal + * Quad 6789 uses an out normal + */ + topVertexCount = 8 * toothCount + 2; + topStripCount[0] = topVertexCount; + + toothFacetVertexCount = 4; + toothFacetCount = 4; + + QuadArray topGearTeeth + = new QuadArray(toothCount * toothFacetVertexCount + * toothFacetCount, + GeometryArray.COORDINATES + | GeometryArray.NORMALS); + + for(int count = 0; count < toothCount; count++) { + index = count * toothFacetCount * toothFacetVertexCount; + toothStartAngle = gearStartAngle + + circularPitchAngle * (double)count; + toothTopStartAngle = toothStartAngle + toothTopAngleIncrement; + toothDeclineStartAngle + = toothStartAngle + toothDeclineAngleIncrement; + toothValleyStartAngle + = toothStartAngle + toothValleyAngleIncrement; + nextToothStartAngle = toothStartAngle + circularPitchAngle; + + xRoot0 = rootRadius * (float)Math.cos(toothStartAngle); + yRoot0 = rootRadius * (float)Math.sin(toothStartAngle); + xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle); + yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle); + xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle); + yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle); + xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle); + yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle); + xRoot4 = rootRadius * (float)Math.cos(nextToothStartAngle); + yRoot4 = rootRadius * (float)Math.sin(nextToothStartAngle); + + // Compute normal for quad 1 + tempCoordinate1.set(xRoot0, yRoot0, frontZ); + tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ); + tempVector1.sub(tempCoordinate2, tempCoordinate1); + leftNormal.cross(frontNormal, tempVector1); + leftNormal.normalize(); + + // Coordinate labeled 0 in the quad + coordinate.set(xRoot0, yRoot0, rearZ); + topGearTeeth.setCoordinate(index, coordinate); + topGearTeeth.setNormal(index, leftNormal); + + // Coordinate labeled 1 in the quad + coordinate.set(tempCoordinate1); + topGearTeeth.setCoordinate(index + 1, coordinate); + topGearTeeth.setNormal(index + 1, leftNormal); + + // Coordinate labeled 2 in the quad + topGearTeeth.setCoordinate(index + 2, tempCoordinate2); + topGearTeeth.setNormal(index + 2, leftNormal); + topGearTeeth.setCoordinate(index + 5, tempCoordinate2); + + // Coordinate labeled 3 in the quad + coordinate.set(xOuter1, yOuter1, toothTipRearZ); + topGearTeeth.setCoordinate(index + 3, coordinate); + topGearTeeth.setNormal(index + 3, leftNormal); + topGearTeeth.setCoordinate(index + 4, coordinate); + + // Compute normal for quad 2 + tempCoordinate1.set(xOuter1, yOuter1, toothTipFrontZ); + tempCoordinate2.set(xOuter2, yOuter2, toothTipFrontZ); + tempVector1.sub(tempCoordinate2, tempCoordinate1); + outNormal.cross(frontNormal, tempVector1); + outNormal.normalize(); + + topGearTeeth.setNormal(index + 4, outNormal); + topGearTeeth.setNormal(index + 5, outNormal); + + // Coordinate labeled 4 in the quad + topGearTeeth.setCoordinate(index + 6, tempCoordinate2); + topGearTeeth.setNormal(index + 6, outNormal); + topGearTeeth.setCoordinate(index + 9, tempCoordinate2); + + // Coordinate labeled 5 in the quad + coordinate.set(xOuter2, yOuter2, toothTipRearZ); + topGearTeeth.setCoordinate(index + 7, coordinate); + topGearTeeth.setNormal(index + 7, outNormal); + topGearTeeth.setCoordinate(index + 8, coordinate); + + // Compute normal for quad 3 + tempCoordinate1.set(xOuter2, yOuter2, toothTipFrontZ); + tempCoordinate2.set(xRoot3, yRoot3, frontZ); + tempVector1.sub(tempCoordinate2, tempCoordinate1); + rightNormal.cross(frontNormal, tempVector1); + rightNormal.normalize(); + + topGearTeeth.setNormal(index + 8, rightNormal); + topGearTeeth.setNormal(index + 9, rightNormal); + + // Coordinate labeled 7 in the quad + topGearTeeth.setCoordinate(index + 10, tempCoordinate2); + topGearTeeth.setNormal(index + 10, rightNormal); + topGearTeeth.setCoordinate(index + 13, tempCoordinate2); + + // Coordinate labeled 6 in the quad + coordinate.set(xRoot3, yRoot3, rearZ); + topGearTeeth.setCoordinate(index + 11, coordinate); + topGearTeeth.setNormal(index + 11, rightNormal); + topGearTeeth.setCoordinate(index + 12, coordinate); + + // Compute normal for quad 4 + tempCoordinate1.set(xRoot3, yRoot3, frontZ); + tempCoordinate2.set(xRoot4, yRoot4, frontZ); + tempVector1.sub(tempCoordinate2, tempCoordinate1); + outNormal.cross(frontNormal, tempVector1); + outNormal.normalize(); + + topGearTeeth.setNormal(index + 12, outNormal); + topGearTeeth.setNormal(index + 13, outNormal); + + // Coordinate labeled 9 in the quad + topGearTeeth.setCoordinate(index + 14, tempCoordinate2); + topGearTeeth.setNormal(index + 14, outNormal); + + // Coordinate labeled 8 in the quad + coordinate.set(xRoot4, yRoot4, rearZ); + topGearTeeth.setCoordinate(index + 15, coordinate); + topGearTeeth.setNormal(index + 15, outNormal); + + // Prepare for the loop by computing the new normal + toothTopStartAngle + = nextToothStartAngle + toothTopAngleIncrement; + xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle); + yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle); + + tempCoordinate1.set(xRoot4, yRoot4, toothTipFrontZ); + tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ); + tempVector1.sub(tempCoordinate2, tempCoordinate1); + leftNormal.cross(frontNormal, tempVector1); + leftNormal.normalize(); + } + newShape = new Shape3D(topGearTeeth, look); + this.addChild(newShape); + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java b/src/classes/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java new file mode 100644 index 0000000..cd2f4ab --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/gears/SpurGearThinBody.java @@ -0,0 +1,187 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.gears; + +import java.lang.Math.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class SpurGearThinBody extends SpurGear { + + /** + * Construct a SpurGearThinBody; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + */ + public SpurGearThinBody(int toothCount, float pitchCircleRadius, + float shaftRadius, float addendum, float dedendum, + float gearThickness) { + this(toothCount, pitchCircleRadius, shaftRadius, + addendum, dedendum, gearThickness, gearThickness, 0.25f, null); + } + + /** + * Construct a SpurGearThinBody; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + * @param look the gear's appearance + */ + public SpurGearThinBody(int toothCount, float pitchCircleRadius, + float shaftRadius, float addendum, float dedendum, + float gearThickness, + Appearance look) { + this(toothCount, pitchCircleRadius, shaftRadius, + addendum, dedendum, gearThickness, gearThickness, 0.25f, look); + } + + /** + * Construct a SpurGearThinBody; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + * @param toothTipThickness thickness of the tip of the tooth + * @param look the gear's appearance + */ + public SpurGearThinBody(int toothCount, float pitchCircleRadius, + float shaftRadius, float addendum, float dedendum, + float gearThickness, float toothTipThickness, + Appearance look) { + this(toothCount, pitchCircleRadius, shaftRadius, addendum, + dedendum, gearThickness, toothTipThickness, 0.25f, look); + } + + /** + * Construct a SpurGearThinBody; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + * @param toothTipThickness thickness of the tip of the tooth + * @param toothToValleyRatio ratio of tooth valley to circular pitch + * (must be <= .25) + * @param look the gear's appearance object + */ + public SpurGearThinBody(int toothCount, float pitchCircleRadius, + float shaftRadius, float addendum, float dedendum, + float gearThickness, float toothTipThickness, + float toothToValleyAngleRatio, Appearance look) { + + this(toothCount, pitchCircleRadius, shaftRadius, addendum, + dedendum, gearThickness, toothTipThickness, 0.25f, look, + 0.6f * gearThickness, 0.75f * (pitchCircleRadius - shaftRadius)); + } + + /** + * Construct a SpurGearThinBody; + * @return a new spur gear that conforms to the input paramters + * @param toothCount number of teeth + * @param pitchCircleRadius radius at center of teeth + * @param shaftRadius radius of hole at center + * @param addendum distance from pitch circle to top of teeth + * @param dedendum distance from pitch circle to root of teeth + * @param gearThickness thickness of the gear + * @param toothTipThickness thickness of the tip of the tooth + * @param toothToValleyRatio ratio of tooth valley to circular pitch + * (must be <= .25) + * @param look the gear's appearance object + * @param bodyThickness the thickness of the gear body + * @param crossSectionWidth the width of the depressed portion of the + * gear's body + */ + public SpurGearThinBody(int toothCount, float pitchCircleRadius, + float shaftRadius, float addendum, float dedendum, + float gearThickness, float toothTipThickness, + float toothToValleyAngleRatio, Appearance look, + float bodyThickness, float crossSectionWidth) { + + super(toothCount, pitchCircleRadius, addendum, dedendum, + toothToValleyAngleRatio); + + float diskCrossSectionWidth = + (rootRadius - shaftRadius - crossSectionWidth)/ 2.0f; + float outerShaftRadius = shaftRadius + diskCrossSectionWidth; + float innerToothRadius = rootRadius - diskCrossSectionWidth; + + // Generate the gear's body disks, first by the shaft, then in + // the body and, lastly, by the teeth + addBodyDisks(shaftRadius, outerShaftRadius, + gearThickness, look); + addBodyDisks(innerToothRadius, rootRadius, + gearThickness, look); + addBodyDisks(outerShaftRadius, innerToothRadius, + bodyThickness, look); + + // Generate the gear's "shaft" equivalents the two at the teeth + // and the two at the shaft + addCylinderSkins(innerToothRadius, gearThickness, InwardNormals, look); + addCylinderSkins(outerShaftRadius, gearThickness, OutwardNormals, look); + + // Generate the gear's interior shaft + addCylinderSkins(shaftRadius, gearThickness, InwardNormals, look); + + // Generate the gear's teeth + addTeeth(pitchCircleRadius, rootRadius, + outsideRadius, gearThickness, toothTipThickness, + toothToValleyAngleRatio, look); + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java new file mode 100644 index 0000000..f53c1ae --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceNIOBuffer.java @@ -0,0 +1,519 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_by_ref; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.*; +import com.sun.j3d.utils.behaviors.vp.*; +import java.nio.*; + +public class GeometryByReferenceNIOBuffer extends JApplet implements ActionListener, +GeometryUpdater { + + RenderingAttributes ra; + ColoringAttributes ca; + Material mat; + Appearance app; + JComboBox geomType; + JComboBox vertexType; + JComboBox colorType; + JCheckBox transparency; + JComboBox updates; + Shape3D shape; + TransparencyAttributes transp; + int updateIndex = 0; + int colorCount = 0, vertexCount = 0; + int vertexIndex = 0, colorIndex = 0; + + GeometryArray tetraRegular, tetraStrip, tetraIndexed, tetraIndexedStrip; + GeometryArray[] geoArrays = new GeometryArray[4]; + + private static final float sqrt3 = (float) Math.sqrt(3.0); + private static final float sqrt3_3 = sqrt3 / 3.0f; + private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f; + + private static final float ycenter = 0.5f * sqrt24_3; + private static final float zcenter = -sqrt3_3; + + private static final Point3f p1 = + new Point3f(-1.0f, -ycenter, -zcenter); + private static final Point3f p2 = + new Point3f(1.0f, -ycenter, -zcenter); + private static final Point3f p3 = + new Point3f(0.0f, -ycenter, -sqrt3 - zcenter); + private static final Point3f p4 = + new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f); + + private static final float[] floatVerts = { + p1.x, p1.y, p1.z, // front face + p2.x, p2.y, p2.z, + p4.x, p4.y, p4.z, + + p1.x, p1.y, p1.z,// left, back face + p4.x, p4.y, p4.z, + p3.x, p3.y, p3.z, + + p2.x, p2.y, p2.z,// right, back face + p3.x, p3.y, p3.z, + p4.x, p4.y, p4.z, + + p1.x, p1.y, p1.z,// bottom face + p3.x, p3.y, p3.z, + p2.x, p2.y, p2.z, + }; + + private static final Color3f c1 = new Color3f(0.6f, 0.0f, 0.0f); + private static final Color3f c2 = new Color3f(0.0f, 0.6f, 0.0f); + private static final Color3f c3 = new Color3f(0.0f, 0.6f, 0.6f); + private static final Color3f c4 = new Color3f(0.6f, 0.6f, 0.0f); + + + + private static final float[] floatClrs = { + c1.x, c1.y, c1.z, // front face + c2.x, c2.y, c2.z, + c4.x, c4.y, c4.z, + + c1.x, c1.y, c1.z,// left, back face + c4.x, c4.y, c4.z, + c3.x, c3.y, c3.z, + + c2.x, c2.y, c2.z,// right, back face + c3.x, c3.y, c3.z, + c4.x, c4.y, c4.z, + + c1.x, c1.y, c1.z,// bottom face + c3.x, c3.y, c3.z, + c2.x, c2.y, c2.z, + }; + + private static final float[] indexedFloatVerts = { + p1.x,p1.y,p1.z, + p2.x,p2.y,p2.z, + p3.x,p3.y,p3.z, + p4.x,p4.y,p4.z, + + }; + + + private static final float[] indexedFloatClrs = { + c1.x,c1.y,c1.z, + c2.x,c2.y,c2.z, + c3.x,c3.y,c3.z, + c4.x,c4.y,c4.z, + }; + + private static final int[] indices = {0,1,3,0,3,2,1,2,3,0,2,1}; + private int[] stripVertexCounts = {3,3,3,3}; + + private SimpleUniverse u; + + private J3DBuffer floatBufferCoord; + private J3DBuffer floatBufferColor; + private J3DBuffer indexedFloatBufferCoord; + private J3DBuffer indexedFloatBufferColor; + + void createJ3DBuffers() { + int i; + ByteOrder order = ByteOrder.nativeOrder(); + + FloatBuffer coord = ByteBuffer.allocateDirect(36 * 4).order(order).asFloatBuffer(); + coord.put(floatVerts, 0, 36); + floatBufferCoord = new J3DBuffer(coord); + + FloatBuffer color = ByteBuffer.allocateDirect(36 * 4).order(order).asFloatBuffer(); + color.put(floatClrs, 0, 36); + floatBufferColor = new J3DBuffer(color); + + FloatBuffer indexedCoord = ByteBuffer.allocateDirect(12 * 4).order(order).asFloatBuffer(); + indexedCoord.put(indexedFloatVerts, 0, 12); + indexedFloatBufferCoord = new J3DBuffer(indexedCoord); + + FloatBuffer indexedColor = ByteBuffer.allocateDirect(12 * 4).order(order).asFloatBuffer(); + indexedColor.put(indexedFloatClrs, 0, 12); + indexedFloatBufferColor = new J3DBuffer(indexedColor); + } + + BranchGroup createSceneGraph() { + BranchGroup objRoot = new BranchGroup(); + + // Set up attributes to render lines + app = new Appearance(); + + transp = new TransparencyAttributes(); + transp.setTransparency(0.5f); + transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE); + transp.setTransparencyMode(TransparencyAttributes.NONE); + app.setTransparencyAttributes(transp); + + //create the direct nio buffer + createJ3DBuffers(); + + tetraRegular = createGeometry(1); + tetraStrip =createGeometry(2); + tetraIndexed = createGeometry(3); + tetraIndexedStrip = createGeometry(4); + + geoArrays[0] = tetraRegular; + geoArrays[1] = tetraStrip; + geoArrays[2] = tetraIndexed; + geoArrays[3] = tetraIndexedStrip; + + shape = new Shape3D(tetraRegular, app); + shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + + Transform3D t = new Transform3D(); + // move the object upwards + t.set(new Vector3f(0.0f, 0.3f, 0.0f)); + + // rotate the shape + Transform3D temp = new Transform3D(); + temp.rotX(Math.PI/4.0d); + t.mul(temp); + temp.rotY(Math.PI/4.0d); + t.mul(temp); + + // Shrink the object + t.setScale(0.6); + + TransformGroup trans = new TransformGroup(t); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + + objRoot.addChild(trans); + trans.addChild(shape); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the global lights + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + objRoot.addChild(aLgt); + objRoot.addChild(lgt1); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + JPanel createGeometryByReferencePanel() { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Geometry Type")); + + String values[] = {"Array", "Strip", "Indexed", "IndexedStrip"}; + geomType = new JComboBox(values); + geomType.setLightWeightPopupEnabled(false); + geomType.addActionListener(this); + geomType.setSelectedIndex(0); + panel.add(new JLabel("Geometry Type")); + panel.add(geomType); + + return panel; + } + + JPanel createUpdatePanel() { + + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Other Attributes")); + + String updateComp[] = { "None","Geometry", "Color"}; + + transparency = new JCheckBox("EnableTransparency", + false); + transparency.addActionListener(this); + panel.add(transparency); + + + updates = new JComboBox(updateComp); + updates.setLightWeightPopupEnabled(false); + updates.addActionListener(this); + updates.setSelectedIndex(0); + panel.add(new JLabel("UpdateData")); + panel.add(updates); + + return panel; + } + + + + public GeometryByReferenceNIOBuffer() { + } + + public void init() { + Container contentPane = getContentPane(); + + Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + contentPane.add("Center", c); + + BranchGroup scene = createSceneGraph(); + // SimpleUniverse is a Convenience Utility class + u = new SimpleUniverse(c); + + // add mouse behaviors to the viewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + u.addBranchGraph(scene); + + // add Orbit behavior to the ViewingPlatform + OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + // Create GUI + JPanel p = new JPanel(); + BoxLayout boxlayout = new BoxLayout(p, + BoxLayout.Y_AXIS); + p.add(createGeometryByReferencePanel()); + p.add(createUpdatePanel()); + p.setLayout(boxlayout); + + contentPane.add("South", p); + } + + public void destroy() { + u.cleanup(); + } + + public void actionPerformed(ActionEvent e) { + Object target = e.getSource(); + GeometryArray geo; + boolean setColor = false, setVertex = false; + if (target == geomType) { + geo = geoArrays[geomType.getSelectedIndex()]; + // Set everything to null, and set it later .. + geo.setColorRefBuffer(null); + geo.setCoordRefBuffer(null); + shape.setGeometry(geoArrays[geomType.getSelectedIndex()]); + + setColor = true; + setVertex= true; + + + } + else if (target == transparency) { + if (transparency.isSelected()) { + transp.setTransparencyMode(TransparencyAttributes.BLENDED); + } + else { + transp.setTransparencyMode(TransparencyAttributes.NONE); + } + + } + else if (target == updates) { + updateIndex = updates.getSelectedIndex(); + if (updateIndex == 1) { + System.out.println("Doing coordinate update"); + ((GeometryArray)(shape.getGeometry())).updateData(this); + } + else if (updateIndex == 2) { + System.out.println("Doing color update"); + ((GeometryArray)(shape.getGeometry())).updateData(this); + } + + } + + if (setVertex) { + geo = (GeometryArray) shape.getGeometry(); + if (geo instanceof IndexedGeometryArray) + geo.setCoordRefBuffer(indexedFloatBufferCoord); + else + geo.setCoordRefBuffer(floatBufferCoord); + + } + if (setColor) { + geo = (GeometryArray) shape.getGeometry(); + if (geo instanceof IndexedGeometryArray) + geo.setColorRefBuffer(indexedFloatBufferColor); + else + geo.setColorRefBuffer(floatBufferColor); + } + } + + + + public static void main(String[] args) { + Frame frame = new MainFrame(new GeometryByReferenceNIOBuffer(), 800, 800); + } + + public GeometryArray createGeometry (int type) { + GeometryArray tetra = null; + if (type == 1) { + tetra =new TriangleArray(12, + TriangleArray.COORDINATES| + TriangleArray.COLOR_3| + TriangleArray.BY_REFERENCE| + TriangleArray.USE_NIO_BUFFER); + + tetra.setCoordRefBuffer(floatBufferCoord); + tetra.setColorRefBuffer(floatBufferColor); + + } + else if (type == 2) { + tetra = new TriangleStripArray(12, + TriangleStripArray.COORDINATES| + TriangleStripArray.COLOR_3| + TriangleStripArray.BY_REFERENCE| + TriangleStripArray.USE_NIO_BUFFER, + stripVertexCounts); + tetra.setCoordRefBuffer(floatBufferCoord); + tetra.setColorRefBuffer(floatBufferColor); + + } + else if (type == 3) { // Indexed Geometry + tetra = new IndexedTriangleArray(4, + IndexedTriangleArray.COORDINATES| + IndexedTriangleArray.COLOR_3| + IndexedTriangleArray.BY_REFERENCE| + IndexedTriangleArray.USE_NIO_BUFFER, + //IndexedTriangleStripArray.USE_COORD_INDEX_ONLY, + 12); + tetra.setCoordRefBuffer(indexedFloatBufferCoord); + tetra.setColorRefBuffer(indexedFloatBufferColor); + ((IndexedTriangleArray)tetra).setCoordinateIndices(0, indices); + ((IndexedTriangleArray)tetra).setColorIndices(0, indices); + } + else if (type == 4) { // Indexed strip geometry + tetra = new IndexedTriangleStripArray(4, + IndexedTriangleStripArray.COORDINATES| + IndexedTriangleStripArray.COLOR_3| + IndexedTriangleStripArray.BY_REFERENCE| + IndexedTriangleStripArray.USE_NIO_BUFFER| + IndexedTriangleStripArray.USE_COORD_INDEX_ONLY, + 12, + stripVertexCounts); + tetra.setCoordRefBuffer(indexedFloatBufferCoord); + tetra.setColorRefBuffer(indexedFloatBufferColor); + ((IndexedTriangleStripArray)tetra).setCoordinateIndices(0, indices); + /* + // Do not set color indices in UCIO mode + ((IndexedTriangleStripArray)tetra).setColorIndices(0, indices); + */ + } + + if (tetra != null) + tetra.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE); + return tetra; + } + + public void updateData(Geometry geometry) { + int i; + float val; + float val1; + if (updateIndex == 1) { // geometry + // Translate the geometry by a small amount in x + vertexCount++; + if ((vertexCount &1) == 1) + val = 0.2f; + else + val = -0.2f; + + FloatBuffer indexedCoord = (FloatBuffer)indexedFloatBufferCoord.getBuffer(); + indexedCoord.rewind(); + FloatBuffer coord = (FloatBuffer)floatBufferCoord.getBuffer(); + coord.rewind(); + + if (vertexIndex == 0) { + // Do Indexed geometry + for (i = 0; i < indexedCoord.limit(); i+=3) { + val1 = indexedCoord.get(i); + indexedCoord.put(i, val1 + val); + } + // Do non-indexed float geometry + for (i = 0; i < coord.limit(); i+=3) { + val1 = coord.get(i); + coord.put(i, val1 + val); + } + } + } + else if (updateIndex == 2) { // colors + colorCount++; + if ((colorCount & 1) == 1) + val = 0.4f; + else + val = -0.4f; + + FloatBuffer indexedColors = (FloatBuffer)indexedFloatBufferColor.getBuffer(); + indexedColors.rewind(); + FloatBuffer colors = (FloatBuffer)floatBufferColor.getBuffer(); + colors.rewind(); + + if (colorIndex == 0) { + // Do Indexed geometry + for (i = 0; i < indexedColors.limit(); i+=3) { + indexedColors.put(i, indexedColors.get(i) + val); + } + // Do non-indexed float geometry + for (i = 0; i < colors.limit(); i+=3) { + colors.put(i, colors.get(i) + val); + } + } + + } + + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java new file mode 100644 index 0000000..a2f3b74 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/GeometryByReferenceTest.java @@ -0,0 +1,554 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_by_ref; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.*; +import com.sun.j3d.utils.behaviors.vp.*; + +public class GeometryByReferenceTest extends JApplet implements ActionListener, +GeometryUpdater { + + RenderingAttributes ra; + ColoringAttributes ca; + Material mat; + Appearance app; + JComboBox geomType; + JComboBox vertexType; + JComboBox colorType; + JCheckBox transparency; + JComboBox updates; + Shape3D shape; + TransparencyAttributes transp; + int updateIndex = 0; + int colorCount = 0, vertexCount = 0; + int vertexIndex = 0, colorIndex = 0; + + GeometryArray tetraRegular, tetraStrip, tetraIndexed, tetraIndexedStrip; + GeometryArray[] geoArrays = new GeometryArray[4]; + + private static final float sqrt3 = (float) Math.sqrt(3.0); + private static final float sqrt3_3 = sqrt3 / 3.0f; + private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f; + + private static final float ycenter = 0.5f * sqrt24_3; + private static final float zcenter = -sqrt3_3; + + private static final Point3f p1 = + new Point3f(-1.0f, -ycenter, -zcenter); + private static final Point3f p2 = + new Point3f(1.0f, -ycenter, -zcenter); + private static final Point3f p3 = + new Point3f(0.0f, -ycenter, -sqrt3 - zcenter); + private static final Point3f p4 = + new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f); + + + private static final float[] floatVerts = { + p1.x, p1.y, p1.z, // front face + p2.x, p2.y, p2.z, + p4.x, p4.y, p4.z, + + p1.x, p1.y, p1.z,// left, back face + p4.x, p4.y, p4.z, + p3.x, p3.y, p3.z, + + p2.x, p2.y, p2.z,// right, back face + p3.x, p3.y, p3.z, + p4.x, p4.y, p4.z, + + p1.x, p1.y, p1.z,// bottom face + p3.x, p3.y, p3.z, + p2.x, p2.y, p2.z, + }; + + private static final Color3f c1 = new Color3f(0.6f, 0.0f, 0.0f); + private static final Color3f c2 = new Color3f(0.0f, 0.6f, 0.0f); + private static final Color3f c3 = new Color3f(0.0f, 0.6f, 0.6f); + private static final Color3f c4 = new Color3f(0.6f, 0.6f, 0.0f); + + + private static final float[] floatClrs = { + c1.x, c1.y, c1.z, // front face + c2.x, c2.y, c2.z, + c4.x, c4.y, c4.z, + + c1.x, c1.y, c1.z,// left, back face + c4.x, c4.y, c4.z, + c3.x, c3.y, c3.z, + + c2.x, c2.y, c2.z,// right, back face + c3.x, c3.y, c3.z, + c4.x, c4.y, c4.z, + + c1.x, c1.y, c1.z,// bottom face + c3.x, c3.y, c3.z, + c2.x, c2.y, c2.z, + } ; + + private static final float[] indexedFloatVerts = { + p1.x,p1.y,p1.z, + p2.x,p2.y,p2.z, + p3.x,p3.y,p3.z, + p4.x,p4.y,p4.z, + + }; + private static final float[] indexedFloatClrs = { + c1.x,c1.y,c1.z, + c2.x,c2.y,c2.z, + c3.x,c3.y,c3.z, + c4.x,c4.y,c4.z, + }; + private static final Point3f[] p3fVerts = { + p1, p2, p4, p1, p4, p3, p2, p3, p4, p1, p3, p2}; + + private static final Point3f[] indexedP3fVerts = {p1, p2, p3, p4}; + + private static final Color3f[] c3fClrs = { + c1, c2, c4, c1, c4, c3, c2, c3, c4, c1, c3, c2}; + + private static final Color3f[] indexedC3fClrs = {c1, c2, c3, c4}; + + + private static final int[] indices = {0,1,3,0,3,2,1,2,3,0,2,1}; + private int[] stripVertexCounts = {3,3,3,3}; + + private SimpleUniverse u; + + BranchGroup createSceneGraph() { + BranchGroup objRoot = new BranchGroup(); + + // Set up attributes to render lines + app = new Appearance(); + + transp = new TransparencyAttributes(); + transp.setTransparency(0.5f); + transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE); + transp.setTransparencyMode(TransparencyAttributes.NONE); + app.setTransparencyAttributes(transp); + + tetraRegular = createGeometry(1); + tetraStrip =createGeometry(2); + tetraIndexed = createGeometry(3); + tetraIndexedStrip = createGeometry(4); + + geoArrays[0] = tetraRegular; + geoArrays[1] = tetraStrip; + geoArrays[2] = tetraIndexed; + geoArrays[3] = tetraIndexedStrip; + + shape = new Shape3D(tetraRegular, app); + shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + + Transform3D t = new Transform3D(); + // move the object upwards + t.set(new Vector3f(0.0f, 0.3f, 0.0f)); + + // rotate the shape + Transform3D temp = new Transform3D(); + temp.rotX(Math.PI/4.0d); + t.mul(temp); + temp.rotY(Math.PI/4.0d); + t.mul(temp); + + // Shrink the object + t.setScale(0.6); + + TransformGroup trans = new TransformGroup(t); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + + objRoot.addChild(trans); + trans.addChild(shape); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the global lights + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + objRoot.addChild(aLgt); + objRoot.addChild(lgt1); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + JPanel createGeometryByReferencePanel() { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Geometry Type")); + + String values[] = {"Array", "Strip", "Indexed", "IndexedStrip"}; + geomType = new JComboBox(values); + geomType.setLightWeightPopupEnabled(false); + geomType.addActionListener(this); + geomType.setSelectedIndex(0); + panel.add(new JLabel("Geometry Type")); + panel.add(geomType); + + + String vertex_types[] = { "Float","P3F"}; + + vertexType = new JComboBox(vertex_types); + vertexType.setLightWeightPopupEnabled(false); + vertexType.addActionListener(this); + vertexType.setSelectedIndex(0); + panel.add(new JLabel("VertexType")); + panel.add(vertexType); + + + String color_types[] = { "Float","C3F"}; + + colorType = new JComboBox(color_types); + colorType.setLightWeightPopupEnabled(false); + colorType.addActionListener(this); + colorType.setSelectedIndex(0); + panel.add(new JLabel("ColorType")); + panel.add(colorType); + + + + + return panel; + } + + JPanel createUpdatePanel() { + + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Other Attributes")); + + String updateComp[] = { "None","Geometry", "Color"}; + + transparency = new JCheckBox("EnableTransparency", + false); + transparency.addActionListener(this); + panel.add(transparency); + + + updates = new JComboBox(updateComp); + updates.setLightWeightPopupEnabled(false); + updates.addActionListener(this); + updates.setSelectedIndex(0); + panel.add(new JLabel("UpdateData")); + panel.add(updates); + + return panel; + } + + + + public GeometryByReferenceTest() { + } + + public void init() { + Container contentPane = getContentPane(); + + Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + contentPane.add("Center", c); + + BranchGroup scene = createSceneGraph(); + // SimpleUniverse is a Convenience Utility class + u = new SimpleUniverse(c); + + // add mouse behaviors to the viewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + u.addBranchGraph(scene); + + // add Orbit behavior to the ViewingPlatform + OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + // Create GUI + JPanel p = new JPanel(); + BoxLayout boxlayout = new BoxLayout(p, + BoxLayout.Y_AXIS); + p.add(createGeometryByReferencePanel()); + p.add(createUpdatePanel()); + p.setLayout(boxlayout); + + contentPane.add("South", p); + } + + public void destroy() { + u.cleanup(); + } + + public void actionPerformed(ActionEvent e) { + Object target = e.getSource(); + GeometryArray geo; + boolean setColor = false, setVertex = false; + if (target == geomType) { + geo = geoArrays[geomType.getSelectedIndex()]; + // Set everything to null, and set it later .. + geo.setColorRefFloat(null); + geo.setColorRef3f(null); + geo.setCoordRefFloat(null); + geo.setCoordRef3f(null); + shape.setGeometry(geoArrays[geomType.getSelectedIndex()]); + + setColor = true; + setVertex= true; + + + } + else if (target == transparency) { + if (transparency.isSelected()) { + transp.setTransparencyMode(TransparencyAttributes.BLENDED); + } + else { + transp.setTransparencyMode(TransparencyAttributes.NONE); + } + + + } + else if (target == updates) { + updateIndex = updates.getSelectedIndex(); + if (updateIndex == 1) { + System.out.println("Doing coordinate update"); + ((GeometryArray)(shape.getGeometry())).updateData(this); + } + else if (updateIndex == 2) { + System.out.println("Doing color update"); + ((GeometryArray)(shape.getGeometry())).updateData(this); + } + + } + else if (target == vertexType) { + geo = ((GeometryArray)shape.getGeometry()); + if (vertexIndex == 0) { + geo.setCoordRefFloat(null); + } + else if (vertexIndex == 1) { + geo.setCoordRef3f(null); + } + vertexIndex = vertexType.getSelectedIndex(); + setVertex = true; + } + else if (target == colorType) { + geo = (GeometryArray) shape.getGeometry(); + if (colorIndex == 0) { + geo.setColorRefFloat(null); + } + else if (colorIndex == 1) { + geo.setColorRef3f(null); + } + colorIndex = colorType.getSelectedIndex(); + setColor = true; + } + + if (setVertex) { + geo = (GeometryArray) shape.getGeometry(); + if (vertexIndex == 0) { + if (geo instanceof IndexedGeometryArray) + geo.setCoordRefFloat(indexedFloatVerts); + else + geo.setCoordRefFloat(floatVerts); + } + else if (vertexIndex == 1) { + if (geo instanceof IndexedGeometryArray) + geo.setCoordRef3f(indexedP3fVerts); + else + geo.setCoordRef3f(p3fVerts); + } + + } + if (setColor) { + geo = (GeometryArray) shape.getGeometry(); + if (colorIndex == 0) { + if (geo instanceof IndexedGeometryArray) + geo.setColorRefFloat(indexedFloatClrs); + else + geo.setColorRefFloat(floatClrs); + } + else if (colorIndex == 1) { + if (geo instanceof IndexedGeometryArray) + geo.setColorRef3f(indexedC3fClrs); + else + geo.setColorRef3f(c3fClrs); + } + } + + } + + + + public static void main(String[] args) { + Frame frame = new MainFrame(new GeometryByReferenceTest(), 800, 800); + } + + public GeometryArray createGeometry (int type) { + GeometryArray tetra = null; + if (type == 1) { + tetra =new TriangleArray(12, + TriangleArray.COORDINATES| + TriangleArray.COLOR_3| + TriangleArray.BY_REFERENCE); + + tetra.setCoordRefFloat(floatVerts); + tetra.setColorRefFloat(floatClrs); + + } + else if (type == 2) { + tetra = new TriangleStripArray(12, + TriangleStripArray.COORDINATES| + TriangleStripArray.COLOR_3| + TriangleStripArray.BY_REFERENCE, + stripVertexCounts); + tetra.setCoordRefFloat(floatVerts); + tetra.setColorRefFloat(floatClrs); + + } + else if (type == 3) { // Indexed Geometry + tetra = new IndexedTriangleArray(4, + IndexedTriangleArray.COORDINATES| + IndexedTriangleArray.COLOR_3| + IndexedTriangleArray.BY_REFERENCE, + 12); + tetra.setCoordRefFloat(indexedFloatVerts); + tetra.setColorRefFloat(indexedFloatClrs); + ((IndexedTriangleArray)tetra).setCoordinateIndices(0, indices); + ((IndexedTriangleArray)tetra).setColorIndices(0, indices); + } + else if (type == 4) { // Indexed strip geometry + tetra = new IndexedTriangleStripArray(4, + IndexedTriangleStripArray.COORDINATES| + IndexedTriangleStripArray.COLOR_3| + IndexedTriangleStripArray.BY_REFERENCE, + 12, + stripVertexCounts); + tetra.setCoordRefFloat(indexedFloatVerts); + tetra.setColorRefFloat(indexedFloatClrs); + ((IndexedTriangleStripArray)tetra).setCoordinateIndices(0, indices); + ((IndexedTriangleStripArray)tetra).setColorIndices(0, indices); + } + + if (tetra != null) + tetra.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE); + return tetra; + } + + public void updateData(Geometry geometry) { + int i; + float val; + + + if (updateIndex == 1) { // geometry + // Translate the geometry by a small amount in x + vertexCount++; + if ((vertexCount &1) == 1) + val = 0.2f; + else + val = -0.2f; + + if (vertexIndex == 0) { + // Do Indexed geometry + for (i = 0; i < indexedFloatVerts.length; i+=3) { + indexedFloatVerts[i] += val; + } + // Do non-indexed float geometry + for (i = 0; i < floatVerts.length; i+=3) { + floatVerts[i] += val; + } + } + else { + // If p3f do each point only once + for (i = 0; i < indexedP3fVerts.length; i++) { + indexedP3fVerts[i].x += val; + } + } + + } + else if (updateIndex == 2) { // colors + colorCount++; + if ((colorCount & 1) == 1) + val = 0.4f; + else + val = -0.4f; + if (colorIndex == 0) { + // Do Indexed geometry + for (i = 0; i < indexedFloatClrs.length; i+=3) { + indexedFloatClrs[i] += val; + } + // Do non-indexed float geometry + for (i = 0; i < floatClrs.length; i+=3) { + floatClrs[i] += val; + } + } + else { + // If c3f do each point only once + for (i = 0; i < indexedC3fClrs.length; i++) { + indexedC3fClrs[i].x += val; + } + } + + } + + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java new file mode 100644 index 0000000..aa649f7 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/ImageComponentByReferenceTest.java @@ -0,0 +1,330 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_by_ref; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.*; +import com.sun.j3d.utils.behaviors.mouse.*; +import com.sun.j3d.utils.image.TextureLoader; +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.geometry.Box; +import com.sun.j3d.utils.geometry.ColorCube; +import java.awt.image.*; +import java.awt.color.ColorSpace; +import com.sun.j3d.utils.geometry.*; + +public class ImageComponentByReferenceTest extends JApplet implements ActionListener { + + Shape3D s1,s2; + TextureLoader t0, t1, t2; + int count = 0; + + Appearance app = new Appearance(); + BranchGroup objRoot = new BranchGroup(); + TransformGroup objTrans = new TransformGroup(); + BufferedImage bImage1; + TiledImage checkBoard; + boolean yUp = false; + boolean byRef = true; + JComboBox rasterType, texType; + ImageComponent2D[] image = new ImageComponent2D[8]; + Appearance dummyApp = new Appearance(); + Texture2D texOne, texCheckBoard; + javax.media.j3d.Raster raster; + Box textureCube; + Shape3D boxShape; + int w1 = 64, h1 = 32, checkw = 16 , checkh = 16; + + private java.net.URL texImage = null; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + objRoot = new BranchGroup(); + + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(Group.ALLOW_CHILDREN_WRITE); + + objRoot.addChild(objTrans); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + app.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + + + textureCube = new Box(0.4f, 0.4f, 0.4f, + Box.GENERATE_TEXTURE_COORDS| + Box.GENERATE_NORMALS, app); + boxShape = textureCube.getShape(Box.FRONT); + boxShape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + objTrans.addChild(textureCube); + + checkBoard = new TiledImage(); + TextureLoader texLoader = new TextureLoader( texImage, this); + ImageComponent2D oneImage = texLoader.getImage(); + bImage1 = oneImage.getImage(); + + int index = 0; + image[index++] = new ImageComponent2D(oneImage.getFormat(), + (RenderedImage)bImage1, + false, + true); + + image[index++] = new ImageComponent2D(oneImage.getFormat(), + (RenderedImage)bImage1, + true, + true); + + + image[index++] = new ImageComponent2D(oneImage.getFormat(), + (RenderedImage)bImage1, + false, + false); + + + image[index++] = new ImageComponent2D(oneImage.getFormat(), + (RenderedImage)bImage1, + true, + false); + + createRaster(objRoot); + + image[index++] = new ImageComponent2D(ImageComponent.FORMAT_RGBA, + checkBoard, + false, + true); + + image[index++] = new ImageComponent2D(ImageComponent.FORMAT_RGBA, + checkBoard, + true, + true); + + + image[index++] = new ImageComponent2D(ImageComponent.FORMAT_RGBA, + checkBoard, + false, + false); + + + image[index++] = new ImageComponent2D(ImageComponent.FORMAT_RGBA, + checkBoard, + true, + false); + + + + texOne = new Texture2D(Texture.BASE_LEVEL, + Texture.RGBA, + image[2].getWidth(), image[2].getHeight()); + + texOne.setCapability(Texture.ALLOW_IMAGE_WRITE); + texOne.setImage(0, image[2]); + + app.setTexture(texOne); + + texCheckBoard = new Texture2D(Texture.BASE_LEVEL, + Texture.RGBA, + image[4].getWidth(), image[4].getHeight()); + + texCheckBoard.setCapability(Texture.ALLOW_IMAGE_WRITE); + objRoot.compile(); + return objRoot; + } + + public void actionPerformed(ActionEvent e ) { + Object target = e.getSource(); + + if (target == rasterType) { + if (rasterType.getSelectedIndex() < 4) { + raster.setSize(w1, h1); + } + else { + raster.setSize(checkw, checkh); + } + raster.setImage(image[rasterType.getSelectedIndex()]); + } + else if (target == texType) { + boxShape.setAppearance(dummyApp); + if (texType.getSelectedIndex() < 4) { + texOne.setImage(0, image[texType.getSelectedIndex()]); + app.setTexture(texOne); + } + else { + texCheckBoard.setImage(0, image[texType.getSelectedIndex()]); + app.setTexture(texCheckBoard); + } + + boxShape.setAppearance(app); + } + + + } + + JPanel createImagePanel() { + JPanel panel = new JPanel(); + String texVals[] = { "One_Yup_ByCopy", + "One_Yup_ByReference", + "One_Ydown_ByCopy", + "One_Ydown_ByReference", + "Checkered_Yup_ByCopy", + "Checkered_Yup_ByReference", + "Checkered_Ydown_ByCopy", + "Checkered_Ydown_ByReference"}; + + rasterType = new JComboBox(texVals); + rasterType.setLightWeightPopupEnabled(false); + rasterType.addActionListener(this); + rasterType.setSelectedIndex(2); + panel.add(new JLabel("Raster Image")); + panel.add(rasterType); + + texType = new JComboBox(texVals); + texType.setLightWeightPopupEnabled(false); + texType.addActionListener(this); + texType.setSelectedIndex(2); + panel.add(new JLabel("Texture Image")); + panel.add(texType); + return panel; + + } + + + + public ImageComponentByReferenceTest() + { + } + + public ImageComponentByReferenceTest(java.net.URL url) { + texImage = url; + } + + public void init() { + if (texImage == null) { + // the path to the image for an applet + try { + texImage = new java.net.URL(getCodeBase().toString() + + "../images/one.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + BranchGroup scene = createSceneGraph();u = new SimpleUniverse(c); + u.getViewingPlatform().setNominalViewingTransform(); + u.addBranchGraph(scene); + Container contentPane = getContentPane(); + JPanel p = new JPanel(); + BoxLayout boxlayout = new BoxLayout(p, + BoxLayout.Y_AXIS); + p.setLayout(boxlayout); + contentPane.add("Center", c); + + contentPane.add("South", p); + + p.add(createImagePanel()); + + } + + public void destroy() { + u.cleanup(); + } + + public static void main(String[] args) { + java.net.URL url = null; + // the path to the image file for an application + try { + url = new java.net.URL("file:../images/one.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + + new MainFrame(new ImageComponentByReferenceTest(url), 800, 700); + } + + void createRaster( BranchGroup scene) { + + + + // Create raster geometries and shapes + Vector3f trans = new Vector3f( ); + Transform3D tr = new Transform3D( ); + TransformGroup tg; + + // Left + raster = new javax.media.j3d.Raster( ); + raster.setCapability(javax.media.j3d.Raster.ALLOW_IMAGE_WRITE); + raster.setCapability(javax.media.j3d.Raster.ALLOW_SIZE_WRITE); + raster.setPosition( new Point3f( -0.9f, 0.75f, 0.0f ) ); + raster.setType( javax.media.j3d.Raster.RASTER_COLOR ); + raster.setOffset( 0, 0 ); + + raster.setSize( image[2].getWidth(), image[2].getHeight() ); + raster.setImage( image[2] ); + Shape3D sh = new Shape3D( raster, new Appearance( ) ); + scene.addChild( sh ); + + + + } +} + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java new file mode 100644 index 0000000..78edf99 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedNIOBuffer.java @@ -0,0 +1,536 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_by_ref; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.image.TextureLoader; +import javax.media.j3d.*; +import javax.vecmath.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.*; +import com.sun.j3d.utils.behaviors.vp.*; +import java.nio.*; + +public class InterleavedNIOBuffer extends JApplet implements ActionListener { + + RenderingAttributes ra; + ColoringAttributes ca; + Material mat; + Appearance app; + JComboBox geomType; + JCheckBox transparency; + JCheckBox textureBox; + Shape3D shape; + TransparencyAttributes transp; + + GeometryArray tetraRegular, tetraStrip, tetraIndexed, tetraIndexedStrip; + GeometryArray[] geoArrays = new GeometryArray[4]; + + // Globally used colors + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f red = new Color3f(1.0f, 0.0f, 0.0f); + Color3f green = new Color3f(0.0f, 1.0f, 0.0f); + Color3f blue = new Color3f(0.0f, 0.0f, 1.0f); + Color3f[] colors = {white, red, green, blue}; + + private static final float sqrt3 = (float) Math.sqrt(3.0); + private static final float sqrt3_3 = sqrt3 / 3.0f; + private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f; + + private static final float ycenter = 0.5f * sqrt24_3; + private static final float zcenter = -sqrt3_3; + + private static final Point3f p1 = + new Point3f(-1.0f, -ycenter, -zcenter); + private static final Point3f p2 = + new Point3f(1.0f, -ycenter, -zcenter); + private static final Point3f p3 = + new Point3f(0.0f, -ycenter, -sqrt3 - zcenter); + private static final Point3f p4 = + new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f); + + private static final Point2f t1 = new Point2f(0.0f, 0.0f); + private static final Point2f t2 = new Point2f(0.5f, 1.0f); + private static final Point2f t3 = new Point2f(1.0f, 0.0f); + private static final Point2f t4 = new Point2f(1.0f, 1.0f); + + private static final Color3f c1 = new Color3f(1.0f, 0.0f, 0.0f); + private static final Color3f c2 = new Color3f(0.0f, 1.0f, 0.0f); + private static final Color3f c3 = new Color3f(0.0f, 1.0f, 1.0f); + private static final Color3f c4 = new Color3f(1.0f, 1.0f, 0.0f); + + + private static final float[] interleaved = { + t1.x, t1.y, + t1.x, t1.y, + c1.x, c1.y, c1.z, // front face + p1.x, p1.y, p1.z, // front face + t2.x, t2.y, + t2.x, t2.y, + c2.x, c2.y, c2.z, + p2.x, p2.y, p2.z, + t4.x, t4.y, + t4.x, t4.y, + c4.x, c4.y, c4.z, + p4.x, p4.y, p4.z, + + t1.x, t1.y, + t1.x, t1.y, + c1.x, c1.y, c1.z,// left, back face + p1.x, p1.y, p1.z,// left, back face + t4.x, t4.y, + t4.x, t4.y, + c4.x, c4.y, c4.z, + p4.x, p4.y, p4.z, + t3.x, t3.y, + t3.x, t3.y, + c3.x, c3.y, c3.z, + p3.x, p3.y, p3.z, + + t2.x, t2.y, + t2.x, t2.y, + c2.x, c2.y, c2.z,// right, back face + p2.x, p2.y, p2.z,// right, back face + t3.x, t3.y, + t3.x, t3.y, + c3.x, c3.y, c3.z, + p3.x, p3.y, p3.z, + t4.x, t4.y, + t4.x, t4.y, + c4.x, c4.y, c4.z, + p4.x, p4.y, p4.z, + + t1.x, t1.y, + t1.x, t1.y, + c1.x, c1.y, c1.z,// bottom face + p1.x, p1.y, p1.z,// bottom face + t3.x, t3.y, + t3.x, t3.y, + c3.x, c3.y, c3.z, + p3.x, p3.y, p3.z, + t2.x, t2.y, + t2.x, t2.y, + c2.x, c2.y, c2.z, + p2.x, p2.y, p2.z, + }; + + private static final float[] indexedInterleaved = { + t1.x,t1.y, + t1.x,t1.y, + c1.x,c1.y,c1.z, + p1.x,p1.y,p1.z, + t2.x,t2.y, + t2.x,t2.y, + c2.x,c2.y,c2.z, + p2.x,p2.y,p2.z, + t3.x,t3.y, + t3.x,t3.y, + c3.x,c3.y,c3.z, + p3.x,p3.y,p3.z, + t4.x,t4.y, + t4.x,t4.y, + c4.x,c4.y,c4.z, + p4.x,p4.y,p4.z, + }; + + + private static final int[] indices = {0,1,3,0,3,2,1,2,3,0,2,1}; + private int[] stripVertexCounts = {3,3,3,3}; + + TextureUnitState textureUnitState[] = new TextureUnitState[2]; + Texture tex1; + Texture tex2; + + private java.net.URL texImage1 = null; + private java.net.URL texImage2 = null; + + private SimpleUniverse u; + + private J3DBuffer interleavedBuffer; + private J3DBuffer indexedInterleavedBuffer; + + void createInterleavedBuffers() { + int size; + ByteOrder order = ByteOrder.nativeOrder(); + + size = (2 + 2 + 3 + 3 ) * 3 * 4; + FloatBuffer vertex = ByteBuffer.allocateDirect(size * 4).order(order).asFloatBuffer(); + vertex.put(interleaved, 0, size); + interleavedBuffer = new J3DBuffer(vertex); + + size = ( 2 + 2 + 3 + 3) * 4; + FloatBuffer indexedVertex = ByteBuffer.allocateDirect(size * 4).order(order).asFloatBuffer(); + indexedVertex.put(indexedInterleaved, 0, size); + indexedInterleavedBuffer = new J3DBuffer(indexedVertex); + } + + BranchGroup createSceneGraph() { + BranchGroup objRoot = new BranchGroup(); + + // Set up attributes to render lines + app = new Appearance(); + app.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE); + + transp = new TransparencyAttributes(); + transp.setTransparency(0.5f); + transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE); + transp.setTransparencyMode(TransparencyAttributes.NONE); + app.setTransparencyAttributes(transp); + + // load textures + TextureAttributes texAttr1 = new TextureAttributes(); + texAttr1.setTextureMode(TextureAttributes.DECAL); + TextureAttributes texAttr2 = new TextureAttributes(); + texAttr2.setTextureMode(TextureAttributes.MODULATE); + + TextureLoader tex = new TextureLoader(texImage1, new String("RGB"), this); + if (tex == null) + return null; + tex1 = tex.getTexture(); + + tex = new TextureLoader(texImage2, new String("RGB"), this); + if (tex == null) + return null; + tex2 = tex.getTexture(); + + textureUnitState[0] = new TextureUnitState(tex1, texAttr1, null); + textureUnitState[1] = new TextureUnitState(tex2, texAttr2, null); + + createInterleavedBuffers(); + + tetraRegular = createGeometry(1); + tetraStrip =createGeometry(2); + tetraIndexed = createGeometry(3); + tetraIndexedStrip = createGeometry(4); + + geoArrays[0] = tetraRegular; + geoArrays[1] = tetraStrip; + geoArrays[2] = tetraIndexed; + geoArrays[3] = tetraIndexedStrip; + + shape = new Shape3D(tetraRegular, app); + shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + + Transform3D t = new Transform3D(); + // move the object upwards + t.set(new Vector3f(0.0f, 0.3f, 0.0f)); + + // rotate the shape + Transform3D temp = new Transform3D(); + temp.rotX(Math.PI/4.0d); + t.mul(temp); + temp.rotY(Math.PI/4.0d); + t.mul(temp); + + // Shrink the object + t.setScale(0.6); + + TransformGroup trans = new TransformGroup(t); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + + objRoot.addChild(trans); + trans.addChild(shape); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the global lights + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + objRoot.addChild(aLgt); + objRoot.addChild(lgt1); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + JPanel createGeometryByReferencePanel() { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Geometry Type")); + + String values[] = {"Array", "Strip", "Indexed", "IndexedStrip"}; + geomType = new JComboBox(values); + geomType.setLightWeightPopupEnabled(false); + geomType.addActionListener(this); + geomType.setSelectedIndex(0); + panel.add(new JLabel("Geometry Type")); + panel.add(geomType); + + transparency = new JCheckBox("EnableTransparency", + false); + transparency.addActionListener(this); + panel.add(transparency); + + textureBox = new JCheckBox("EnableTexture", false); + textureBox.addActionListener(this); + panel.add(textureBox); + + return panel; + } + + public InterleavedNIOBuffer() { + } + + public InterleavedNIOBuffer(java.net.URL texURL1, java.net.URL texURL2) { + texImage1 = texURL1; + texImage2 = texURL2; + } + + public void init() { + + // create textures + + if (texImage1 == null) { + // the path to the image for an applet + try { + texImage1 = new java.net.URL(getCodeBase().toString() + + "../images/bg.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + if (texImage2 == null) { + // the path to the image for an applet + try { + texImage2 = new java.net.URL(getCodeBase().toString() + + "../images/one.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + Container contentPane = getContentPane(); + + Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + contentPane.add("Center", c); + + BranchGroup scene = createSceneGraph(); + // SimpleUniverse is a Convenience Utility class + u = new SimpleUniverse(c); + + // add mouse behaviors to the viewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + // add Orbit behavior to the viewing platform + OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + u.addBranchGraph(scene); + + + // Create GUI + JPanel p = new JPanel(); + BoxLayout boxlayout = new BoxLayout(p, + BoxLayout.Y_AXIS); + p.add(createGeometryByReferencePanel()); + p.setLayout(boxlayout); + + contentPane.add("South", p); + } + + public void destroy() { + u.cleanup(); + } + + public void actionPerformed(ActionEvent e) { + Object target = e.getSource(); + if (target == geomType) { + shape.setGeometry(geoArrays[geomType.getSelectedIndex()]); + + } + else if (target == transparency) { + if (transparency.isSelected()) { + transp.setTransparencyMode(TransparencyAttributes.BLENDED); + } + else { + transp.setTransparencyMode(TransparencyAttributes.NONE); + } + } + else if (target == textureBox) { + if (textureBox.isSelected()) { + app.setTextureUnitState(textureUnitState); + } + else { + app.setTextureUnitState(null); + } + } + } + + + + public static void main(String[] args) { + java.net.URL texURL1 = null; + java.net.URL texURL2 = null; + // the path to the image for an application + try { + texURL1 = new java.net.URL("file:../images/bg.jpg"); + texURL2 = new java.net.URL("file:../images/one.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + + Frame frame = new MainFrame(new InterleavedNIOBuffer(texURL1, texURL2), + 800, 800); + } + + public GeometryArray createGeometry (int type) { + GeometryArray tetra = null; + int texCoordSetMap[] = {0, 0}; + + if (type == 1) { + tetra =new TriangleArray(12, + TriangleArray.COORDINATES| + TriangleArray.COLOR_3| + /* + TriangleArray.NORMAL_3| + */ + TriangleArray.TEXTURE_COORDINATE_2 | + TriangleArray.INTERLEAVED| + TriangleArray.BY_REFERENCE| + TriangleArray.USE_NIO_BUFFER, + 2, texCoordSetMap); + + tetra.setInterleavedVertexBuffer(interleavedBuffer); + + } + else if (type == 2) { + tetra = new TriangleStripArray(12, + TriangleStripArray.COORDINATES| + TriangleStripArray.COLOR_3| + /* + TriangleArray.NORMAL_3| + */ + TriangleArray.TEXTURE_COORDINATE_2 | + TriangleStripArray.INTERLEAVED| + TriangleStripArray.BY_REFERENCE| + TriangleStripArray.USE_NIO_BUFFER, + 2, texCoordSetMap, + stripVertexCounts); + tetra.setInterleavedVertexBuffer(interleavedBuffer); + + + } + else if (type == 3) { // Indexed Geometry + tetra = new IndexedTriangleArray(4, + IndexedTriangleArray.COORDINATES| + IndexedTriangleArray.COLOR_3| + /* + IndexedTriangleArray.NORMAL_3| + */ + IndexedTriangleArray.TEXTURE_COORDINATE_2 | + IndexedTriangleArray.INTERLEAVED| + IndexedTriangleArray.BY_REFERENCE| + IndexedTriangleArray.USE_NIO_BUFFER| + IndexedTriangleArray.USE_COORD_INDEX_ONLY, + 2, texCoordSetMap, + 12); + tetra.setInterleavedVertexBuffer(indexedInterleavedBuffer); + ((IndexedTriangleArray)tetra).setCoordinateIndices(0, indices); + /* + // Do not set color or texcoord indices in UCIO mode + ((IndexedTriangleArray)tetra).setColorIndices(0, indices); + ((IndexedTriangleArray)tetra).setTextureCoordinateIndices( + 0, 0, indices); + ((IndexedTriangleArray)tetra).setTextureCoordinateIndices( + 1, 0, indices); + */ + } + else if (type == 4) { // Indexed strip geometry + tetra = new IndexedTriangleStripArray(4, + IndexedTriangleStripArray.COORDINATES| + IndexedTriangleStripArray.COLOR_3| + /* + IndexedTriangleArray.NORMAL_3| + */ + IndexedTriangleArray.TEXTURE_COORDINATE_2 | + IndexedTriangleStripArray.INTERLEAVED| + IndexedTriangleStripArray.BY_REFERENCE| + IndexedTriangleStripArray.USE_NIO_BUFFER, + //IndexedTriangleStripArray.USE_COORD_INDEX_ONLY, + 2, texCoordSetMap, + 12, + stripVertexCounts); + tetra.setInterleavedVertexBuffer(indexedInterleavedBuffer); + ((IndexedTriangleStripArray)tetra).setCoordinateIndices(0, indices); + ((IndexedTriangleStripArray)tetra).setColorIndices(0, indices); + ((IndexedTriangleStripArray)tetra).setTextureCoordinateIndices( + 0, 0, indices); + ((IndexedTriangleStripArray)tetra).setTextureCoordinateIndices( + 1, 0, indices); + } + else if (type == 5) { // Interleaved array + } + return tetra; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java new file mode 100644 index 0000000..788e1f6 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/InterleavedTest.java @@ -0,0 +1,506 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_by_ref; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.image.TextureLoader; +import javax.media.j3d.*; +import javax.vecmath.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.*; +import com.sun.j3d.utils.behaviors.vp.*; + +public class InterleavedTest extends JApplet implements ActionListener { + + RenderingAttributes ra; + ColoringAttributes ca; + Material mat; + Appearance app; + JComboBox geomType; + JCheckBox transparency; + JCheckBox textureBox; + Shape3D shape; + TransparencyAttributes transp; + + GeometryArray tetraRegular, tetraStrip, tetraIndexed, tetraIndexedStrip; + GeometryArray[] geoArrays = new GeometryArray[4]; + + // Globally used colors + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f red = new Color3f(1.0f, 0.0f, 0.0f); + Color3f green = new Color3f(0.0f, 1.0f, 0.0f); + Color3f blue = new Color3f(0.0f, 0.0f, 1.0f); + Color3f[] colors = {white, red, green, blue}; + + private static final float sqrt3 = (float) Math.sqrt(3.0); + private static final float sqrt3_3 = sqrt3 / 3.0f; + private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f; + + private static final float ycenter = 0.5f * sqrt24_3; + private static final float zcenter = -sqrt3_3; + + private static final Point3f p1 = + new Point3f(-1.0f, -ycenter, -zcenter); + private static final Point3f p2 = + new Point3f(1.0f, -ycenter, -zcenter); + private static final Point3f p3 = + new Point3f(0.0f, -ycenter, -sqrt3 - zcenter); + private static final Point3f p4 = + new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f); + + private static final Point2f t1 = new Point2f(0.0f, 0.0f); + private static final Point2f t2 = new Point2f(0.5f, 1.0f); + private static final Point2f t3 = new Point2f(1.0f, 0.0f); + private static final Point2f t4 = new Point2f(1.0f, 1.0f); + + private static final Color3f c1 = new Color3f(1.0f, 0.0f, 0.0f); + private static final Color3f c2 = new Color3f(0.0f, 1.0f, 0.0f); + private static final Color3f c3 = new Color3f(0.0f, 1.0f, 1.0f); + private static final Color3f c4 = new Color3f(1.0f, 1.0f, 0.0f); + + + private static final float[] interleaved = { + t1.x, t1.y, + t1.x, t1.y, + c1.x, c1.y, c1.z, // front face + p1.x, p1.y, p1.z, // front face + t2.x, t2.y, + t2.x, t2.y, + c2.x, c2.y, c2.z, + p2.x, p2.y, p2.z, + t4.x, t4.y, + t4.x, t4.y, + c4.x, c4.y, c4.z, + p4.x, p4.y, p4.z, + + t1.x, t1.y, + t1.x, t1.y, + c1.x, c1.y, c1.z,// left, back face + p1.x, p1.y, p1.z,// left, back face + t4.x, t4.y, + t4.x, t4.y, + c4.x, c4.y, c4.z, + p4.x, p4.y, p4.z, + t3.x, t3.y, + t3.x, t3.y, + c3.x, c3.y, c3.z, + p3.x, p3.y, p3.z, + + t2.x, t2.y, + t2.x, t2.y, + c2.x, c2.y, c2.z,// right, back face + p2.x, p2.y, p2.z,// right, back face + t3.x, t3.y, + t3.x, t3.y, + c3.x, c3.y, c3.z, + p3.x, p3.y, p3.z, + t4.x, t4.y, + t4.x, t4.y, + c4.x, c4.y, c4.z, + p4.x, p4.y, p4.z, + + t1.x, t1.y, + t1.x, t1.y, + c1.x, c1.y, c1.z,// bottom face + p1.x, p1.y, p1.z,// bottom face + t3.x, t3.y, + t3.x, t3.y, + c3.x, c3.y, c3.z, + p3.x, p3.y, p3.z, + t2.x, t2.y, + t2.x, t2.y, + c2.x, c2.y, c2.z, + p2.x, p2.y, p2.z, + }; + + private static final float[] indexedInterleaved = { + t1.x,t1.y, + t1.x,t1.y, + c1.x,c1.y,c1.z, + p1.x,p1.y,p1.z, + t2.x,t2.y, + t2.x,t2.y, + c2.x,c2.y,c2.z, + p2.x,p2.y,p2.z, + t3.x,t3.y, + t3.x,t3.y, + c3.x,c3.y,c3.z, + p3.x,p3.y,p3.z, + t4.x,t4.y, + t4.x,t4.y, + c4.x,c4.y,c4.z, + p4.x,p4.y,p4.z, + }; + + + private static final int[] indices = {0,1,3,0,3,2,1,2,3,0,2,1}; + private int[] stripVertexCounts = {3,3,3,3}; + + TextureUnitState textureUnitState[] = new TextureUnitState[2]; + Texture tex1; + Texture tex2; + + private java.net.URL texImage1 = null; + private java.net.URL texImage2 = null; + + private SimpleUniverse u; + + BranchGroup createSceneGraph() { + BranchGroup objRoot = new BranchGroup(); + + // Set up attributes to render lines + app = new Appearance(); + app.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_WRITE); + + transp = new TransparencyAttributes(); + transp.setTransparency(0.5f); + transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE); + transp.setTransparencyMode(TransparencyAttributes.NONE); + app.setTransparencyAttributes(transp); + + // load textures + TextureAttributes texAttr1 = new TextureAttributes(); + texAttr1.setTextureMode(TextureAttributes.DECAL); + TextureAttributes texAttr2 = new TextureAttributes(); + texAttr2.setTextureMode(TextureAttributes.MODULATE); + + TextureLoader tex = new TextureLoader(texImage1, new String("RGB"), this); + if (tex == null) + return null; + tex1 = tex.getTexture(); + + tex = new TextureLoader(texImage2, new String("RGB"), this); + if (tex == null) + return null; + tex2 = tex.getTexture(); + + textureUnitState[0] = new TextureUnitState(tex1, texAttr1, null); + textureUnitState[1] = new TextureUnitState(tex2, texAttr2, null); + + tetraRegular = createGeometry(1); + tetraStrip =createGeometry(2); + tetraIndexed = createGeometry(3); + tetraIndexedStrip = createGeometry(4); + + geoArrays[0] = tetraRegular; + geoArrays[1] = tetraStrip; + geoArrays[2] = tetraIndexed; + geoArrays[3] = tetraIndexedStrip; + + shape = new Shape3D(tetraRegular, app); + shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + + Transform3D t = new Transform3D(); + // move the object upwards + t.set(new Vector3f(0.0f, 0.3f, 0.0f)); + + // rotate the shape + Transform3D temp = new Transform3D(); + temp.rotX(Math.PI/4.0d); + t.mul(temp); + temp.rotY(Math.PI/4.0d); + t.mul(temp); + + // Shrink the object + t.setScale(0.6); + + TransformGroup trans = new TransformGroup(t); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + + objRoot.addChild(trans); + trans.addChild(shape); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the global lights + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + objRoot.addChild(aLgt); + objRoot.addChild(lgt1); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + JPanel createGeometryByReferencePanel() { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder("Geometry Type")); + + String values[] = {"Array", "Strip", "Indexed", "IndexedStrip"}; + geomType = new JComboBox(values); + geomType.setLightWeightPopupEnabled(false); + geomType.addActionListener(this); + geomType.setSelectedIndex(0); + panel.add(new JLabel("Geometry Type")); + panel.add(geomType); + + transparency = new JCheckBox("EnableTransparency", + false); + transparency.addActionListener(this); + panel.add(transparency); + + textureBox = new JCheckBox("EnableTexture", false); + textureBox.addActionListener(this); + panel.add(textureBox); + + return panel; + } + + public InterleavedTest() { + } + + public InterleavedTest(java.net.URL texURL1, java.net.URL texURL2) { + texImage1 = texURL1; + texImage2 = texURL2; + } + + public void init() { + + // create textures + + if (texImage1 == null) { + // the path to the image for an applet + try { + texImage1 = new java.net.URL(getCodeBase().toString() + + "../images/bg.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + if (texImage2 == null) { + // the path to the image for an applet + try { + texImage2 = new java.net.URL(getCodeBase().toString() + + "../images/one.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + Container contentPane = getContentPane(); + + Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + contentPane.add("Center", c); + + BranchGroup scene = createSceneGraph(); + // SimpleUniverse is a Convenience Utility class + u = new SimpleUniverse(c); + + // add mouse behaviors to the viewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + // add Orbit behavior to the viewing platform + OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + u.addBranchGraph(scene); + + + // Create GUI + JPanel p = new JPanel(); + BoxLayout boxlayout = new BoxLayout(p, + BoxLayout.Y_AXIS); + p.add(createGeometryByReferencePanel()); + p.setLayout(boxlayout); + + contentPane.add("South", p); + } + + public void destroy() { + u.cleanup(); + } + + public void actionPerformed(ActionEvent e) { + Object target = e.getSource(); + if (target == geomType) { + shape.setGeometry(geoArrays[geomType.getSelectedIndex()]); + + } + else if (target == transparency) { + if (transparency.isSelected()) { + transp.setTransparencyMode(TransparencyAttributes.BLENDED); + } + else { + transp.setTransparencyMode(TransparencyAttributes.NONE); + } + } + else if (target == textureBox) { + if (textureBox.isSelected()) { + app.setTextureUnitState(textureUnitState); + } + else { + app.setTextureUnitState(null); + } + } + } + + + + public static void main(String[] args) { + java.net.URL texURL1 = null; + java.net.URL texURL2 = null; + // the path to the image for an application + try { + texURL1 = new java.net.URL("file:../images/bg.jpg"); + texURL2 = new java.net.URL("file:../images/one.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + + Frame frame = new MainFrame(new InterleavedTest(texURL1, texURL2), + 800, 800); + } + + public GeometryArray createGeometry (int type) { + GeometryArray tetra = null; + int texCoordSetMap[] = {0, 0}; + + if (type == 1) { + tetra =new TriangleArray(12, + TriangleArray.COORDINATES| + TriangleArray.COLOR_3| + /* + TriangleArray.NORMAL_3| + */ + TriangleArray.TEXTURE_COORDINATE_2 | + TriangleArray.INTERLEAVED| + TriangleArray.BY_REFERENCE, + 2, texCoordSetMap); + + tetra.setInterleavedVertices(interleaved); + + } + else if (type == 2) { + tetra = new TriangleStripArray(12, + TriangleStripArray.COORDINATES| + TriangleStripArray.COLOR_3| + /* + TriangleArray.NORMAL_3| + */ + TriangleArray.TEXTURE_COORDINATE_2 | + TriangleStripArray.INTERLEAVED| + TriangleStripArray.BY_REFERENCE, + 2, texCoordSetMap, + stripVertexCounts); + tetra.setInterleavedVertices(interleaved); + + + } + else if (type == 3) { // Indexed Geometry + tetra = new IndexedTriangleArray(4, + IndexedTriangleArray.COORDINATES| + IndexedTriangleArray.COLOR_3| + /* + IndexedTriangleArray.NORMAL_3| + */ + IndexedTriangleArray.TEXTURE_COORDINATE_2 | + IndexedTriangleArray.INTERLEAVED| + IndexedTriangleArray.BY_REFERENCE, + 2, texCoordSetMap, + 12); + tetra.setInterleavedVertices(indexedInterleaved); + ((IndexedTriangleArray)tetra).setCoordinateIndices(0, indices); + ((IndexedTriangleArray)tetra).setColorIndices(0, indices); + ((IndexedTriangleArray)tetra).setTextureCoordinateIndices( + 0, 0, indices); + ((IndexedTriangleArray)tetra).setTextureCoordinateIndices( + 1, 0, indices); + } + else if (type == 4) { // Indexed strip geometry + tetra = new IndexedTriangleStripArray(4, + IndexedTriangleStripArray.COORDINATES| + IndexedTriangleStripArray.COLOR_3| + /* + IndexedTriangleArray.NORMAL_3| + */ + IndexedTriangleArray.TEXTURE_COORDINATE_2 | + IndexedTriangleStripArray.INTERLEAVED| + IndexedTriangleStripArray.BY_REFERENCE, + 2, texCoordSetMap, + 12, + stripVertexCounts); + tetra.setInterleavedVertices(indexedInterleaved); + ((IndexedTriangleStripArray)tetra).setCoordinateIndices(0, indices); + ((IndexedTriangleStripArray)tetra).setColorIndices(0, indices); + ((IndexedTriangleStripArray)tetra).setTextureCoordinateIndices( + 0, 0, indices); + ((IndexedTriangleStripArray)tetra).setTextureCoordinateIndices( + 1, 0, indices); + } + else if (type == 5) { // Interleaved array + } + return tetra; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java new file mode 100644 index 0000000..fcc51e4 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_by_ref/TiledImage.java @@ -0,0 +1,358 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_by_ref; + +import java.awt.*; +import java.awt.image.*; +import java.util.Vector; +import java.awt.color.ColorSpace; + +public class TiledImage extends Object implements RenderedImage { + + + WritableRaster[][] tile = new WritableRaster[3][3]; + + WritableRaster bigTile; + ComponentColorModel colorModel; + BufferedImage checkBoard; + int minX = -2; + int minY = -1; + + TiledImage() { + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + int i, j, k, cc = 255; + int[] bandOffset = new int[4]; + colorModel = + new ComponentColorModel(cs, nBits, true, false, Transparency.OPAQUE, 0); + // Create 9 tiles + bandOffset[0] = 3; + bandOffset[1] = 2; + bandOffset[2] = 1; + bandOffset[3] = 0; + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + tile[i][j] = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, 8, 8 , 32, 4, bandOffset, null); + } + } + + // tile {-2, -1} + byte[] byteData = ((DataBufferByte)tile[0][0].getDataBuffer()).getData(); + for (i=4, k = 8 * 4 * 4+4 * 4;i < 8;i++, k+= 16){ + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)cc; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + } + + // tile {-1, -1} + byteData = ((DataBufferByte)tile[1][0].getDataBuffer()).getData(); + for (i=4, k = 8 * 4 * 4;i < 8;i++){ + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)cc; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + } + + // tile {1, -1} + byteData = ((DataBufferByte)tile[2][0].getDataBuffer()).getData(); + for (i=4, k = 8 * 4 * 4;i < 8;i++, k+= 16){ + for (j=0;j < 4;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + } + + // tile {-2, 0} + byteData = ((DataBufferByte)tile[0][1].getDataBuffer()).getData(); + for (i=0, k = 16;i < 4;i++, k+=16){ + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)cc; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + } + for (i=4, k = 8*4*4+16;i < 8;i++, k+=16){ + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)0 ; + } + } + // tile {-1, 0} + byteData = ((DataBufferByte)tile[1][1].getDataBuffer()).getData(); + for (i=0, k = 0;i < 4;i++){ + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)cc; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + } + for (i=0, k = 8 * 4 * 4;i < 4;i++){ + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)0 ; + } + + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)cc ; + } + + } + + + // tile {0, 0} + byteData = ((DataBufferByte)tile[2][1].getDataBuffer()).getData(); + for (i=0, k = 0;i < 4;i++, k+= 16) { + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + } + for (i=4, k = 8 * 4* 4;i < 8;i++, k+= 16) { + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)cc ; + } + } + + + // tile {-2, 1} + byteData = ((DataBufferByte)tile[0][2].getDataBuffer()).getData(); + for (i=4, k = 16;i < 8;i++, k+= 16) { + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)0 ; + } + } + + + // tile {-1, 1} + byteData = ((DataBufferByte)tile[1][2].getDataBuffer()).getData(); + for (i=0, k = 0;i < 8;i++) { + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)0 ; + } + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)cc ; + } + } + + + + // tile {0, 1} + byteData = ((DataBufferByte)tile[2][2].getDataBuffer()).getData(); + for (i=4, k = 0;i < 8;i++, k+= 16) { + for (j=4;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)cc ; + } + } + + bigTile = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, 16, 16 , 64, 4, bandOffset, null);; + byteData = ((DataBufferByte)bigTile.getDataBuffer()).getData(); + for (i=0, k = 0;i < 8;i++){ + for (j=0;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)cc; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + for (;j < 16;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)0; + byteData[k+3] = (byte)cc ; + } + } + for (;i < 16;i++){ + for (j=0;j < 8;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)0; + } + for (;j < 16;j++, k+=4){ + byteData[k] = (byte)0; + byteData[k+1] = (byte)0; + byteData[k+2] = (byte)cc; + byteData[k+3] = (byte)cc ; + } + } + checkBoard = new BufferedImage(colorModel, bigTile, false, null); + } + + + + // create four tiles {r, g, b, y} + public WritableRaster copyData(WritableRaster raster) { + return checkBoard.copyData(raster); + } + + public ColorModel getColorModel() { + return checkBoard.getColorModel(); + } + + public Raster getData() { + return checkBoard.getData(); + } + + public Raster getData(Rectangle rect) { + return checkBoard.getData(rect); + } + + public int getHeight() { + return 16; + } + + public int getMinTileX() { + return minX; + } + + public int getMinTileY() { + return minY; + } + + public int getMinX () { + return -8; + } + + public int getMinY () { + return -8; + } + + public int getNumXTiles() { + return 3; + } + + public int getNumYTiles() { + return 3; + } + + public Object getProperty(String name) { + return checkBoard.getProperty(name); + } + + public String[] getPropertyNames() { + return checkBoard.getPropertyNames(); + } + + + public SampleModel getSampleModel() { + return checkBoard.getSampleModel(); + } + + public Vector getSources() { + return null; + } + + public Raster getTile(int tileX, int tileY) { + return tile[tileX- minX][tileY - minY]; + } + + public int getTileGridXOffset() { + return 4; + } + + public int getTileGridYOffset() { + return -4; + } + + + public int getTileHeight() { + return 8; + } + + + public int getTileWidth() { + return 8; + } + + public int getWidth() { + return 16; + } +} + + diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java b/src/classes/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java new file mode 100644 index 0000000..57267eb --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_compression/ObjectFileCompressor.java @@ -0,0 +1,249 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_compression; + +import com.sun.j3d.utils.compression.* ; +import com.sun.j3d.loaders.objectfile.ObjectFile ; +import com.sun.j3d.loaders.ParsingErrorException ; +import com.sun.j3d.loaders.IncorrectFormatException ; +import com.sun.j3d.loaders.Scene ; +import javax.media.j3d.* ; +import java.util.* ; +import java.net.* ; +import java.io.* ; + +/** + * This extension of ObjectFile provides the methods setQuantization() and + * compress() to compress Wavefront .obj files into the format described by + * appendix B of the Java 3D specification. + */ +public class ObjectFileCompressor extends ObjectFile { + private GeometryCompressor compressor = null ; + + public ObjectFileCompressor() { + super(STRIPIFY | TRIANGULATE) ; + compressor = new GeometryCompressor() ; + } + + public ObjectFileCompressor(int flags) { + super(flags | STRIPIFY | TRIANGULATE) ; + compressor = new GeometryCompressor() ; + } + + public ObjectFileCompressor(int flags, float radians) { + super(flags | STRIPIFY | TRIANGULATE, radians) ; + compressor = new GeometryCompressor() ; + } + + public void setFlags(int flags) { + super.setFlags(flags | STRIPIFY | TRIANGULATE) ; + } + + private int positionQuant = 10 ; + private int colorQuant = 8 ; + private int normalQuant = 3 ; + + /** + * Set the position, normal, and color quantization values for compression. + * @param positionQuant number of bits to quantize each position's X, Y, + * and Z components, ranging from 1 to 16 with a default of 10 + * @param colorQuant number of bits to quantize each color's R, G, B, and + * alpha components, ranging from 2 to 16 with a default of 8 + * @param normalQuant number of bits for quantizing each normal's U and V + * components, ranging from 0 to 6 with a default of 3 + */ + public void setQuantization(int positionQuant, + int colorQuant, + int normalQuant) { + + this.positionQuant = positionQuant ; + this.colorQuant = colorQuant ; + this.normalQuant = normalQuant ; + } + + /** + * Compress the specified .obj file into a CompressedGeometry node + * component. + * @param objFileName String object representing the path to a .obj file + * @return a CompressedGeometry node component + */ + public CompressedGeometry compress(String objFileName) { + return compressScene(getScene(objFileName)) ; + } + + /** + * Compress the specified .obj file and add it to the end of an open + * compressed geometry file. + * @param objFileName String object representing the path to a .obj file + * @param file a currently open CompressedGeometryFile object + * @exception IOException - if write fails + */ + public void compress(String objFileName, CompressedGeometryFile file) + throws IOException { + compressScene(getScene(objFileName), file) ; + } + + /** + * Compress the specified .obj file into a CompressedGeometry node + * component. + * @param reader an open .obj file + * @return a CompressedGeometry node component + */ + public CompressedGeometry compress(Reader reader) { + return compressScene(getScene(reader)) ; + } + + /** + * Compress the specified .obj file and add it to the end of an open + * compressed geometry file. + * @param reader an open .obj file + * @param file an open CompressedGeometryFile object + * @exception IOException - if write fails + */ + public void compress(Reader reader, CompressedGeometryFile file) + throws IOException { + compressScene(getScene(reader), file) ; + } + + /** + * Compress the specified .obj file into a CompressedGeometry node + * component. + * @param url Uniform Resource Locator for the .obj file + * @return a CompressedGeometry node component + */ + public CompressedGeometry compress(URL url) { + return compressScene(getScene(url)) ; + } + + /** + * Compress the specified .obj file and add it to the end of an open + * compressed geometry file. + * @param url Uniform Resource Locator for the .obj file + * @param file a currently open CompressedGeometryFile object + * @exception IOException - if write fails + */ + public void compress(URL url, CompressedGeometryFile file) + throws IOException { + compressScene(getScene(url), file) ; + } + + private CompressedGeometry compressScene(Scene scene) { + return compressor.compress(getStream(scene)) ; + } + + private void compressScene(Scene scene, CompressedGeometryFile file) + throws IOException { + compressor.compress(getStream(scene), file) ; + } + + private CompressionStream getStream(Scene scene) { + Hashtable objs = scene.getNamedObjects() ; + Shape3D shapes[] = new Shape3D[objs.size()] ; + + objs.values().toArray(shapes) ; + return new CompressionStream(positionQuant, colorQuant, normalQuant, + shapes) ; + } + + private Scene getScene(String objFileName) { + Scene scene = null ; + try { + scene = load(objFileName) ; + } + catch (FileNotFoundException e) { + System.err.println(e) ; + System.exit(1) ; + } + catch (ParsingErrorException e) { + System.err.println(e) ; + System.exit(1) ; + } + catch (IncorrectFormatException e) { + System.err.println(e) ; + System.exit(1) ; + } + return scene ; + } + + private Scene getScene(Reader reader) { + Scene scene = null ; + try { + scene = load(reader) ; + } + catch (FileNotFoundException e) { + System.err.println(e) ; + System.exit(1) ; + } + catch (ParsingErrorException e) { + System.err.println(e) ; + System.exit(1) ; + } + catch (IncorrectFormatException e) { + System.err.println(e) ; + System.exit(1) ; + } + return scene ; + } + + private Scene getScene(URL url) { + Scene scene = null ; + try { + scene = load(url) ; + } + catch (FileNotFoundException e) { + System.err.println(e) ; + System.exit(1) ; + } + catch (ParsingErrorException e) { + System.err.println(e) ; + System.exit(1) ; + } + catch (IncorrectFormatException e) { + System.err.println(e) ; + System.exit(1) ; + } + return scene ; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_compression/README.txt b/src/classes/org/jdesktop/j3d/examples/geometry_compression/README.txt new file mode 100644 index 0000000..1cab35b --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_compression/README.txt @@ -0,0 +1,23 @@ +This directory contains example code for using compressed geometry in +Java 3D through the com.sun.j3d.utils.compression package. + +Applications: + + obj2cg -- takes the names of .obj files to compress followed by the name + of a .cg compressed geometry resource file. If the .cg file + doesn't exist, then an attempt is made to create it; otherwise, + new compressed geometry objects are appended to the end. + + The .obj files are compressed and stored into the .cg file in + the order in which they appear in the command line, and can be + accessed through indices [0 .. fileCount-1] + + cgview -- takes the name of a .cg file and the index of the object to + display, which can range from [0 .. objectCount-1]. The object + may rotated, scaled, and translated in response to mouse drags. + + +Utility classes: + + ObjectFileCompressor.java -- + Extends ObjectFile with compression methods. diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_compression/cgview.java b/src/classes/org/jdesktop/j3d/examples/geometry_compression/cgview.java new file mode 100644 index 0000000..2efc221 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_compression/cgview.java @@ -0,0 +1,214 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_compression; + +import com.sun.j3d.utils.compression.* ; +import com.sun.j3d.utils.behaviors.vp.* ; +import com.sun.j3d.utils.applet.MainFrame ; +import com.sun.j3d.utils.universe.* ; +import javax.media.j3d.* ; +import javax.vecmath.* ; +import java.applet.Applet ; +import java.awt.BorderLayout ; +import java.awt.event.* ; +import java.io.* ; + +public class cgview extends Applet { + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph(CompressedGeometry cg) { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup() ; + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup() ; + Transform3D t3d = new Transform3D() ; + t3d.setScale(0.7) ; + objScale.setTransform(t3d) ; + objRoot.addChild(objScale) ; + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup() ; + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE) ; + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ) ; + objScale.addChild(objTrans) ; + + // Add compressed geometry to the scene graph. + CompressedGeometryHeader hdr = new CompressedGeometryHeader() ; + cg.getCompressedGeometryHeader(hdr) ; + + // There isn't really enough information in the compressed geometry + // header to unamiguously determine the proper rendering attributes. + // The bufferDataPresent field specifies whether or not normals are + // bundled with vertices, but the compressed buffer can still contain + // normals that should be lit. Assume that any surface geometry + // should be lit and that lines and points should not unless the + // header contains the NORMAL_IN_BUFFER bit. + Material m = new Material() ; + if ((hdr.bufferType == hdr.TRIANGLE_BUFFER) || + ((hdr.bufferDataPresent & hdr.NORMAL_IN_BUFFER) == 1)) + m.setLightingEnable(true) ; + else + m.setLightingEnable(false) ; + + Appearance a = new Appearance() ; + a.setMaterial(m) ; + + objTrans.addChild(new Shape3D(cg, a)) ; + + // Create mouse behavior scheduling bounds. + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0) ; + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f); + Background bgNode = new Background(bgColor) ; + bgNode.setApplicationBounds(bounds) ; + objRoot.addChild(bgNode) ; + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f) ; + AmbientLight ambientLightNode = new AmbientLight(ambientColor) ; + ambientLightNode.setInfluencingBounds(bounds) ; + objRoot.addChild(ambientLightNode) ; + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f) ; + Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f) ; + Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f) ; + Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -0.9f) ; + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction) ; + light1.setInfluencingBounds(bounds) ; + objRoot.addChild(light1) ; + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction) ; + light2.setInfluencingBounds(bounds) ; + objRoot.addChild(light2) ; + + return objRoot ; + } + + private void usage() { + System.out.println("Usage: cgview <.cg file> ") ; + System.exit(0) ; + } + + public cgview(String args[]) { + if (args.length < 1) + usage() ; + + int index ; + if (args.length < 2) + index = 0 ; + else + index = Integer.parseInt(args[1]) ; + + String filename = args[0] ; + if (filename == null) + usage() ; + + // Read the compressed geometry. + CompressedGeometry cg = null ; + try { + CompressedGeometryFile cgf ; + cgf = new CompressedGeometryFile(filename, false) ; + + if (cgf.getObjectCount() == 0) { + System.out.println("no objects were found in " + filename) ; + System.exit(0) ; + } + + cg = cgf.read(index) ; + cgf.close() ; + + } catch (IOException e) { + System.out.println(e) ; + System.exit(0) ; + } + + setLayout(new BorderLayout()) ; + Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + add("Center", c) ; + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(cg) ; + u = new SimpleUniverse(c) ; + + // add mouse behaviors to the ViewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + u.addBranchGraph(scene) ; + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows cgview to be run as an application + // as well as an applet. + // + public static void main(String[] args) { + new MainFrame(new cgview(args), 700, 700) ; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java b/src/classes/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java new file mode 100644 index 0000000..e863dbc --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/geometry_compression/obj2cg.java @@ -0,0 +1,73 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.geometry_compression; + +import com.sun.j3d.utils.compression.* ; +import javax.media.j3d.* ; +import java.io.* ; + +class obj2cg { + + public static void main(String args[]) throws IOException { + if (args.length < 2) { + System.out.println + ("obj2cg wants the names of .obj files to compress,\n" + + "followed by the name of a .cg file to create or to\n" + + "which to append.") ; + System.exit(0) ; + } + + CompressedGeometryFile file ; + file = new CompressedGeometryFile(args[args.length-1], true) ; + + ObjectFileCompressor compressor ; + compressor = new ObjectFileCompressor() ; + + for (int i = 0 ; i < args.length-1 ; i++) + compressor.compress(args[i], file) ; + + file.close() ; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java new file mode 100644 index 0000000..9841a52 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ObjLoadGLSL.java @@ -0,0 +1,342 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.glsl_shader; + +import com.sun.j3d.loaders.objectfile.ObjectFile; +import com.sun.j3d.loaders.ParsingErrorException; +import com.sun.j3d.loaders.IncorrectFormatException; +import com.sun.j3d.loaders.Scene; +import com.sun.j3d.utils.shader.StringIO; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; +import java.io.*; +import com.sun.j3d.utils.behaviors.vp.*; +import java.net.URL; +import java.net.MalformedURLException; + +public class ObjLoadGLSL extends Applet { + + private String shaderName = "polkadot3d"; + private boolean spin = false; + private boolean noTriangulate = false; + private boolean noStripify = false; + private double creaseAngle = 60.0; + private URL filename = null; + private SimpleUniverse u; + private BoundingSphere bounds; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.7); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objScale.addChild(objTrans); + + int flags = ObjectFile.RESIZE; + if (!noTriangulate) flags |= ObjectFile.TRIANGULATE; + if (!noStripify) flags |= ObjectFile.STRIPIFY; + ObjectFile f = new ObjectFile(flags, + (float)(creaseAngle * Math.PI / 180.0)); + Scene s = null; + try { + s = f.load(filename); + } + catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + catch (ParsingErrorException e) { + throw new RuntimeException(e); + } + catch (IncorrectFormatException e) { + throw new RuntimeException(e); + } + + // Set vertex and fragment shader program for all Shape3D nodes in scene + String vertexProgram = null; + String fragmentProgram = null; + try { + vertexProgram = StringIO.readFully(shaderName + ".vert"); + fragmentProgram = StringIO.readFully(shaderName + ".frag"); + } + catch (IOException e) { + throw new RuntimeException(e); + } + Shader[] shaders = new Shader[2]; + shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_VERTEX, + vertexProgram); + shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_FRAGMENT, + fragmentProgram); + ShaderProgram shaderProgram = new GLSLShaderProgram(); + shaderProgram.setShaders(shaders); + setShaderProgram(s.getSceneGroup(), shaderProgram); + + objTrans.addChild(s.getSceneGroup()); + + bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + if (spin) { + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + } + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f); + Background bgNode = new Background(bgColor); + bgNode.setApplicationBounds(bounds); + objRoot.addChild(bgNode); + + return objRoot; + } + + private void usage() + { + System.out.println( + "Usage: java ObjLoadGLSL [-s] [-S shaderName] [-n] [-t] [-c degrees] <.obj file>"); + System.out.println(" -s Spin (no user interaction)"); + System.out.println(" -S Set shader name (default is 'simple')"); + System.out.println(" -n No triangulation"); + System.out.println(" -t No stripification"); + System.out.println( + " -c Set crease angle for normal generation (default is 60 without"); + System.out.println( + " smoothing group info, otherwise 180 within smoothing groups)"); + System.exit(0); + } // End of usage + + + + public void init() { + if (filename == null) { + // Applet + try { + URL path = getCodeBase(); + filename = new URL(path.toString() + "./galleon.obj"); + } + catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // add mouse behaviors to the ViewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + PlatformGeometry pg = new PlatformGeometry(); + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + pg.addChild(ambientLightNode); + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 0.2f, 0.4f); + Vector3f light1Direction = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light2Direction = new Vector3f(1.0f, 1.0f, 1.0f); + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + pg.addChild(light1); + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + pg.addChild(light2); + + viewingPlatform.setPlatformGeometry( pg ); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + if (!spin) { + OrbitBehavior orbit = new OrbitBehavior(c, + OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + } + + /* + // Limit the frame rate to 100 Hz + u.getViewer().getView().setMinimumFrameCycleTime(10); + */ + + u.addBranchGraph(scene); + } + + // Set shader program for all nodes in specified branch graph + private void setShaderProgram(BranchGroup g, ShaderProgram shaderProgram) { + ShaderAppearance myApp = new ShaderAppearance(); + Material mat = new Material(); + myApp.setShaderProgram(shaderProgram); + myApp.setMaterial(mat); + setShaderProgram(g, myApp); + } + + // Recursively set shader program for all children of specified group + private void setShaderProgram(Group g, + ShaderAppearance myApp) { + + Enumeration e = g.getAllChildren(); + while (e.hasMoreElements()) { + Node n = (Node)(e.nextElement()); + if (n instanceof Group) { + setShaderProgram((Group)n, myApp); + } + else if (n instanceof Shape3D) { + Shape3D s = (Shape3D)n; + s.setAppearance(myApp); + } + } + } + + // Caled if running as a program + public ObjLoadGLSL(String[] args) { + if (args.length != 0) { + for (int i = 0 ; i < args.length ; i++) { + if (args[i].startsWith("-")) { + if (args[i].equals("-s")) { + spin = true; + } else if (args[i].equals("-n")) { + noTriangulate = true; + } else if (args[i].equals("-t")) { + noStripify = true; + } else if (args[i].equals("-c")) { + if (i < args.length - 1) { + creaseAngle = (new Double(args[++i])).doubleValue(); + } else usage(); + } else if (args[i].equals("-S")) { + if (i < args.length - 1) { + shaderName = args[++i]; + } else usage(); + } else { + usage(); + } + } else { + try { + if ((args[i].indexOf("file:") == 0) || + (args[i].indexOf("http") == 0)) { + filename = new URL(args[i]); + } + else if (args[i].charAt(0) != '/') { + filename = new URL("file:./" + args[i]); + } + else { + filename = new URL("file:" + args[i]); + } + } + catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + } + } + } + + + + // Running as an applet + public ObjLoadGLSL() { + } + + public void destroy() { + u.cleanup(); + } + + + + // + // The following allows ObjLoadGLSL to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new ObjLoadGLSL(args), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form b/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form new file mode 100644 index 0000000..dcccf73 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.form @@ -0,0 +1,138 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java b/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java new file mode 100644 index 0000000..4f93a77 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/PhongShadingGLSL.java @@ -0,0 +1,450 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.glsl_shader; + +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.shader.StringIO; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.GraphicsConfiguration; +import java.io.IOException; + +/** + * + * @author kcr + */ +public class PhongShadingGLSL extends javax.swing.JFrame { + + // Constants for type of light to use + private static final int DIRECTIONAL_LIGHT = 0; + private static final int POINT_LIGHT = 1; + private static final int SPOT_LIGHT = 2; + + // Flag indicates type of lights: directional, point, or spot lights. + private static int lightType = DIRECTIONAL_LIGHT; + + private SimpleUniverse u = null; + + private ShaderAppearance sApp = null; + private ShaderProgram gouraudSP = null; + private ShaderProgram phongSP = null; + + public BranchGroup createSceneGraph() { + Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f); + Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f); + Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f); +// Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f); +// Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f); + Color3f lColor1 = new Color3f(1.0f, 1.0f, 0.5f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + + Transform3D t; + + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.5); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + objRoot.addChild(bg); + + // Create the TransformGroup node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at run time. Add it to + // the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(objTrans); + + // Create a Sphere object, generate one copy of the sphere, + // and add it into the scene graph. + sApp = new ShaderAppearance(); + sApp.setCapability(ShaderAppearance.ALLOW_SHADER_PROGRAM_WRITE); + Material m = new Material(objColor, eColor, objColor, sColor, 100.0f); + sApp.setMaterial(m); + + // Create Gouraud and Phong shader programs + String vertexProgram = null; + String fragmentProgram = null; + Shader[] shaders = new Shader[2]; + String[] attrNames = { "numLights" }; + + try { + vertexProgram = StringIO.readFully("./gouraud.vert"); + fragmentProgram = StringIO.readFully("./gouraud.frag"); + } + catch (IOException e) { + throw new RuntimeException(e); + } + shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_VERTEX, + vertexProgram); + shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_FRAGMENT, + fragmentProgram); + gouraudSP = new GLSLShaderProgram(); + gouraudSP.setShaders(shaders); + + try { + vertexProgram = StringIO.readFully("./phong.vert"); + fragmentProgram = StringIO.readFully("./phong.frag"); + } + catch (IOException e) { + throw new RuntimeException(e); + } + shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_VERTEX, + vertexProgram); + shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_FRAGMENT, + fragmentProgram); + phongSP = new GLSLShaderProgram(); + phongSP.setShaders(shaders); + + if (gouraudButton.isSelected()) { + sApp.setShaderProgram(gouraudSP); + } else if (phongButton.isSelected()) { + sApp.setShaderProgram(phongSP); + } + Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS, 30, sApp); + objTrans.addChild(sph); + + // Create a new Behavior object that will perform the + // desired operation on the specified transform and add + // it into the scene graph. + Transform3D yAxis = new Transform3D(); + yAxis.rotZ(Math.PI); + Alpha rotationAlpha = new Alpha(-1, 10000); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objRoot.addChild(rotator); + + // Create the transform group node for the each light and initialize + // it to the identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add them to the root + // of the subgraph. + TransformGroup l1RotTrans = new TransformGroup(); + l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(l1RotTrans); + + TransformGroup l2RotTrans = new TransformGroup(); + l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(l2RotTrans); + + // Create transformations for the positional lights + t = new Transform3D(); + Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0); + t.set(lPos1); + TransformGroup l1Trans = new TransformGroup(t); + l1RotTrans.addChild(l1Trans); + +// t = new Transform3D(); +// Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0); +// t.set(lPos2); +// TransformGroup l2Trans = new TransformGroup(t); +// l2RotTrans.addChild(l2Trans); + + // Create Geometry for point lights + ColoringAttributes caL1 = new ColoringAttributes(); +// ColoringAttributes caL2 = new ColoringAttributes(); + caL1.setColor(lColor1); +// caL2.setColor(lColor2); + Appearance appL1 = new Appearance(); +// Appearance appL2 = new Appearance(); + appL1.setColoringAttributes(caL1); +// appL2.setColoringAttributes(caL2); + l1Trans.addChild(new Sphere(0.05f, appL1)); +// l2Trans.addChild(new Sphere(0.05f, appL2)); + + // Create lights + AmbientLight aLgt = new AmbientLight(alColor); + + Light lgt1 = null; +// Light lgt2 = null; + + Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f); + Point3f atten = new Point3f(1.0f, 0.0f, 0.0f); + Vector3f lDirect1 = new Vector3f(lPos1); +// Vector3f lDirect2 = new Vector3f(lPos2); + lDirect1.negate(); +// lDirect2.negate(); + + switch (lightType) { + case DIRECTIONAL_LIGHT: + lgt1 = new DirectionalLight(lColor1, lDirect1); +// lgt2 = new DirectionalLight(lColor2, lDirect2); + break; + case POINT_LIGHT: + assert false : "can't get here"; + lgt1 = new PointLight(lColor1, lPoint, atten); +// lgt2 = new PointLight(lColor2, lPoint, atten); + break; + case SPOT_LIGHT: + assert false : "can't get here"; + lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1, + 25.0f * (float)Math.PI / 180.0f, 10.0f); +// lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2, +// 25.0f * (float)Math.PI / 180.0f, 10.0f); + break; + } + + // Set the influencing bounds + aLgt.setInfluencingBounds(bounds); + lgt1.setInfluencingBounds(bounds); +// lgt2.setInfluencingBounds(bounds); + + // Add the lights into the scene graph + objScale.addChild(aLgt); + l1Trans.addChild(lgt1); +// l2Trans.addChild(lgt2); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + yAxis = new Transform3D(); + Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator1 = + new RotationInterpolator(rotor1Alpha, + l1RotTrans, + yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator1.setSchedulingBounds(bounds); + l1RotTrans.addChild(rotator1); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Alpha rotor2Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 1000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator2 = + new RotationInterpolator(rotor2Alpha, + l2RotTrans, + yAxis, + 0.0f, 0.0f); + bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator2.setSchedulingBounds(bounds); + l2RotTrans.addChild(rotator2); + + return objRoot; + } + + private Canvas3D initScene() { + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + BranchGroup scene = createSceneGraph(); + u.addBranchGraph(scene); + + return c; + } + + /** + * Creates new form PhongShadingGLSL + */ + public PhongShadingGLSL() { + // Initialize the GUI components + initComponents(); + + // Create the scene and add the Canvas3D to the drawing panel + Canvas3D c = initScene(); + drawingPanel.add(c, java.awt.BorderLayout.CENTER); + } + + // ---------------------------------------------------------------- + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //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(); + }// //GEN-END:initComponents + + private void phongButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_phongButtonActionPerformed + sApp.setShaderProgram(phongSP); + }//GEN-LAST:event_phongButtonActionPerformed + + private void gouraudButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gouraudButtonActionPerformed + sApp.setShaderProgram(gouraudSP); + }//GEN-LAST:event_gouraudButtonActionPerformed + + private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed + System.exit(0); + }//GEN-LAST:event_exitMenuItemActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new PhongShadingGLSL().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel drawingPanel; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JMenu fileMenu; + private javax.swing.JRadioButton gouraudButton; + private javax.swing.JPanel guiPanel; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JPanel jPanel1; + private javax.swing.JRadioButton phongButton; + private javax.swing.ButtonGroup shaderButtonGroup; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form new file mode 100644 index 0000000..714273d --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.form @@ -0,0 +1,266 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java new file mode 100644 index 0000000..ba4e0f6 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/ShaderTestGLSL.java @@ -0,0 +1,668 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.glsl_shader; + +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.shader.StringIO; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.GraphicsConfiguration; +import java.io.IOException; + +public class ShaderTestGLSL extends javax.swing.JFrame { + + static final int GOLD = 1; + static final int SILVER = 2; + + static final int DIMPLE_SHADER = 1; + static final int BRICK_SHADER = 2; + static final int WOOD_SHADER = 3; + static final int POLKADOT3D_SHADER = 4; + + static final String[] shaderAttrNames1 = { + "Density", "Size", "LightPosition", "Color" + }; + + static final String[] shaderAttrNames2 = { + "BrickColor", "LightPosition" + }; + + private SimpleUniverse u = null; + private View view; + private BranchGroup transpObj; + private BranchGroup scene = null; + private int shaderSelected = DIMPLE_SHADER; + private float density = 16.0f; + private int color = GOLD; + + private Color3f eColor = new Color3f(0.2f, 0.2f, 0.2f); + private Color3f sColor = new Color3f(0.8f, 0.8f, 0.8f); + private Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f); + private Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + private Color3f gold = new Color3f(0.7f, 0.6f, 0.18f); + private Color3f silver = new Color3f(0.75f, 0.75f, 0.75f); + + // Handlers for doing update + private ShaderAppearance sApp1 = null; + private ShaderAppearance sApp2 = null; + private ShaderAppearance sApp3 = null; + private ShaderAppearance sApp4 = null; + private ShaderProgram sp1 = null; + private ShaderProgram sp2 = null; + private ShaderProgram sp3 = null; + private ShaderProgram sp4 = null; + private ShaderAttributeSet sas1 = null; + private ShaderAttributeSet sas2 = null; + private ShaderAttributeObject sao1 = null; + private ShaderAttributeObject sao2 = null; + private Sphere sphere = null; + private Shape3D s3d = null; + + private Material createMaterial() { + Material m; + m = new Material(objColor, eColor, objColor, sColor, 100.0f); + m.setLightingEnable(true); + return m; + } + + private ShaderProgram createGLSLShaderProgram(int index) { + String vertexProgram = null; + String fragmentProgram = null; + try { + switch (index) { + case DIMPLE_SHADER: + vertexProgram = StringIO.readFully("./dimple.vert"); + fragmentProgram = StringIO.readFully("./dimple.frag"); + break; + case BRICK_SHADER: + vertexProgram = StringIO.readFully("./aabrick.vert"); + fragmentProgram = StringIO.readFully("./aabrick.frag"); + break; + case WOOD_SHADER: + vertexProgram = StringIO.readFully("./wood.vert"); + fragmentProgram = StringIO.readFully("./wood.frag"); + break; + case POLKADOT3D_SHADER: + vertexProgram = StringIO.readFully("./polkadot3d.vert"); + fragmentProgram = StringIO.readFully("./polkadot3d.frag"); + break; + default: + } + } + catch (IOException e) { + throw new RuntimeException(e); + } + Shader[] shaders = new Shader[2]; + shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_VERTEX, + vertexProgram); + shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_FRAGMENT, + fragmentProgram); + ShaderProgram shaderProgram = new GLSLShaderProgram(); + shaderProgram.setShaders(shaders); + return shaderProgram; + } + + private ShaderAttributeSet createShaderAttributeSet(int index) { + ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet(); + ShaderAttributeObject shaderAttribute = null; + + switch (index) { + case DIMPLE_SHADER: + // "Density", "Size", "Scale", "Color", "LightPosition" + shaderAttribute = new ShaderAttributeValue("Size", new Float(0.25)); + shaderAttributeSet.put(shaderAttribute); + shaderAttribute = new ShaderAttributeValue("LightPosition", + new Point3f(0.0f, 0.0f, 0.5f)); + shaderAttributeSet.put(shaderAttribute); + + sao1 = new ShaderAttributeValue("Density", new Float(density)); + sao1.setCapability(ShaderAttributeObject.ALLOW_VALUE_READ); + sao1.setCapability(ShaderAttributeObject.ALLOW_VALUE_WRITE); + shaderAttributeSet.put(sao1); + + if(color == GOLD) { + sao2 = new ShaderAttributeValue("Color", gold); + } + else if (color == SILVER) { + sao2 = new ShaderAttributeValue("Color", silver); + } + sao2.setCapability(ShaderAttributeObject.ALLOW_VALUE_READ); + sao2.setCapability(ShaderAttributeObject.ALLOW_VALUE_WRITE); + shaderAttributeSet.put(sao2); + break; + + case BRICK_SHADER: + // "BrickColor", "LightPosition" + shaderAttribute = new ShaderAttributeValue("BrickColor", + new Color3f(1.0f, 0.3f, 0.2f)); + shaderAttributeSet.put(shaderAttribute); + shaderAttribute = new ShaderAttributeValue("LightPosition", + new Point3f(0.0f, 0.0f, 0.5f)); + shaderAttributeSet.put(shaderAttribute); + break; + default: + assert false; + } + return shaderAttributeSet; + } + + private ShaderAppearance createShaderAppearance() { + ShaderAppearance sApp = new ShaderAppearance(); + sApp.setMaterial(createMaterial()); + return sApp; + } + + + private BranchGroup createSubSceneGraph() { + // Create the sub-root of the branch graph + BranchGroup subRoot = new BranchGroup(); + + // + // Create 1 spheres with a GLSLShader and add it into the scene graph. + // + sApp1 = createShaderAppearance(); + sApp1.setCapability(ShaderAppearance.ALLOW_SHADER_PROGRAM_READ); + sApp1.setCapability(ShaderAppearance.ALLOW_SHADER_PROGRAM_WRITE); + sApp1.setCapability(ShaderAppearance.ALLOW_SHADER_ATTRIBUTE_SET_READ); + sApp1.setCapability(ShaderAppearance.ALLOW_SHADER_ATTRIBUTE_SET_WRITE); + + sp1 = createGLSLShaderProgram(1); + sp1.setShaderAttrNames(shaderAttrNames1); + sas1 = createShaderAttributeSet(1); + sas1.setCapability(ShaderAttributeSet.ALLOW_ATTRIBUTES_READ); + sas1.setCapability(ShaderAttributeSet.ALLOW_ATTRIBUTES_WRITE); + sApp1.setShaderProgram(sp1); + sApp1.setShaderAttributeSet(sas1); + + // Setup Brick shader + sp2 = createGLSLShaderProgram(2); + sp2.setShaderAttrNames(shaderAttrNames2); + sas2 = createShaderAttributeSet(2); + sApp2 = createShaderAppearance(); + sApp2.setShaderProgram(sp2); + sApp2.setShaderAttributeSet(sas2); + + // Setup Wood shader + sp3 = createGLSLShaderProgram(3); + sApp3 = createShaderAppearance(); + sApp3.setShaderProgram(sp3); + + // Setup Polkadot3d shader + sp4 = createGLSLShaderProgram(4); + sApp4 = createShaderAppearance(); + sApp4.setShaderProgram(sp4); + + sphere = new Sphere(1.5f, Sphere.GENERATE_NORMALS, 200, null); + s3d = (Shape3D)sphere.getShape(); + s3d.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + s3d.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + s3d.setAppearance(sApp1); + + TransformGroup objTG; + Transform3D t = new Transform3D(); + t.set(new Vector3d(0.0, 0.0, 0.0)); + objTG = new TransformGroup(t); + objTG.addChild(sphere); + subRoot.addChild(objTG); + + return subRoot; + } + + private BranchGroup createSceneGraph(int selectedScene) { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + objRoot.setCapability(BranchGroup.ALLOW_DETACH); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + objScale.addChild(bg); + + objScale.addChild(createSubSceneGraph()); + + // Create a position interpolator and attach it to the view + // platform + TransformGroup vpTrans = + u.getViewingPlatform().getViewPlatformTransform(); + Transform3D axisOfTranslation = new Transform3D(); + Alpha transAlpha = new Alpha(-1, + Alpha.INCREASING_ENABLE | + Alpha.DECREASING_ENABLE, + 0, 0, + 5000, 0, 0, + 5000, 0, 0); + axisOfTranslation.rotY(-Math.PI/2.0); + PositionInterpolator translator = + new PositionInterpolator(transAlpha, + vpTrans, + axisOfTranslation, + 2.0f, 3.5f); + translator.setSchedulingBounds(bounds); + objScale.addChild(translator); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + private Canvas3D initScene() { + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + + u = new SimpleUniverse(c); + + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + view = u.getViewer().getView(); + + return c; + } + + /** + * Creates new form ShaderTestGLSL + */ + public ShaderTestGLSL() { + // Initialize the GUI components + initComponents(); + + // Create the scene and add the Canvas3D to the drawing panel + Canvas3D c = initScene(); + drawingPanel.add(c, java.awt.BorderLayout.CENTER); + } + + + // ---------------------------------------------------------------- + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //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(); + } + // //GEN-END:initComponents + + private void silverButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_silverButtonActionPerformed + color = SILVER; + if(scene != null) { + sao2.setValue(silver); + } + }//GEN-LAST:event_silverButtonActionPerformed + + private void goldButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goldButtonActionPerformed + color = GOLD; + if(scene != null) { + sao2.setValue(gold); + } + }//GEN-LAST:event_goldButtonActionPerformed + + private void replaceSPButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_replaceSPButtonActionPerformed + if (shaderSelected != DIMPLE_SHADER) { + goldButton.setEnabled(false); + silverButton.setEnabled(false); + zeroButton.setEnabled(false); + halfButton.setEnabled(false); + fullButton.setEnabled(false); + } + + switch(shaderSelected) { + case DIMPLE_SHADER: + s3d.setAppearance(sApp1); + goldButton.setEnabled(true); + silverButton.setEnabled(true); + zeroButton.setEnabled(true); + halfButton.setEnabled(true); + fullButton.setEnabled(true); + shaderSelected = BRICK_SHADER; + break; + case BRICK_SHADER: + s3d.setAppearance(sApp2); + shaderSelected = WOOD_SHADER; + break; + case WOOD_SHADER: + s3d.setAppearance(sApp3); + shaderSelected = POLKADOT3D_SHADER; + break; + case POLKADOT3D_SHADER: + s3d.setAppearance(sApp4); + shaderSelected = DIMPLE_SHADER; + break; + default: + assert false; + } + + }//GEN-LAST:event_replaceSPButtonActionPerformed + + private void fullButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fullButtonActionPerformed + density = 16.0f; + if (scene != null) { + sao1.setValue(new Float(density)); + } + }//GEN-LAST:event_fullButtonActionPerformed + + private void DetachButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DetachButtonActionPerformed + if (scene != null) { + scene.detach(); + scene = null; + replaceSPButton.setEnabled(false); + goldButton.setEnabled(true); + silverButton.setEnabled(true); + zeroButton.setEnabled(true); + halfButton.setEnabled(true); + fullButton.setEnabled(true); + shaderSelected = DIMPLE_SHADER; + } + }//GEN-LAST:event_DetachButtonActionPerformed + + private void AttachButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AttachButtonActionPerformed + if (scene == null) { + scene = createSceneGraph(1); + u.addBranchGraph(scene); + replaceSPButton.setEnabled(true); + shaderSelected = BRICK_SHADER; + } + }//GEN-LAST:event_AttachButtonActionPerformed + + private void halfButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_halfButtonActionPerformed + density = 8.0f; + if(scene != null) { + sao1.setValue(new Float(density)); + } + }//GEN-LAST:event_halfButtonActionPerformed + + private void zeroButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zeroButtonActionPerformed + density = 0.0f; + if(scene != null) { + sao1.setValue(new Float(density)); + } + + }//GEN-LAST:event_zeroButtonActionPerformed + + private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed + System.exit(0); + }//GEN-LAST:event_exitMenuItemActionPerformed + + /** Exit the Application */ + private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm + System.exit(0); + }//GEN-LAST:event_exitForm + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + new ShaderTestGLSL().setVisible(true); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JToggleButton AttachButton; + private javax.swing.JToggleButton DetachButton; + private javax.swing.ButtonGroup colorButtonGroup; + private javax.swing.JPanel colorPanel; + private javax.swing.ButtonGroup densityButtonGroup; + private javax.swing.JPanel densityPanel; + private javax.swing.JPanel drawingPanel; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JMenu fileMenu; + private javax.swing.JRadioButton fullButton; + private javax.swing.JRadioButton goldButton; + private javax.swing.JPanel guiPanel; + private javax.swing.JRadioButton halfButton; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JPanel mainPanel; + private javax.swing.JButton replaceSPButton; + private javax.swing.ButtonGroup sceneGraphButtonGroup; + private javax.swing.JPanel sceneGraphPanel; + private javax.swing.JRadioButton silverButton; + private javax.swing.JRadioButton zeroButton; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java b/src/classes/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java new file mode 100644 index 0000000..0865f93 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/SphereGLSL.java @@ -0,0 +1,341 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.glsl_shader; + +import java.applet.Applet; +import java.awt.*; +import java.io.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.shader.StringIO; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; +import java.net.URL; +import java.net.MalformedURLException; + +/** + * Simple GLSL Shader test program + */ +public class SphereGLSL extends Applet { + + // Constants for type of light to use + private static final int DIRECTIONAL_LIGHT = 0; + private static final int POINT_LIGHT = 1; + private static final int SPOT_LIGHT = 2; + + // Flag indicates type of lights: directional, point, or spot + // lights. This flag is set based on command line argument + private static int lightType = DIRECTIONAL_LIGHT; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph(SimpleUniverse u) { + Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f); + Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f); + Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f); + Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f); + Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + + Transform3D t; + + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + objScale.addChild(bg); + + // Create a Sphere object, generate one copy of the sphere, + // and add it into the scene graph. + ShaderAppearance a = new ShaderAppearance(); + Material m = new Material(objColor, eColor, objColor, sColor, 100.0f); + m.setLightingEnable(true); + String vertexProgram = null; + String fragmentProgram = null; + try { + vertexProgram = StringIO.readFully("./simple.vert"); + fragmentProgram = StringIO.readFully("./simple.frag"); + } + catch (IOException e) { + throw new RuntimeException(e); + } + Shader[] shaders = new Shader[2]; + shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_VERTEX, + vertexProgram); + shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, + Shader.SHADER_TYPE_FRAGMENT, + fragmentProgram); + ShaderProgram shaderProgram = new GLSLShaderProgram(); + shaderProgram.setShaders(shaders); + + a.setShaderProgram(shaderProgram); + a.setMaterial(m); + Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS, 200, a); + objScale.addChild(sph); + + // Create the transform group node for the each light and initialize + // it to the identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add them to the root + // of the subgraph. + TransformGroup l1RotTrans = new TransformGroup(); + l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(l1RotTrans); + + TransformGroup l2RotTrans = new TransformGroup(); + l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(l2RotTrans); + + // Create transformations for the positional lights + t = new Transform3D(); + Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0); + t.set(lPos1); + TransformGroup l1Trans = new TransformGroup(t); + l1RotTrans.addChild(l1Trans); + + t = new Transform3D(); + Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0); + t.set(lPos2); + TransformGroup l2Trans = new TransformGroup(t); + l2RotTrans.addChild(l2Trans); + + // Create Geometry for point lights + ColoringAttributes caL1 = new ColoringAttributes(); + ColoringAttributes caL2 = new ColoringAttributes(); + caL1.setColor(lColor1); + caL2.setColor(lColor2); + Appearance appL1 = new Appearance(); + Appearance appL2 = new Appearance(); + appL1.setColoringAttributes(caL1); + appL2.setColoringAttributes(caL2); + l1Trans.addChild(new Sphere(0.05f, appL1)); + l2Trans.addChild(new Sphere(0.05f, appL2)); + + // Create lights + AmbientLight aLgt = new AmbientLight(alColor); + + Light lgt1 = null; + Light lgt2 = null; + + Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f); + Point3f atten = new Point3f(1.0f, 0.0f, 0.0f); + Vector3f lDirect1 = new Vector3f(lPos1); + Vector3f lDirect2 = new Vector3f(lPos2); + lDirect1.negate(); + lDirect2.negate(); + + switch (lightType) { + case DIRECTIONAL_LIGHT: + lgt1 = new DirectionalLight(lColor1, lDirect1); + lgt2 = new DirectionalLight(lColor2, lDirect2); + break; + case POINT_LIGHT: + lgt1 = new PointLight(lColor1, lPoint, atten); + lgt2 = new PointLight(lColor2, lPoint, atten); + break; + case SPOT_LIGHT: + lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1, + 25.0f * (float)Math.PI / 180.0f, 10.0f); + lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2, + 25.0f * (float)Math.PI / 180.0f, 10.0f); + break; + } + + // Set the influencing bounds + aLgt.setInfluencingBounds(bounds); + lgt1.setInfluencingBounds(bounds); + lgt2.setInfluencingBounds(bounds); + + // Add the lights into the scene graph + objScale.addChild(aLgt); + l1Trans.addChild(lgt1); + l2Trans.addChild(lgt2); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator1 = + new RotationInterpolator(rotor1Alpha, + l1RotTrans, + yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator1.setSchedulingBounds(bounds); + l1RotTrans.addChild(rotator1); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Alpha rotor2Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 1000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator2 = + new RotationInterpolator(rotor2Alpha, + l2RotTrans, + yAxis, + 0.0f, 0.0f); + bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator2.setSchedulingBounds(bounds); + l2RotTrans.addChild(rotator2); + + // Create a position interpolator and attach it to the view + // platform + TransformGroup vpTrans = + u.getViewingPlatform().getViewPlatformTransform(); + Transform3D axisOfTranslation = new Transform3D(); + Alpha transAlpha = new Alpha(-1, + Alpha.INCREASING_ENABLE | + Alpha.DECREASING_ENABLE, + 0, 0, + 5000, 0, 0, + 5000, 0, 0); + axisOfTranslation.rotY(-Math.PI/2.0); + PositionInterpolator translator = + new PositionInterpolator(transAlpha, + vpTrans, + axisOfTranslation, + 2.0f, 3.5f); + translator.setSchedulingBounds(bounds); + objScale.addChild(translator); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public SphereGLSL() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + u = new SimpleUniverse(c); + BranchGroup scene = createSceneGraph(u); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + /* + // Limit the frame rate to 100 Hz + u.getViewer().getView().setMinimumFrameCycleTime(10); + */ + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows SphereGLSL to be run as an application + // as well as an applet + // + public static void main(String[] args) { + // Parse the Input Arguments + String usage = "Usage: java SphereGLSL [-point | -spot | -dir]"; + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("-")) { + if (args[i].equals("-point")) { + /* + System.out.println("Using point lights"); + lightType = POINT_LIGHT; + */ + System.out.println("Point lights not yet implemented, option ignored"); + } + else if (args[i].equals("-spot")) { + /* + System.out.println("Using spot lights"); + lightType = SPOT_LIGHT; + */ + System.out.println("Spot lights not yet implemented, option ignored"); + } + else if (args[i].equals("-dir")) { + System.out.println("Using directional lights"); + lightType = DIRECTIONAL_LIGHT; + } + else { + System.out.println(usage); + System.exit(0); + } + } + else { + System.out.println(usage); + System.exit(0); + } + } + + new MainFrame(new SphereGLSL(), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag new file mode 100644 index 0000000..7c9aab8 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.frag @@ -0,0 +1,55 @@ +// +// Fragment shader for antialiased procedural bricks +// +// Authors: Dave Baldwin, Randi Rost +// based on a shader by Darwyn Peachey +// +// Copyright (c) 2002-2004 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +uniform vec3 BrickColor; +//uniform vec3 MortarColor; +//uniform vec2 BrickSize; +//uniform vec2 BrickPct; +//uniform vec2 MortarPct; + +//const vec3 BrickColor = vec3 (1, 0.3, 0.2); +const vec3 MortarColor = vec3 (0.85, 0.86, 0.84); +const vec2 BrickSize = vec2 (0.3, 0.15); +const vec2 BrickPct = vec2 (0.9, 0.85); +const vec2 MortarPct = vec2 (0.1, 0.15); + +varying vec2 MCposition; +varying float LightIntensity; + +#define Integral(x, p, notp) ((floor(x)*(p)) + max(fract(x)-(notp), 0.0)) + +void main(void) +{ + vec2 position, fw, useBrick; + vec3 color; + + // Determine position within the brick pattern + position = MCposition / BrickSize; + + // Adjust every other row by an offset of half a brick + if (fract(position.y * 0.5) > 0.5) + position.x += 0.5; + + // Calculate filter size + //fw = fwidth(position); //fwidth not implemented on WildcatVP + fw = (abs(dFdx(MCposition)) + abs(dFdy(MCposition))) / BrickSize; + + // Perform filtering by integrating the 2D pulse made by the + // brick pattern over the filter width and height + useBrick = (Integral(position + fw, BrickPct, MortarPct) - + Integral(position, BrickPct, MortarPct)) / fw; + + // Determine final color + color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y); + color *= LightIntensity; + + gl_FragColor = vec4 (color, 1.0); +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert new file mode 100644 index 0000000..226dbe4 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/aabrick.vert @@ -0,0 +1,42 @@ +// +// Vertex shader for antialiased procedural bricks +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +// based on a shader by Darwyn Peachey +// +// Copyright (c) 2002-2004 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +uniform vec3 LightPosition; +//const vec3 LightPosition = vec3 (0, 4, 4); + +const float SpecularContribution = 0.3; +const float DiffuseContribution = 1.0 - SpecularContribution; + +varying float LightIntensity; +varying vec2 MCposition; + +void main(void) +{ + vec3 ecPosition = vec3 (gl_ModelViewMatrix * gl_Vertex); + vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal); + vec3 lightVec = normalize(LightPosition - ecPosition); + vec3 reflectVec = reflect(-lightVec, tnorm); + vec3 viewVec = normalize(-ecPosition); + float diffuse = max(dot(lightVec, tnorm), 0.0); + float spec = 0.0; + + if (diffuse > 0.0) + { + spec = max(dot(reflectVec, viewVec), 0.0); + spec = pow(spec, 16.0); + } + + LightIntensity = DiffuseContribution * diffuse + + SpecularContribution * spec; + + MCposition = gl_Vertex.xy; + gl_Position = ftransform(); +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.frag new file mode 100644 index 0000000..282add7 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.frag @@ -0,0 +1,61 @@ + +// +// dimple.frag: Fragment shader for bump mapping dimples (bumps) +// +// author: John Kessenich +// +// Copyright (c) 2002: 3Dlabs, Inc. +// +// +varying vec3 LightDir; +varying vec3 EyeDir; +varying vec3 Normal; + +//const vec3 Color = vec3(0.7, 0.6, 0.18); + +//const float Density = 16.0; +//const float Size = 0.25; + +uniform vec3 Color; +uniform float Density; +uniform float Size; +// uniform float SpecularFactor; + +//float Density = 27.6; +//float Size = 0.13025; + + +//uniform float Scale; + +const float SpecularFactor = 0.4; + +void main (void) +{ + vec3 litColor; + + vec2 c = Density * (gl_TexCoord[0].xy); + vec2 p = fract(c) - vec2(0.5); + float d = (p.x * p.x) + (p.y * p.y); + if (d >= Size) + p = vec2(0.0); + + vec3 normDelta = vec3(-p.x, -p.y, 1.0); + + litColor = Color * max(0.0, dot(normDelta, LightDir)); + + float t = 2.0 * dot(LightDir, normDelta); + vec3 reflectDir = t * normDelta; + reflectDir = LightDir - reflectDir; + +// vec3 reflectDir = LightDir - 2.0 * dot(LightDir, normDelta) * normDelta; + + float spec = max(dot(EyeDir, reflectDir), 0.0); + spec = spec * spec; + spec = spec * spec; + spec *= SpecularFactor; + + litColor = min(litColor + spec, vec3(1.0)); + gl_FragColor = vec4(litColor, gl_Color.a); +// gl_FragColor = vec4(litColor, 1.0); +// gl_FragColor = vec4(Scale); +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.vert new file mode 100644 index 0000000..e45796b --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/dimple.vert @@ -0,0 +1,42 @@ + +// +// dimple.vert: Vertex shader for bump mapping dimples (bumps) +// +// author: John Kessenich +// +// Copyright (c) 2002: 3Dlabs, Inc. +// + +varying vec3 LightDir; +varying vec3 EyeDir; +varying vec3 Normal; + +uniform vec3 LightPosition; +// uniform float Scale; +// vec3 LightPosition = vec3(0.0, 0.0, 5.0); +float Scale = 1.0; + +void main(void) +{ + vec4 pos = gl_ModelViewMatrix * gl_Vertex; + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + vec3 eyeDir = vec3(pos); +// gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[0] = gl_Vertex; + gl_FrontColor = gl_Color; + + vec3 n = normalize(gl_NormalMatrix * gl_Normal); + vec3 t = normalize(cross(vec3(1.141, 2.78, 3.14), n)); + vec3 b = cross(n, t); + + vec3 v; + v.x = dot(LightPosition, t); + v.y = dot(LightPosition, b); + v.z = dot(LightPosition, n); + LightDir = normalize(v); + + v.x = dot(eyeDir, t); + v.y = dot(eyeDir, b); + v.z = dot(eyeDir, n); + EyeDir = normalize(v); +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag new file mode 100644 index 0000000..951ee8e --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.frag @@ -0,0 +1,50 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +// Simple GLSL fragment program to add the primary and secondary (specular) colors + +void main() +{ + gl_FragColor = gl_Color + gl_SecondaryColor; +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert new file mode 100644 index 0000000..fd49c18 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/gouraud.vert @@ -0,0 +1,100 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +// A GLSL vertex program for handling 1 directional light with specular. +// This implements per-vertex lighting (Gouraud shading). + +void directionalLight0( + in vec3 normal, + inout vec4 ambient, + inout vec4 diffuse, + inout vec4 specular) +{ + // Normalized light direction and half vector + vec3 lightDirection = normalize(vec3(gl_LightSource[0].position)); + vec3 halfVector = normalize(vec3(gl_LightSource[0].halfVector)); + + float nDotVP; // normal . light_direction + float nDotHV; // normal . light_half_vector + float pf; // power factor + + nDotVP = max(0.0, dot(normal, lightDirection)); + nDotHV = max(0.0, dot(normal, halfVector)); + + if (nDotVP == 0.0) { + pf = 0.0; + } + else { + pf = pow(nDotHV, gl_FrontMaterial.shininess); + } + + ambient += gl_LightSource[0].ambient; + diffuse += gl_LightSource[0].diffuse * nDotVP; + specular += gl_LightSource[0].specular * pf; +} + + +void main() +{ + vec3 tnorm = normalize(vec3(gl_NormalMatrix * gl_Normal)); + vec4 amb = vec4(0.0); + vec4 diff = vec4(0.0); + vec4 spec = vec4(0.0); + int i; + + // Transform the vertex + vec4 outPosition = gl_ModelViewProjectionMatrix * gl_Vertex; + + directionalLight0(tnorm, amb, diff, spec); + + // Apply the result of the lighting equation + vec4 outSecondaryColor = vec4(vec3(spec * gl_FrontMaterial.specular), 1.0); + vec4 outColor = vec4(vec3(gl_FrontLightModelProduct.sceneColor + + amb * gl_FrontMaterial.ambient + + diff * gl_FrontMaterial.diffuse), 1.0); + + gl_FrontColor = outColor; + gl_FrontSecondaryColor = outSecondaryColor; + gl_Position = outPosition; +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.frag new file mode 100644 index 0000000..41de179 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.frag @@ -0,0 +1,98 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +// A GLSL fragment program for handling 1 directional light with specular. +// This implements per-pixel lighting (Phong shading) + +void directionalLight0( + in vec3 normal, + inout vec4 ambient, + inout vec4 diffuse, + inout vec4 specular) +{ + // Normalized light direction and half vector + vec3 lightDirection = normalize(vec3(gl_LightSource[0].position)); + vec3 halfVector = normalize(vec3(gl_LightSource[0].halfVector)); + + float nDotVP; // normal . light_direction + float nDotHV; // normal . light_half_vector + float pf; // power factor + + nDotVP = max(0.0, dot(normal, lightDirection)); + nDotHV = max(0.0, dot(normal, halfVector)); + + if (nDotVP == 0.0) { + pf = 0.0; + } + else { + pf = pow(nDotHV, gl_FrontMaterial.shininess); + } + + ambient += gl_LightSource[0].ambient; + diffuse += gl_LightSource[0].diffuse * nDotVP; + specular += gl_LightSource[0].specular * pf; +} + + +// Per-pixel normal (input from vertex shader) +varying vec3 Normal; + +void main() +{ + vec3 unitNorm = normalize(Normal); + vec4 amb = vec4(0.0); + vec4 diff = vec4(0.0); + vec4 spec = vec4(0.0); + int i; + + directionalLight0(unitNorm, amb, diff, spec); + + // Apply the result of the lighting equation + vec4 secondaryColor = vec4(vec3(spec * gl_FrontMaterial.specular), 1.0); + vec4 color = vec4(vec3(gl_FrontLightModelProduct.sceneColor + + amb * gl_FrontMaterial.ambient + + diff * gl_FrontMaterial.diffuse), 1.0); + + gl_FragColor = color + secondaryColor; +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.vert new file mode 100644 index 0000000..9a67c8b --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/phong.vert @@ -0,0 +1,56 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +// A GLSL vertex program for doing Phone shading (per-fragment lighting) + +// Per-pixel normal (output to fragment shader) +varying vec3 Normal; + +void main() +{ + Normal = normalize(vec3(gl_NormalMatrix * gl_Normal)); + + // Transform the vertex + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag new file mode 100644 index 0000000..b341454 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.frag @@ -0,0 +1,48 @@ +// +// Fragment shader for 3 dimensional polka dot shader. +// +// Author: Joshua Doss +// +// Copyright (C) 2002-2004 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// +varying float LightIntensity; +varying vec3 MCPosition; + +//Create uniform variables so dots can be spaced and scaled by user +//uniform vec3 Spacing; +//uniform float DotSize; +const vec3 Spacing = vec3 (0.314, 0.36, 0.261); +const float DotSize = 0.123; + +//Create colors as uniform variables so they can be easily changed +//uniform vec3 ModelColor, PolkaDotColor; +const vec3 ModelColor = vec3 (0.75, 0.2, 0.1); +const vec3 PolkaDotColor = vec3 (1, 1, 1); + +void main(void) +{ + float insidesphere, sphereradius, scaledpointlength; + vec3 scaledpoint, finalcolor; + + // Scale the coordinate system + // The following line of code is not yet implemented in current drivers: + // mcpos = mod(Spacing, MCposition); + // We will use a workaround found below for now + scaledpoint = MCPosition - (Spacing * floor(MCPosition/Spacing)); + + // Bring the scaledpoint vector into the center of the scaled coordinate system + scaledpoint = scaledpoint - Spacing/2.0; + + // Find the length of the scaledpoint vector and compare it to the dotsize + scaledpointlength = length(scaledpoint); + insidesphere = step(scaledpointlength,DotSize); + + // Determine final output color before lighting + finalcolor = vec3(mix(ModelColor, PolkaDotColor, insidesphere)); + + // Output final color and factor in lighting + gl_FragColor = clamp((vec4( finalcolor, 1.0 ) * LightIntensity), vec4(0.0), vec4(1.0)); +} + diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert new file mode 100644 index 0000000..86f432f --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/polkadot3d.vert @@ -0,0 +1,58 @@ +// This is the Vertex Shader for three dimensional polka dots. +// +// author(s): Joshua Doss +// +// Copyright (C) 2002-2004 3Dlabs Inc. Ltd. + +//Create uniform variables for lighting to allow user interaction +//uniform float SpecularContribution; +//uniform vec3 LightPosition; + +const float SpecularContribution = 0.36; +const vec3 LightPosition = vec3 (0, 4, 5); + +varying vec3 MCPosition; +varying float LightIntensity; + +void main(void) +{ + float diffusecontribution = 1.0 - SpecularContribution; + + // compute the vertex position in eye coordinates + vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex); + + // compute the transformed normal + vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal); + + // compute a vector from the model to the light position + vec3 lightVec = normalize(LightPosition - ecPosition); + + // compute the reflection vector + vec3 reflectVec = reflect(-lightVec, tnorm); + + // compute a unit vector in direction of viewing position + vec3 viewVec = normalize(-ecPosition); + + // calculate amount of diffuse light based on normal and light angle + float diffuse = max(dot(lightVec, tnorm), 0.0); + float spec = 0.0; + + // if there is diffuse lighting, calculate specular + if(diffuse > 0.0) + { + spec = max(dot(reflectVec, viewVec), 0.0); + spec = pow(spec, 16.0); + } + + // add up the light sources, since this is a varying (global) it will pass to frag shader + LightIntensity = diffusecontribution * diffuse * 1.5 + + SpecularContribution * spec; + + // the varying variable MCPosition will be used by the fragment shader to determine where + // in model space the current pixel is + MCPosition = vec3 (gl_Vertex); + + // send vertex information + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} + diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.frag new file mode 100644 index 0000000..6542b34 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.frag @@ -0,0 +1,62 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +// Simple GLSL fragment program to attenuate the input fragment color as a +// function of the distance of the fragment position from the center +// of the window + +const float windowSize = 700.0; // TODO: this should be a built-in parameter! + +void main() +{ + // Compute distance from center in range [0.0, 1.0] + vec2 dist = min(abs((gl_FragCoord.xy - (windowSize)/2.0) / windowSize), 1.0); + vec2 invDist = 1.0 - dist; + + // Compute attenuation + float atten = invDist.x * invDist.y; + vec4 outcolor = (gl_Color + gl_SecondaryColor) * atten; + + gl_FragColor = outcolor; +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.vert new file mode 100644 index 0000000..7d3e152 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/simple.vert @@ -0,0 +1,129 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +// A simple GLSL vertex program for handling 2 directional lights with +// separate specular + +void directionalLight( + in int i, + in vec3 normal, + inout vec4 ambient, + inout vec4 diffuse, + inout vec4 specular) +{ + // Normalized light direction and half vector + // (shouldn't they be pre-normalized?!) + vec3 lightDirection = normalize(vec3(gl_LightSource[i].position)); + vec3 halfVector = normalize(vec3(gl_LightSource[i].halfVector)); + + float nDotVP; // normal . light_direction + float nDotHV; // normal . light_half_vector + float pf; // power factor + + nDotVP = max(0.0, dot(normal, lightDirection)); + nDotHV = max(0.0, dot(normal, halfVector)); + + if (nDotVP == 0.0) { + pf = 0.0; + } + else { + pf = pow(nDotHV, gl_FrontMaterial.shininess); + } + + ambient += gl_LightSource[i].ambient; + diffuse += gl_LightSource[i].diffuse * nDotVP; + specular += gl_LightSource[i].specular * pf; +} + + +const int numEnabledLights = 2; // TODO: this should be a built-in parameter! + +void main() +{ + //vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex; + //vec3 ecPosition3 = ecPosition.xyz / ecPosition.w; + vec3 tnorm = normalize(vec3(gl_NormalMatrix * gl_Normal)); + vec4 amb = vec4(0.0); + vec4 diff = vec4(0.0); + vec4 spec = vec4(0.0); + int i; + + // Transform the vertex + vec4 outPosition = gl_ModelViewProjectionMatrix * gl_Vertex; + + for (i = 0; i < numEnabledLights; i++) { + directionalLight(i, tnorm, amb, diff, spec); + } + + // Apply the result of the lighting equation + vec4 outSecondaryColor = vec4(vec3(spec * gl_FrontMaterial.specular), 1.0); + vec3 color0 = vec3(gl_FrontLightModelProduct.sceneColor + + amb * gl_FrontMaterial.ambient + + diff * gl_FrontMaterial.diffuse); + + // Generate a pseudo-random noise pattern + vec3 xyz = clamp((outPosition.xyz + 1.0) * 0.5, 0.0, 1.0); + + xyz = fract(xyz * 262144.0); + float randSeed = fract(3.0 * xyz.x + 5.0 * xyz.y + 7.0 * xyz.z); + + vec3 altColor; + + randSeed = fract(37.0 * randSeed); + altColor.x = randSeed * 0.5 + 0.5; + randSeed = fract(37.0 * randSeed); + altColor.y = randSeed * 0.5 + 0.5; + randSeed = fract(37.0 * randSeed); + altColor.z = randSeed * 0.5 + 0.5; + randSeed = fract(37.0 * randSeed); + float altAlpha = randSeed * 0.5; + + // Apply noise and output final vertex color + vec4 outColor; + outColor = vec4(mix(color0, altColor, altAlpha), 1.0); + + gl_FrontColor = outColor; + gl_FrontSecondaryColor = outSecondaryColor; + gl_Position = outPosition; +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.frag new file mode 100644 index 0000000..fa50453 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.frag @@ -0,0 +1,34 @@ +// +// Fragment shader for cartoon-style shading +// +// Author: Philip Rideout +// +// Copyright (c) 2004 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +//uniform vec3 DiffuseColor; +//uniform vec3 PhongColor; +//uniform float Edge; +//uniform float Phong; + +vec3 DiffuseColor = vec3(0.5,0.5,1.0); +vec3 PhongColor = vec3(0.75,0.75,1.0); +float Edge = 0.64; +float Phong = 0.90; + +varying vec3 Normal; +varying vec3 LightDir; + +void main (void) +{ + vec3 color = DiffuseColor; + float f = max( 0.0, dot(LightDir,Normal)); + if (abs(f) < Edge) + color = DiffuseColor * 0.2; + if (f > Phong) + color = PhongColor; + + gl_FragColor = vec4(color, 1); +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.vert new file mode 100644 index 0000000..d044af7 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/toon.vert @@ -0,0 +1,19 @@ +// +// Vertex shader for cartoon-style shading +// +// Author: Philip Rideout +// +// Copyright (c) 2004 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +varying vec3 Normal; +varying vec3 LightDir; + +void main(void) +{ + Normal = normalize(gl_NormalMatrix * gl_Normal); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + LightDir = vec3(normalize(gl_LightSource[0].position)); +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.frag b/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.frag new file mode 100644 index 0000000..eecf91f --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.frag @@ -0,0 +1,66 @@ +// +// Simple fragment shader for wood +// +// Author: John Kessenich +// +// Copyright (c) 2002-2004 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +//uniform float GrainSizeRecip; +//uniform vec3 DarkColor; +//uniform vec3 spread; +const float GrainSizeRecip = 1.0; +const vec3 DarkColor = vec3 (0.6, 0.3, 0.1); +const vec3 spread = vec3 (0.15, 0.075, 0.0); + +varying float lightIntensity; +varying vec3 Position; + +void main (void) +{ + // + // cheap noise + // + vec3 location = Position; + vec3 floorvec = vec3(floor(10.0 * Position.x), 0.0, floor(10.0 * Position.z)); + vec3 noise = Position * 10.0 - floorvec - 0.5; + noise *= noise; + location += noise * 0.12; + + // + // distance from axis + // + float dist = location.x * location.x + location.z * location.z; + float grain = dist * GrainSizeRecip; + + // + // grain effects as function of distance + // + float brightness = fract(grain); + if (brightness > 0.5) + brightness = (1.0 - brightness); + vec3 color = DarkColor + brightness * spread; + + brightness = fract(grain * 7.0); + if (brightness > 0.5) + brightness = 1.0 - brightness; + color -= brightness * spread; + + // + // also as a function of lines parallel to the axis + // + brightness = fract(grain * 47.0) * 0.60; + float line = fract(Position.z + Position.x); + float snap = floor(line * 20.0) * (1.0/20.0); + if (line < snap + 0.006) + color -= brightness * spread; + + // + // apply lighting effects from vertex processor + // + color = clamp(color * lightIntensity, 0.0, 1.0); + + gl_FragColor = vec4(color, 1.0); +} diff --git a/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.vert b/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.vert new file mode 100644 index 0000000..84651aa --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/glsl_shader/wood.vert @@ -0,0 +1,25 @@ +// +// Simple vertex shader for wood +// +// Author: John Kessenich +// +// Copyright (c) 2002-2004 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +varying float lightIntensity; +varying vec3 Position; +//uniform vec3 LightPosition; +//uniform float Scale; +const vec3 LightPosition = vec3 (0.0,0.0,0.4); +const float Scale = 1.0; + +void main(void) +{ + vec4 pos = gl_ModelViewMatrix * gl_Vertex; + Position = vec3(gl_Vertex) * Scale; + vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal); + lightIntensity = max(dot(normalize(LightPosition - vec3(pos)), tnorm), 0.0) * 1.5; + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} diff --git a/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form b/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form new file mode 100644 index 0000000..48fadea --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.form @@ -0,0 +1,36 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java b/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java new file mode 100644 index 0000000..8fe0f49 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/hello_universe/HelloUniverse.java @@ -0,0 +1,169 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.hello_universe; + +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.geometry.ColorCube; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.GraphicsConfiguration; + +/** + * Simple Java 3D example program to display a spinning cube. + */ +public class HelloUniverse extends javax.swing.JFrame { + + private SimpleUniverse univ = null; + private BranchGroup scene = null; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create the TransformGroup node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at run time. Add it to + // the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple Shape3D node; add it to the scene graph. + objTrans.addChild(new ColorCube(0.4)); + + // Create a new Behavior object that will perform the + // desired operation on the specified transform and add + // it into the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, 4000); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objRoot.addChild(rotator); + + // Have Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + private Canvas3D createUniverse() { + // Get the preferred graphics configuration for the default screen + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + // Create a Canvas3D using the preferred configuration + Canvas3D c = new Canvas3D(config); + + // Create simple universe with view branch + univ = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + univ.getViewingPlatform().setNominalViewingTransform(); + + // Ensure at least 5 msec per frame (i.e., < 200Hz) + univ.getViewer().getView().setMinimumFrameCycleTime(5); + + return c; + } + + /** + * Creates new form HelloUniverse + */ + public HelloUniverse() { + // Initialize the GUI components + initComponents(); + + // Create Canvas3D and SimpleUniverse; add canvas to drawing panel + Canvas3D c = createUniverse(); + drawingPanel.add(c, java.awt.BorderLayout.CENTER); + + // Create the content branch and add it to the universe + scene = createSceneGraph(); + univ.addBranchGraph(scene); + } + + // ---------------------------------------------------------------- + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //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(); + }// //GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new HelloUniverse().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel drawingPanel; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/classes/org/jdesktop/j3d/examples/lightwave/README.txt b/src/classes/org/jdesktop/j3d/examples/lightwave/README.txt new file mode 100644 index 0000000..c37f4d9 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/lightwave/README.txt @@ -0,0 +1,321 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + + Release Notes for the Lightwave 3D Java3D Loader + ------------------------------------------------ + Updated May 13, 1998 + + + +These release notes are intended to document the known working and +non-working features of the loader. This is important because the loader +implements an important subset of Lightwave functionality, but it definitely +skips many major features of Lightwave files. Please read these notes +to make sure that the features you need are actually implemented. Or +if you see differences between Lightwave display of your file and +the Java3D version of that file, take a look at these notes to see +what might not be working properly. + + +Testing the Loader +------------------ +The application in this directory (Viewer) is intended to be a very +basic test application for loading/viewing Lightwave 3D models. To +use the program, type: + java Viewer +where is the name of a valid Lightwave 3D scene file that is +reachable from the current directory. There is a very basic test file +included in this directory called ballcone.lws. To load/view that file, +type: + java Viewer ballcone.lws +Note that Lightwave scene files (*.lws) embed the pathnames to object +files (*.lwo) within them, and that object files have pathnames +to image files (for textures) embedded in them. Whatever those +pathnames are in those files must be valid for the directory in which +you are running the application that loads the scene file. For example, +if I was loading in a scene file that referred to an object file +called "data/object.lwo", then the file "object.lwo" should be located in +a subdirectory of this current directory called "data". + + +Summary of Loader +----------------- +The Lw3d loader was intended to implement a major subset of the features in +Lightwave 3D that would be used for realtime 3D animations. That is, any +features (such as Bones and other high-end rendering +options) which would require significant rendering time were simply +not doable. These more advanced features are intended to be rendered +off-line, saving each frame separately and later compositing them +together into an animation. But Java3D is a realtime 3D rendering +system, so these type of animations just do not map into a Java3D viewer +very well. + +Another category of non-implemented items are those that we simply have not +yet gotten to. There are a few known features of Lightwave files that +would work well through Java3D but just haven't been implemented in the +loader yet. + +Although there are a lot of features that are not yet implemented, +the basics of Lightwave 3D functionality (scene creation, animating +objects/lights/cameras, different surface properties) all work pretty +much as expected. So try it out and let us know non-documented items +that didn't work properly. + + +Details of Non-Implemented Features +----------------------------------- +This list is probably not comprehensive, but hopefully points out most of +the features or areas where the implementation is incomplete (or not +there at all). + + +Limitations of Scene Files (*.lws) +---------------------------------- +1) Bones/Skeleton +Bones functionality is not implemented at all. Unfortunately, this +great feature of Lightwave 3D is not currently implementable in the +loader because the processing time that it would take to compute +frames based on Bones data would be far more than a real-time rendering +system can afford. + +The loader may, at some future point, provide a mechanism to read +in frames of geometry that were saved from Lightwave Bones descriptions. +That is, there are plug-ins available for Lightwave 3D that allow you +to save out files with Bones information as a series of files with +pre-calculated geometry for each frame; eventually we would like the +Lightwave 3D loader to support those files. + +Workaround: None; the best and only workaround is to find a different +method of animating your objects. + + +2) Spline paths +Spline paths will be interpreted as linear piecewise paths instead, +traveling between each control point specified for the spline. + +Workaround: Specify linear paths. If your path looks too hard-jointed +through the loader, specify more keyframes for the path to smooth it out. + + +3) Object Scaling +Scaling objects in the scene (versus the object files) is currently +ignored. + +Workaround: scale the objects in their individual object files. + + +4) Shadows +Shadows options are ignored in the loader. + +Workaround: None. + + +5) Envelopes +Most envelopes are ignored. There are a couple of exceptions to this, +such as light intensity envelopes, but even those features have not been +completely implemented and tested. + +Workaround: None. + + +6) Camera effects +All advanced-rendering camera effects are ignored in the loader. This +includes the following items in Lightwave 3D files: + - Lens Flare + - F-stop + - Focal Distance + - Blur Length + - Dissolves + - Glow + - Zoom + - Intensity Falloff + - Antialiasing + +Workaround: None. + + +7) Inverse Kinematics +IK options such as Goal Objects and Anchors are ignored. + +Workaround: Animate objects directly instead of indirectly via IK. + + +8) Morphs +All morph options are ignored. + +Workaround: None. + + +9) Display properties +Lightwave allows you to specify surface properties for different rendering +modes (e.g., wireframe color). All of these parameters are ignored and +the full properties of any item are used at all times. + +Workaround: None. + + +10) Various Surface Properties +Various minor surface properties are currently ignored, including: + - Polygon size + - Dissolves + - Clip map + - Unaffected by fog + - Edge parameters + +Workaround: None. + + +11) Lights +The following items are currently ignored for Light objects: + - Target objects + - Flare parameters + - Shadow options + +Workaround: None for flares or shadows. For targeting problems, animate the +light directly (versus indirectly through using Target). + + +12) Camera Targeting +The Target option for Camera objects is currently ignored by the loader. + +Workaround: Animate the camera directly (versus indirectly through using +Target). + + +13) Effects +Most effects (from the Effects dialog box in the layout program) are +ignored, save for fog (which should accept all parameters) and +backdrop colors (solid backdrops only - gradient backdrops are +ignored). + +Workaround: None. + + +14) Render Options +Most options from the Render dialog box are ignored - most of these pertain +to saving the animation in any case (something that doesn't happen through +the Loader). + +Workaround: None. + + + +Limitations of Object Files (*.lwo) +----------------------------------- +1) MetaNURBS +Geometry stored in MetaNURBS format will be ignored by the loader. + +Workaround: pre-tessellate your MetaNURBS surfaces and save your +geometry (object) files in that format. + + +2) Layered Object Files +There is currently no support for the "Layered Object File Format" +of Lightwave 3D. + +Workaround: None. + + +3) Reflectivity +There is no way to reproduce the reflective properties of surfaces +through Java3D, so any reflectivity settings in Lightwave object files +will be ignored. + +Workaround: None. + + +4) Refraction +Refractive properties of surfaces are ignored. + +Workaround: None. + + +5) Edge Transparency +Edge transparency properties are ignored. + +Workaround. None. + + +6) Texture types +Texture mapping is currently somewhat limited in the loader. The following +types of texture mapping effects should work: + - Diffuse (the texture modifies the Diffuse aspects of the surface) + - Color (the texture modifies the Color properties of the surface). +Textures that attempt to modify other parameters of the surface will +be ignored. + +Also, the following texture types should work: + - Planar Image Map + - Spherical Image Map + - Cylindrical Image Map +Other kinds of mappings will not work (including Marble, Grid, Dots, etc.) + +Some Texture parameters will not work. The following should work correctly: + - size + - center +Advanced texture parameters such as falloff and velocity will be ignored. + +Summary: There are so many texture mapping parameters in Lightwave 3D that +it's difficult to produce a list of all of the items that won't work +properly. In a nutshell, basic decal-type (color modifying) or brightness +(diffuse modifying) textures that are mapped as planes, spheres, or +cylinders should work correctly. Anything else will probably not work. + +Workaround: Use the basics. + + +7) Plug-ins +There is currently no support for any plug-in capabilities. For example, +if there are plug-in shaders specified for your file, those shaders will be +ignored. + +Workaround: None. + + +8) Image Sequences +There is no support for image sequences - textures must be static files. + +Workaround: None. + + diff --git a/src/classes/org/jdesktop/j3d/examples/lightwave/Viewer.java b/src/classes/org/jdesktop/j3d/examples/lightwave/Viewer.java new file mode 100644 index 0000000..8959d4d --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/lightwave/Viewer.java @@ -0,0 +1,209 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.lightwave; + +import java.applet.Applet; +import java.awt.*; + +import javax.media.j3d.BranchGroup; +import javax.media.j3d.Canvas3D; +import javax.media.j3d.Transform3D; +import javax.media.j3d.TransformGroup; +import javax.media.j3d.View; +import javax.vecmath.Matrix4d; + +import com.sun.j3d.loaders.lw3d.Lw3dLoader; +import com.sun.j3d.loaders.Loader; +import com.sun.j3d.loaders.Scene; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.SimpleUniverse; + + +/** + * This class loads in a Lightwave3D file and displays it in an applet + * window. The application is fairly basic; a more complete version + * of a Lightwave 3D loader might incorporate features such as + * settable clip plane distances and animated views (these are both + * possible with the current Lightwave 3D loader, they just need to + * be implemented in the application). + */ +public class Viewer extends Applet { + + private java.net.URL filename; + private SimpleUniverse u; + + public Viewer(java.net.URL url) { + filename = url; + } + + public Viewer() {} + + public void init() { + if (filename == null) { + // the path to the file for an applet + try { + java.net.URL path = getCodeBase(); + filename = new java.net.URL(path.toString() + + "./ballcone.lws"); + } + catch (java.net.MalformedURLException ex) { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + System.exit(1); + } + } + + // Construct the Lw3d loader and load the file + Loader lw3dLoader = new Lw3dLoader(Loader.LOAD_ALL); + Scene loaderScene = null; + try { + loaderScene = lw3dLoader.load(filename); + } + catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + + // Construct the applet canvas + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a basic universe setup and the root of our scene + u = new SimpleUniverse(c); + BranchGroup sceneRoot = new BranchGroup(); + + // Change the back clip distance; the default is small for + // some lw3d worlds + View theView = u.getViewer().getView(); + theView.setBackClipDistance(50000f); + + // Now add the scene graph defined in the lw3d file + if (loaderScene.getSceneGroup() != null) { + // Instead of using the default view location (which may be + // completely bogus for the particular file you're loading), + // let's use the initial view from the file. We can get + // this by getting the view groups from the scene (there's + // only one for Lightwave 3D), then using the inverse of the + // transform on that view as the transform for the entire scene. + + // First, get the view groups (shouldn't be null unless there + // was something wrong in the load + TransformGroup viewGroups[] = loaderScene.getViewGroups(); + + // Get the Transform3D from the view and invert it + Transform3D t = new Transform3D(); + viewGroups[0].getTransform(t); + Matrix4d m = new Matrix4d(); + t.get(m); + m.invert(); + t.set(m); + + // Now we've got the transform we want. Create an + // appropriate TransformGroup and parent the scene to it. + // Then insert the new group into the main BranchGroup. + TransformGroup sceneTransform = new TransformGroup(t); + sceneTransform.addChild(loaderScene.getSceneGroup()); + sceneRoot.addChild(sceneTransform); + } + + // Make the scene graph live by inserting the root into the universe + u.addBranchGraph(sceneRoot); + } + + + public void destroy() { + u.cleanup(); + } + + /** + * The main method of the application takes one argument in the + * args array; the filname that you want to load. Note that the + * file must be reachable from the directory in which you're running + * this application. + */ + public static void main(String args[]) { + java.net.URL url = null; + java.net.URL pathUrl = null; + if (args.length > 0) { + try { + if ((args[0].indexOf("file:") == 0) || + (args[0].indexOf("http") == 0)) { + url = new java.net.URL(args[0]); + } + else if (args[0].charAt(0) != '/') { + url = new java.net.URL("file:./" + args[0]); + } + else { + url = new java.net.URL("file:" + args[0]); + } + } + catch (java.net.MalformedURLException ex) { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + System.exit(1); + } + } + else { + // the path to the image for an application + try { + url = new java.net.URL("file:./ballcone.lws"); + } + catch (java.net.MalformedURLException ex) { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + System.exit(1); + } + } + new MainFrame(new Viewer(url), 500, 500); + } +} + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/lod/LOD.java b/src/classes/org/jdesktop/j3d/examples/lod/LOD.java new file mode 100644 index 0000000..45381f4 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/lod/LOD.java @@ -0,0 +1,181 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.lod; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.behaviors.vp.*; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class LOD extends Applet { + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + createLights(objRoot); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objRoot.addChild(objTrans); + + // Create a switch to hold the different levels of detail + Switch sw = new Switch(0); + sw.setCapability(javax.media.j3d.Switch.ALLOW_SWITCH_READ); + sw.setCapability(javax.media.j3d.Switch.ALLOW_SWITCH_WRITE); + + + // Create several levels for the switch, with less detailed + // spheres for the ones which will be used when the sphere is + // further away + sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 40)); + sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 20)); + sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 10)); + sw.addChild(new Sphere(0.4f, Sphere.GENERATE_NORMALS, 3)); + + // Add the switch to the main group + objTrans.addChild(sw); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // set up the DistanceLOD behavior + float[] distances = new float[3]; + distances[0] = 5.0f; + distances[1] = 10.0f; + distances[2] = 25.0f; + DistanceLOD lod = new DistanceLOD(distances); + lod.addSwitch(sw); + lod.setSchedulingBounds(bounds); + objTrans.addChild(lod); + + // Have Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + private void createLights(BranchGroup graphRoot) { + + // Create a bounds for the light source influence + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the global, ambient light + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + graphRoot.addChild(aLgt); + + // Set up the directional (infinite) light source + Color3f lColor1 = new Color3f(0.9f, 0.9f, 0.9f); + Vector3f lDir1 = new Vector3f(1.0f, 1.0f, -1.0f); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + graphRoot.addChild(lgt1); + } + + + public LOD() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // only add zoom mouse behavior to viewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + // add orbit behavior to the ViewingPlatform, but disable rotate + // and translate + OrbitBehavior orbit = new OrbitBehavior(c, + OrbitBehavior.REVERSE_ZOOM | + OrbitBehavior.DISABLE_ROTATE | + OrbitBehavior.DISABLE_TRANSLATE); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows LOD to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new LOD(), 512, 512); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java b/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java new file mode 100644 index 0000000..790806c --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest.java @@ -0,0 +1,176 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.model_clip; + +import com.sun.j3d.utils.behaviors.mouse.*; +import com.sun.j3d.utils.geometry.Cylinder; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/** + * ModelClipTest draws a cylinder and creates two clip planes + * to see the interior of the cylinder. + */ +public class ModelClipTest extends Applet { + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() + { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // This Transformgroup is used by the mouse manipulators to + // move the CYlinder. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objScale.addChild(objTrans); + + //Create Model Clip + ModelClip mc = new ModelClip(); + boolean enables[] = {false, false, false, false, false, false}; + Vector4d eqn1 = new Vector4d(0.0, 1.0, 0.0, 0.0); + Vector4d eqn2 = new Vector4d(1.0, 1.0, 0.0, 0.0); + mc.setEnables(enables); + mc.setPlane(1, eqn1); + mc.setPlane(2, eqn2); + mc.setEnable(1, true); + mc.setEnable(2, true); + mc.setInfluencingBounds(bounds); + objTrans.addChild(mc); + + //Create a cylinder + PolygonAttributes attr = new PolygonAttributes(); + attr.setCullFace(PolygonAttributes.CULL_NONE); + Appearance ap = new Appearance(); + Material mat = new Material(); + mat.setLightingEnable(true); + ap.setMaterial(mat); + ap.setPolygonAttributes(attr); + + Cylinder CylinderObj = new Cylinder(1.0f, 2.0f, ap); + objTrans.addChild(CylinderObj); + + // Create the rotate behavior node + MouseRotate behavior = new MouseRotate(objTrans); + objTrans.addChild(behavior); + behavior.setSchedulingBounds(bounds); + + // Create the zoom behavior node + MouseZoom behavior2 = new MouseZoom(objTrans); + objTrans.addChild(behavior2); + behavior2.setSchedulingBounds(bounds); + + //Shine it with two colored lights. + Color3f lColor1 = new Color3f(0.5f, 0.0f, 0.5f); + Color3f lColor2 = new Color3f(0.7f, 0.7f, 0.0f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, 1.0f); + Vector3f lDir2 = new Vector3f(0.0f, 0.0f, -1.0f); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2); + lgt1.setInfluencingBounds(bounds); + lgt2.setInfluencingBounds(bounds); + objScale.addChild(lgt1); + objScale.addChild(lgt2); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public ModelClipTest (){ + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + + public static void main(String argv[]) + { + + BranchGroup group; + + new MainFrame(new ModelClipTest(), 500, 500); + } +} + diff --git a/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java b/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java new file mode 100644 index 0000000..be3e832 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/model_clip/ModelClipTest2.java @@ -0,0 +1,197 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.model_clip; + +import com.sun.j3d.utils.behaviors.mouse.*; +import com.sun.j3d.utils.geometry.Cylinder; +import com.sun.j3d.utils.geometry.Box; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/** + * ModelClipTest2 draws a cylinder and creates two clip planes + * to see the interior of the cylinder. It also has a behavior to + * move the clip planes. + */ +public class ModelClipTest2 extends Applet { + + private SimpleUniverse u; + + public BranchGroup createSceneGraph() + { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + //Shine it with two colored lights. + Color3f lColor0 = new Color3f(1.0f, 1.0f, 1.0f); + Color3f lColor1 = new Color3f(0.5f, 0.0f, 0.5f); + Color3f lColor2 = new Color3f(0.7f, 0.7f, 0.0f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, 1.0f); + Vector3f lDir2 = new Vector3f(0.0f, 0.0f, -1.0f); + + AmbientLight lgt0 = new AmbientLight(true, lColor2); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2); + lgt0.setInfluencingBounds(bounds); + lgt1.setInfluencingBounds(bounds); + lgt2.setInfluencingBounds(bounds); + objScale.addChild(lgt0); + objScale.addChild(lgt1); + objScale.addChild(lgt2); + + // Create a Transformgroup for the geometry + TransformGroup objRot = new TransformGroup(); + Transform3D t3d1 = new Transform3D(); + AxisAngle4f rot1 = new AxisAngle4f(0.0f, 1.0f, 0.0f, 45.0f); + t3d1.setRotation(rot1); + objRot.setTransform(t3d1); + objScale.addChild(objRot); + + + //Create a cylinder + PolygonAttributes attr = new PolygonAttributes(); + attr.setCullFace(PolygonAttributes.CULL_NONE); + Appearance ap = new Appearance(); + Material mat = new Material(); + mat.setLightingEnable(true); + ap.setMaterial(mat); + ap.setPolygonAttributes(attr); + + Cylinder CylinderObj = new Cylinder(0.5f, 2.2f, ap); + objRot.addChild(CylinderObj); + + //Create a box + Box BoxObj = new Box(0.8f, 0.8f, 0.8f, ap); + objRot.addChild(BoxObj); + + + // This Transformgroup is used by the mouse manipulators to + // move the model clip planes. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objRot.addChild(objTrans); + + // Create the rotate behavior node + MouseRotate behavior = new MouseRotate(objTrans); + objTrans.addChild(behavior); + behavior.setSchedulingBounds(bounds); + + // Create the zoom behavior node + MouseZoom behavior2 = new MouseZoom(objTrans); + objTrans.addChild(behavior2); + behavior2.setSchedulingBounds(bounds); + + //Create Model Clip + ModelClip mc = new ModelClip(); + boolean enables[] = {false, false, false, false, false, false}; + Vector4d eqn = new Vector4d(0.0, 1.0, 1.0, 0.0); + mc.setEnables(enables); + mc.setPlane(1, eqn); + mc.setEnable(1, true); + mc.setInfluencingBounds(bounds); + objTrans.addChild(mc); + + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public ModelClipTest2 (){ + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + + + public static void main(String argv[]) + { + + BranchGroup group; + + new MainFrame(new ModelClipTest2(), 500, 500); + } +} + diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/ColorCube.java b/src/classes/org/jdesktop/j3d/examples/morphing/ColorCube.java new file mode 100644 index 0000000..fd3fbda --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/morphing/ColorCube.java @@ -0,0 +1,123 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.morphing; + +import javax.media.j3d.*; +import javax.vecmath.*; + +class ColorCube extends QuadArray { + private static final float[] verts = { + // front face + 1.0f, -1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 1.0f, + // back face + -1.0f, -1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, + 1.0f, 1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, + // right face + 1.0f, -1.0f, -1.0f, + 1.0f, 1.0f, -1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 1.0f, + // left face + -1.0f, -1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, -1.0f, + -1.0f, -1.0f, -1.0f, + // top face + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, 1.0f, + // bottom face + -1.0f, -1.0f, 1.0f, + -1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, 1.0f, + }; + + private static final float[] colors = { + // front face (red) + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + // back face (green) + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + // right face (blue) + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + // left face (yellow) + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + // top face (magenta) + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + // bottom face (cyan) + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + }; + + ColorCube() { + super(24, QuadArray.COORDINATES | QuadArray.COLOR_3); + + setCoordinates(0, verts); + setColors(0, colors); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java b/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java new file mode 100644 index 0000000..0957e19 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidDown.java @@ -0,0 +1,123 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.morphing; + +import javax.media.j3d.*; +import javax.vecmath.*; + +class ColorPyramidDown extends QuadArray { + private static final float[] verts = { + // front face + 0.0f, -1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + 0.0f, -1.0f, 0.0f, + // back face + 0.0f, -1.0f, 0.0f, + -1.0f, 1.0f, -1.0f, + 1.0f, 1.0f, -1.0f, + 0.0f, -1.0f, 0.0f, + // right face + 0.0f, -1.0f, 0.0f, + 1.0f, 1.0f, -1.0f, + 1.0f, 1.0f, 1.0f, + 0.0f, -1.0f, 0.0f, + // left face + 0.0f, -1.0f, 0.0f, + -1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, -1.0f, + 0.0f, -1.0f, 0.0f, + // top face + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, 1.0f, + // bottom face + 0.0f, -1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, + }; + + private static final float[] colors = { + // front face (green) + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + // back face (red) + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + // right face (yellow) + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + // left face (magenta) + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + // top face (blue) + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + // bottom face (cyan) + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + }; + + ColorPyramidDown() { + super(24, QuadArray.COORDINATES | QuadArray.COLOR_3); + + setCoordinates(0, verts); + setColors(0, colors); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java b/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java new file mode 100644 index 0000000..407c8bb --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/morphing/ColorPyramidUp.java @@ -0,0 +1,125 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.morphing; + +import javax.media.j3d.*; +import javax.vecmath.*; + +class ColorPyramidUp extends QuadArray { + private static final float[] verts = { + // front face + 1.0f, -1.0f, 1.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 1.0f, + // back face + -1.0f, -1.0f, -1.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 1.0f, -1.0f, -1.0f, + // right face + 1.0f, -1.0f, -1.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 1.0f, + // left face + -1.0f, -1.0f, 1.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, -1.0f, + // top face + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + // bottom face + -1.0f, -1.0f, 1.0f, + -1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, 1.0f, + }; + + private static final float[] colors = { + + // front face (cyan) + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, + // back face (magenta) + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, + // right face (yellow) + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + // left face (blue) + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, + // top face (green) + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + // bottom face (red) + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, + + }; + + ColorPyramidUp() { + super(24, QuadArray.COORDINATES | QuadArray.COLOR_3); + + setCoordinates(0, verts); + setColors(0, colors); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/Morphing.java b/src/classes/org/jdesktop/j3d/examples/morphing/Morphing.java new file mode 100644 index 0000000..cbca643 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/morphing/Morphing.java @@ -0,0 +1,262 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.morphing; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.io.*; +import com.sun.j3d.loaders.objectfile.ObjectFile; +import com.sun.j3d.loaders.Scene; +import com.sun.j3d.loaders.ParsingErrorException; +import com.sun.j3d.loaders.IncorrectFormatException; + +public class Morphing extends Applet { + + private java.net.URL[] objFiles = null; + + private SimpleUniverse u = null; + + private BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + objScale.addChild(bg); + + // Set up the global lights + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + objScale.addChild(aLgt); + objScale.addChild(lgt1); + + // + // Create the transform group nodes for the 3 original objects + // and the morphed object. Add them to the root of the + // branch graph. + // + TransformGroup objTrans[] = new TransformGroup[4]; + + for(int i=0; i<4; i++) { + objTrans[i] = new TransformGroup(); + objScale.addChild(objTrans[i]); + } + + Transform3D tr = new Transform3D(); + Transform3D rotX90 = new Transform3D(); + rotX90.rotX(90.0 * Math.PI / 180.0); + + objTrans[0].getTransform(tr); + tr.setTranslation(new Vector3d(-2.0, 1.5, -2.0)); + tr.mul(rotX90); + objTrans[0].setTransform(tr); + + objTrans[1].getTransform(tr); + tr.setTranslation(new Vector3d(0.0, 1.5, -2.0)); + tr.mul(rotX90); + objTrans[1].setTransform(tr); + + objTrans[2].getTransform(tr); + tr.setTranslation(new Vector3d(2.0, 1.5, -2.0)); + tr.mul(rotX90); + objTrans[2].setTransform(tr); + + objTrans[3].getTransform(tr); + tr.setTranslation(new Vector3d(0.0, -2.0, -2.0)); + tr.mul(rotX90); + objTrans[3].setTransform(tr); + + + // Now load the object files + Scene s[] = new Scene[3]; + GeometryArray g[] = new GeometryArray[3]; + Shape3D shape[] = new Shape3D[3]; + ObjectFile loader = new ObjectFile(ObjectFile.RESIZE); + for(int i=0; i<3; i++) { + s[i] = null; + g[i] = null; + shape[i] = null; + } + + for(int i=0; i<3;i++) { + try { + s[i] = loader.load(objFiles[i]); + } + catch (FileNotFoundException e) { + System.err.println(e); + System.exit(1); + } + catch (ParsingErrorException e) { + System.err.println(e); + System.exit(1); + } + catch (IncorrectFormatException e) { + System.err.println(e); + System.exit(1); + } + + BranchGroup b = s[i].getSceneGroup(); + shape[i] = (Shape3D) b.getChild(0); + g[i] = (GeometryArray) shape[i].getGeometry(); + + shape[i].setGeometry(g[i]); + objTrans[i].addChild(b); + } + + // + // Create a Morph node, and set the appearance and input geometry + // arrays. Set the Morph node's capability bits to allow the weights + // to be modified at runtime. + // + Appearance app = new Appearance(); + Color3f objColor = new Color3f(1.0f, 0.7f, 0.8f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + app.setMaterial(new Material(objColor, black, objColor, black, 80.0f)); + Morph morph = new Morph(g, app); + morph.setCapability(Morph.ALLOW_WEIGHTS_READ); + morph.setCapability(Morph.ALLOW_WEIGHTS_WRITE); + + objTrans[3].addChild(morph); + + // Now create the Alpha object that controls the speed of the + // morphing operation. + Alpha morphAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE | + Alpha.DECREASING_ENABLE, + 0, 0, + 2000, 1000, 200, + 2000, 1000, 200); + + // Finally, create the morphing behavior + MorphingBehavior mBeh = new MorphingBehavior(morphAlpha, morph); + mBeh.setSchedulingBounds(bounds); + objScale.addChild(mBeh); + + return objRoot; + } + + public Morphing() {} + + public Morphing(java.net.URL[] urls) { + objFiles = urls; + } + + public void init() { + if (objFiles == null) { + objFiles = new java.net.URL[3]; + // the path to the image for an applet + String path = getCodeBase().toString(); + try { + objFiles[0] = new java.net.URL(path + "hand1.obj"); + objFiles[1] = new java.net.URL(path + "hand2.obj"); + objFiles[2] = new java.net.URL(path + "hand3.obj"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + public static void main(String[] args) { + java.net.URL[] urls = new java.net.URL[3]; + // the path to the image file for an application + try { + urls[0] = new java.net.URL("file:./hand1.obj"); + urls[1] = new java.net.URL("file:./hand2.obj"); + urls[2] = new java.net.URL("file:./hand3.obj"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + new MainFrame(new Morphing(urls), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java b/src/classes/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java new file mode 100644 index 0000000..3353329 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/morphing/MorphingBehavior.java @@ -0,0 +1,99 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.morphing; + +import java.util.Enumeration; +import javax.media.j3d.*; +import javax.vecmath.*; + +// User-defined morphing behavior class +public class MorphingBehavior extends Behavior { + + Alpha alpha; + Morph morph; + double weights[]; + + WakeupOnElapsedFrames w = new WakeupOnElapsedFrames(0); + + // Override Behavior's initialize method to setup wakeup criteria + public void initialize() { + alpha.setStartTime(System.currentTimeMillis()); + + // Establish initial wakeup criteria + wakeupOn(w); + } + + // Override Behavior's stimulus method to handle the event + public void processStimulus(Enumeration criteria) { + + // NOTE: This assumes 3 objects. It should be generalized to + // "n" objects. + + double val = alpha.value(); + if (val < 0.5) { + double a = val * 2.0; + weights[0] = 1.0 - a; + weights[1] = a; + weights[2] = 0.0; + } + else { + double a = (val - 0.5) * 2.0; + weights[0] = 0.0; + weights[1] = 1.0f - a; + weights[2] = a; + } + + morph.setWeights(weights); + + // Set wakeup criteria for next time + wakeupOn(w); + } + + public MorphingBehavior(Alpha a, Morph m) { + alpha = a; + morph = m; + weights = morph.getWeights(); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java b/src/classes/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java new file mode 100644 index 0000000..e4d86ee --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/morphing/Pyramid2Cube.java @@ -0,0 +1,194 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.morphing; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Pyramid2Cube extends Applet { + + private SimpleUniverse u = null; + + private BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + + // Create a bounds for the background and behavior + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + objScale.addChild(bg); + + // + // Create the transform group nodes for the 3 original objects + // and the morphed object. Add them to the root of the + // branch graph. + // + TransformGroup objTrans[] = new TransformGroup[4]; + + for(int i=0; i<4; i++) { + objTrans[i] = new TransformGroup(); + objScale.addChild(objTrans[i]); + } + + Transform3D tr = new Transform3D(); + Transform3D rotY15 = new Transform3D(); + rotY15.rotY(15.0 * Math.PI / 180.0); + + objTrans[0].getTransform(tr); + tr.setTranslation(new Vector3d(-3.0, 1.5, -6.5)); + tr.mul(rotY15); + objTrans[0].setTransform(tr); + + objTrans[1].getTransform(tr); + tr.setTranslation(new Vector3d(0.0, 1.5, -6.5)); + tr.mul(rotY15); + objTrans[1].setTransform(tr); + + objTrans[2].getTransform(tr); + tr.setTranslation(new Vector3d(3.0, 1.5, -6.5)); + tr.mul(rotY15); + objTrans[2].setTransform(tr); + + objTrans[3].getTransform(tr); + tr.setTranslation(new Vector3d(0.0, -2.0, -5.0)); + tr.mul(rotY15); + objTrans[3].setTransform(tr); + + // Now create simple geometries. + + QuadArray g[] = new QuadArray[3]; + Shape3D shape[] = new Shape3D[3]; + for(int i=0; i<3; i++) { + g[i] = null; + shape[i] = null; + } + + g[0] = new ColorPyramidUp(); + g[1] = new ColorCube(); + g[2] = new ColorPyramidDown(); + + Appearance a = new Appearance(); + + for(int i=0; i<3;i++) { + shape[i] = new Shape3D(g[i],a); + objTrans[i].addChild(shape[i]); + } + + // + // Create a Morph node, and set the appearance and input geometry + // arrays. Set the Morph node's capability bits to allow the weights + // to be modified at runtime. + // + Morph morph = new Morph((GeometryArray[]) g, a); + morph.setCapability(Morph.ALLOW_WEIGHTS_READ); + morph.setCapability(Morph.ALLOW_WEIGHTS_WRITE); + + objTrans[3].addChild(morph); + + // Now create the Alpha object that controls the speed of the + // morphing operation. + Alpha morphAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE | + Alpha.DECREASING_ENABLE, + 0, 0, + 4000, 1000, 500, + 4000, 1000, 500); + + // Finally, create the morphing behavior + MorphingBehavior mBeh = new MorphingBehavior(morphAlpha, morph); + mBeh.setSchedulingBounds(bounds); + objScale.addChild(mBeh); + + return objRoot; + } + + public Pyramid2Cube() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + public static void main(String[] args) { + new MainFrame(new Pyramid2Cube(), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/objload/ObjLoad.java b/src/classes/org/jdesktop/j3d/examples/objload/ObjLoad.java new file mode 100644 index 0000000..dd57983 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/objload/ObjLoad.java @@ -0,0 +1,287 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.objload; + +import com.sun.j3d.loaders.objectfile.ObjectFile; +import com.sun.j3d.loaders.ParsingErrorException; +import com.sun.j3d.loaders.IncorrectFormatException; +import com.sun.j3d.loaders.Scene; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.io.*; +import com.sun.j3d.utils.behaviors.vp.*; +import java.net.URL; +import java.net.MalformedURLException; + +public class ObjLoad extends Applet { + + private boolean spin = false; + private boolean noTriangulate = false; + private boolean noStripify = false; + private double creaseAngle = 60.0; + private URL filename = null; + private SimpleUniverse u; + private BoundingSphere bounds; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.7); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objScale.addChild(objTrans); + + int flags = ObjectFile.RESIZE; + if (!noTriangulate) flags |= ObjectFile.TRIANGULATE; + if (!noStripify) flags |= ObjectFile.STRIPIFY; + ObjectFile f = new ObjectFile(flags, + (float)(creaseAngle * Math.PI / 180.0)); + Scene s = null; + try { + s = f.load(filename); + } + catch (FileNotFoundException e) { + System.err.println(e); + System.exit(1); + } + catch (ParsingErrorException e) { + System.err.println(e); + System.exit(1); + } + catch (IncorrectFormatException e) { + System.err.println(e); + System.exit(1); + } + + objTrans.addChild(s.getSceneGroup()); + + bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + if (spin) { + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + } + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f); + Background bgNode = new Background(bgColor); + bgNode.setApplicationBounds(bounds); + objRoot.addChild(bgNode); + + return objRoot; + } + + private void usage() + { + System.out.println( + "Usage: java ObjLoad [-s] [-n] [-t] [-c degrees] <.obj file>"); + System.out.println(" -s Spin (no user interaction)"); + System.out.println(" -n No triangulation"); + System.out.println(" -t No stripification"); + System.out.println( + " -c Set crease angle for normal generation (default is 60 without"); + System.out.println( + " smoothing group info, otherwise 180 within smoothing groups)"); + System.exit(0); + } // End of usage + + + + public void init() { + if (filename == null) { + // Applet + try { + URL path = getCodeBase(); + filename = new URL(path.toString() + "./galleon.obj"); + } + catch (MalformedURLException e) { + System.err.println(e); + System.exit(1); + } + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // add mouse behaviors to the ViewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + PlatformGeometry pg = new PlatformGeometry(); + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + pg.addChild(ambientLightNode); + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f); + Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f); + Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f); + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + pg.addChild(light1); + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + pg.addChild(light2); + + viewingPlatform.setPlatformGeometry( pg ); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + if (!spin) { + OrbitBehavior orbit = new OrbitBehavior(c, + OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + } + + u.addBranchGraph(scene); + } + + // Caled if running as a program + public ObjLoad(String[] args) { + if (args.length != 0) { + for (int i = 0 ; i < args.length ; i++) { + if (args[i].startsWith("-")) { + if (args[i].equals("-s")) { + spin = true; + } else if (args[i].equals("-n")) { + noTriangulate = true; + } else if (args[i].equals("-t")) { + noStripify = true; + } else if (args[i].equals("-c")) { + if (i < args.length - 1) { + creaseAngle = (new Double(args[++i])).doubleValue(); + } else usage(); + } else { + usage(); + } + } else { + try { + if ((args[i].indexOf("file:") == 0) || + (args[i].indexOf("http") == 0)) { + filename = new URL(args[i]); + } + else if (args[i].charAt(0) != '/') { + filename = new URL("file:./" + args[i]); + } + else { + filename = new URL("file:" + args[i]); + } + } + catch (MalformedURLException e) { + System.err.println(e); + System.exit(1); + } + } + } + } + } + + + + // Running as an applet + public ObjLoad() { + } + + public void destroy() { + u.cleanup(); + } + + + + // + // The following allows ObjLoad to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new ObjLoad(args), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java new file mode 100644 index 0000000..503dc42 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenCanvas3D.java @@ -0,0 +1,105 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.offscreen_canvas3d; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.event.*; +import javax.media.j3d.*; +import javax.vecmath.*; + + +class OffScreenCanvas3D extends Canvas3D { + + Raster drawRaster; + boolean printing = false; + + public OffScreenCanvas3D(GraphicsConfiguration gconfig, boolean offscreenflag, + Raster drawRaster) { + + super(gconfig, offscreenflag); + this.drawRaster = drawRaster; + } + + public void print(boolean toWait) { + + if (!toWait) + printing = true; + + BufferedImage bImage = new BufferedImage( + 200, 200 , BufferedImage.TYPE_INT_ARGB); + + ImageComponent2D buffer = new ImageComponent2D( + ImageComponent.FORMAT_RGBA, bImage); + buffer.setCapability(ImageComponent2D.ALLOW_IMAGE_READ); + + this.setOffScreenBuffer(buffer); + this.renderOffScreenBuffer(); + + if (toWait) { + this.waitForOffScreenRendering(); + drawOffScreenBuffer(); + } + } + + public void postSwap() { + + if (printing) { + super.postSwap(); + drawOffScreenBuffer(); + printing = false; + } + } + + void drawOffScreenBuffer() { + + BufferedImage bImage = this.getOffScreenBuffer().getImage(); + ImageComponent2D newImageComponent = new ImageComponent2D( + ImageComponent.FORMAT_RGBA, bImage); + + drawRaster.setImage(newImageComponent); + } +} + diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form new file mode 100644 index 0000000..39a0712 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.form @@ -0,0 +1,36 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java new file mode 100644 index 0000000..f432e46 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OffScreenTest.java @@ -0,0 +1,219 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.offscreen_canvas3d; + +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.geometry.ColorCube; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.*; +import java.awt.image.BufferedImage; + +/** + * OffScreenTest programs with no UI. + */ +public class OffScreenTest extends javax.swing.JFrame { + + private SimpleUniverse univ = null; + private BranchGroup scene = null; + private Raster drawRaster = null; + + private BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // trans object has composited transformation matrix + Transform3D trans = new Transform3D(); + Transform3D rot = new Transform3D(); + + trans.rotX(Math.PI/4.0d); + rot.rotY(Math.PI/5.0d); + trans.mul(rot); + trans.setScale(0.7); + trans.setTranslation(new Vector3d(-0.4, 0.3, 0.0)); + + TransformGroup objTrans = new TransformGroup(trans); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node, add it to the scene graph. + // ColorCube is a Convenience Utility class + objTrans.addChild(new ColorCube(0.4)); + + //Create a raster + BufferedImage bImage = new BufferedImage(200, 200 , + BufferedImage.TYPE_INT_ARGB); + ImageComponent2D buffer = + new ImageComponent2D(ImageComponent.FORMAT_RGBA, bImage); + buffer.setCapability(ImageComponent2D.ALLOW_IMAGE_READ); + + drawRaster = new Raster(new Point3f(0.0f, 0.0f, 0.0f), + Raster.RASTER_COLOR, + 0, 0, 200, 200, buffer, null); + + drawRaster.setCapability(Raster.ALLOW_IMAGE_WRITE); + Shape3D shape = new Shape3D(drawRaster); + objRoot.addChild(shape); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + + private OnScreenCanvas3D createOnScreenCanvasAndUniverse() { + // Get the preferred graphics configuration for the default screen + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + // Create a Canvas3D using the preferred configuration + OnScreenCanvas3D onScrCanvas = new OnScreenCanvas3D(config, false); + + // Create simple universe with view branch + univ = new SimpleUniverse(onScrCanvas); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + univ.getViewingPlatform().setNominalViewingTransform(); + + // Ensure at least 5 msec per frame (i.e., < 200Hz) + univ.getViewer().getView().setMinimumFrameCycleTime(5); + + return onScrCanvas; + } + + private OffScreenCanvas3D createOffScreenCanvas() { + // request an offscreen Canvas3D with a single buffer configuration + GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); + template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY); + GraphicsConfiguration gc = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getBestConfiguration(template); + + // Create a offscreen Canvas3D using the single buffer configuration. + OffScreenCanvas3D offScrCanvas = + new OffScreenCanvas3D(gc, true, drawRaster); + + return offScrCanvas; + } + + /** + * Creates new form OffScreenTest + */ + public OffScreenTest() { + // Initialize the GUI components + initComponents(); + + // Create the content branch and add it to the universe + scene = createSceneGraph(); + + // Create an OnScreenCanvas3D and SimpleUniverse; add canvas to drawing panel + OnScreenCanvas3D onScreenCanvas = createOnScreenCanvasAndUniverse(); + drawingPanel.add(onScreenCanvas, java.awt.BorderLayout.CENTER); + + // Creante an OffScreenCanvas3D + OffScreenCanvas3D offScreenCanvas = createOffScreenCanvas(); + + // set the offscreen to match the onscreen + Screen3D sOn = onScreenCanvas.getScreen3D(); + Screen3D sOff = offScreenCanvas.getScreen3D(); + sOff.setSize(sOn.getSize()); + sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth()); + sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight()); + + // attach the same view to the offscreen canvas + View view = univ.getViewer().getView(); + view.addCanvas3D(offScreenCanvas); + + // tell onscreen about the offscreen so it knows to + // render to the offscreen at postswap + onScreenCanvas.setOffScreenCanvas(offScreenCanvas); + + univ.addBranchGraph(scene); + + view.stopView(); + // Make sure that image are render completely + // before grab it in postSwap(). + onScreenCanvas.setImageReady(); + view.startView(); + } + + // ---------------------------------------------------------------- + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //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(); + }// //GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new OffScreenTest().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel drawingPanel; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java new file mode 100644 index 0000000..93c3d5b --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/OnScreenCanvas3D.java @@ -0,0 +1,85 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.offscreen_canvas3d; + +import com.sun.j3d.utils.geometry.ColorCube; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import java.awt.image.BufferedImage; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + + +class OnScreenCanvas3D extends Canvas3D { + + OffScreenCanvas3D c; + boolean print = false; + boolean imageReady = false; + + public OnScreenCanvas3D(GraphicsConfiguration gconfig, boolean offscreenflag) + { + super(gconfig, offscreenflag); + } + + public void setOffScreenCanvas(OffScreenCanvas3D c) + { + this.c = c; + } + + public void setImageReady() { + imageReady = true; + } + + public void postSwap() + { + if (imageReady && !print) { + c.print(false); + print = true; + } + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form new file mode 100644 index 0000000..54d6721 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.form @@ -0,0 +1,82 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java new file mode 100644 index 0000000..89d6557 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/offscreen_canvas3d/PrintFromButton.java @@ -0,0 +1,262 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.offscreen_canvas3d; + +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.geometry.ColorCube; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.GraphicsConfiguration; +import javax.swing.JPopupMenu; +import java.awt.*; +import java.awt.image.BufferedImage; + +/** + * PrintFromButton programs with simple UI. + */ +public class PrintFromButton extends javax.swing.JFrame { + + private SimpleUniverse univ = null; + private BranchGroup scene = null; + private Raster drawRaster = null; + private OffScreenCanvas3D offScreenCanvas = null; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // trans object has composited transformation matrix + Transform3D trans = new Transform3D(); + Transform3D rot = new Transform3D(); + + trans.rotX(Math.PI/4.0d); + rot.rotY(Math.PI/5.0d); + trans.mul(rot); + trans.setScale(0.7); + trans.setTranslation(new Vector3d(-0.4, 0.3, 0.0)); + + TransformGroup objTrans = new TransformGroup(trans); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node, add it to the scene graph. + // ColorCube is a Convenience Utility class + objTrans.addChild(new ColorCube(0.4)); + + //Create a raster + BufferedImage bImage = new BufferedImage(200, 200 , + BufferedImage.TYPE_INT_ARGB); + ImageComponent2D buffer = + new ImageComponent2D(ImageComponent.FORMAT_RGBA, bImage); + buffer.setCapability(ImageComponent2D.ALLOW_IMAGE_READ); + + drawRaster = new Raster(new Point3f(0.0f, 0.0f, 0.0f), + Raster.RASTER_COLOR, + 0, 0, 200, 200, buffer, null); + + drawRaster.setCapability(Raster.ALLOW_IMAGE_WRITE); + Shape3D shape = new Shape3D(drawRaster); + objRoot.addChild(shape); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + private OnScreenCanvas3D createOnScreenCanvasAndUniverse() { + // Get the preferred graphics configuration for the default screen + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + // Create a Canvas3D using the preferred configuration + OnScreenCanvas3D onScrCanvas = new OnScreenCanvas3D(config, false); + + // Create simple universe with view branch + univ = new SimpleUniverse(onScrCanvas); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + univ.getViewingPlatform().setNominalViewingTransform(); + + // Ensure at least 5 msec per frame (i.e., < 200Hz) + univ.getViewer().getView().setMinimumFrameCycleTime(5); + + return onScrCanvas; + } + + private OffScreenCanvas3D createOffScreenCanvas() { + // request an offscreen Canvas3D with a single buffer configuration + GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); + template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY); + GraphicsConfiguration gc = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getBestConfiguration(template); + + // Create a offscreen Canvas3D using the single buffer configuration. + OffScreenCanvas3D offScrCanvas = + new OffScreenCanvas3D(gc, true, drawRaster); + + return offScrCanvas; + } + + /** + * Creates new form PrintFromButton + */ + public PrintFromButton() { + // Initialize the GUI components + JPopupMenu.setDefaultLightWeightPopupEnabled(false); + initComponents(); + + // Create the content branch and add it to the universe + scene = createSceneGraph(); + + // Create an OnScreenCanvas3D and SimpleUniverse; add canvas to drawing panel + OnScreenCanvas3D onScreenCanvas = createOnScreenCanvasAndUniverse(); + drawingPanel.add(onScreenCanvas, java.awt.BorderLayout.CENTER); + + // Creante an OffScreenCanvas3D + offScreenCanvas = createOffScreenCanvas(); + + // set the offscreen to match the onscreen + Screen3D sOn = onScreenCanvas.getScreen3D(); + Screen3D sOff = offScreenCanvas.getScreen3D(); + sOff.setSize(sOn.getSize()); + sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth()); + sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight()); + + // attach the same view to the offscreen canvas + View view = univ.getViewer().getView(); + view.addCanvas3D(offScreenCanvas); + + univ.addBranchGraph(scene); + } + + // ---------------------------------------------------------------- + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //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(); + }// //GEN-END:initComponents + + private void myButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_myButtonActionPerformed + offScreenCanvas.print(false); + }//GEN-LAST:event_myButtonActionPerformed + + private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed + System.exit(0); + }//GEN-LAST:event_exitMenuItemActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new PrintFromButton().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel drawingPanel; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JMenu fileMenu; + private javax.swing.JPanel guiPanel; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JButton myButton; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java b/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java new file mode 100644 index 0000000..0d12bd3 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/oriented_shape3d/MouseRotateY.java @@ -0,0 +1,196 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.oriented_shape3d; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import com.sun.j3d.utils.behaviors.mouse.*; + +/** + * MouseRotateY is a Java3D behavior object that lets users control the + * rotation of an object via a mouse. + *

+ * To use this utility, first create a transform group that this + * rotate behavior will operate on. Then, + *

+ * 
+ *   MouseRotateY behavior = new MouseRotateY();
+ *   behavior.setTransformGroup(objTrans);
+ *   objTrans.addChild(behavior);
+ *   behavior.setSchedulingBounds(bounds);
+ *
+ *
+ * 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= 1) { + return Printable.NO_SUCH_PAGE; + } + + Graphics2D g2d = (Graphics2D)g; + //g2d.translate(pf.getImageableX(), pf.getImageableY()); + AffineTransform t2d = new AffineTransform(); + t2d.translate(pf.getImageableX(), pf.getImageableY()); + double xscale = pf.getImageableWidth() / (double)bImage.getWidth(); + double yscale = pf.getImageableHeight() / (double)bImage.getHeight(); + double scale = Math.min(xscale, yscale); + t2d.scale(scale, scale); + try { + g2d.drawImage(bImage,t2d, this); + } + catch (Exception ex) { + ex.printStackTrace(); + return Printable.NO_SUCH_PAGE; + } + return Printable.PAGE_EXISTS; + } + + void print() { + PrinterJob printJob = PrinterJob.getPrinterJob(); + PageFormat pageFormat = printJob.defaultPage(); + pageFormat.setOrientation(PageFormat.LANDSCAPE); + pageFormat = printJob.validatePage(pageFormat); + printJob.setPrintable(this, pageFormat); + if (printJob.printDialog()) { + try { + printJob.print(); + } + catch (PrinterException ex) { + ex.printStackTrace(); + } + } + } + + public boolean imageUpdate(Image img, + int infoflags, + int x, + int y, + int width, + int height) { + return false; + } + + ImagePrinter(BufferedImage bImage) { + this.bImage = bImage; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java new file mode 100644 index 0000000..474f386 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/OffScreenCanvas3D.java @@ -0,0 +1,82 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.print_canvas3d; + +import java.awt.GraphicsConfiguration; +import java.awt.image.BufferedImage; +import javax.media.j3d.*; +import javax.vecmath.*; + + +class OffScreenCanvas3D extends Canvas3D { + OffScreenCanvas3D(GraphicsConfiguration graphicsConfiguration, + boolean offScreen) { + + super(graphicsConfiguration, offScreen); + } + + BufferedImage doRender(int width, int height) { + + BufferedImage bImage = + new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + + ImageComponent2D buffer = + new ImageComponent2D(ImageComponent.FORMAT_RGBA, bImage); + + setOffScreenBuffer(buffer); + renderOffScreenBuffer(); + waitForOffScreenRendering(); + bImage = getOffScreenBuffer().getImage(); + + // To release the reference of buffer inside Java 3D. + setOffScreenBuffer(null); + + return bImage; + } + + public void postSwap() { + // No-op since we always wait for off-screen rendering to complete + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form new file mode 100644 index 0000000..5150ee2 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.form @@ -0,0 +1,74 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java new file mode 100644 index 0000000..c40993a --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/print_canvas3d/PrintCanvas3D.java @@ -0,0 +1,374 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.print_canvas3d; + +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.*; +import java.awt.GraphicsConfiguration; +import javax.swing.JPopupMenu; + +import com.sun.j3d.loaders.objectfile.ObjectFile; +import com.sun.j3d.loaders.ParsingErrorException; +import com.sun.j3d.loaders.IncorrectFormatException; +import com.sun.j3d.loaders.Scene; +import java.awt.image.BufferedImage; +import java.awt.event.*; +import java.io.*; +import com.sun.j3d.utils.behaviors.mouse.*; + +public class PrintCanvas3D extends javax.swing.JFrame { + + private static final boolean noTriangulate = false; + private static final boolean noStripify = false; + private static final double creaseAngle = 60.0; + private Canvas3D onScreenCanvas3D; + private OffScreenCanvas3D offScreenCanvas3D; + private String filename = null; + private static final int OFF_SCREEN_SCALE = 3; + + private SimpleUniverse univ = null; + + public BranchGroup createSceneGraph(String args[]) { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.7); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objScale.addChild(objTrans); + + int flags = ObjectFile.RESIZE; + if (!noTriangulate) flags |= ObjectFile.TRIANGULATE; + if (!noStripify) flags |= ObjectFile.STRIPIFY; + ObjectFile f = + new ObjectFile(flags, + (float)(creaseAngle * Math.PI / 180.0)); + Scene scene = null; + try { + scene = f.load(filename); + } + catch (FileNotFoundException e) { + System.err.println(e); + System.exit(1); + } + catch (ParsingErrorException e) { + System.err.println(e); + System.exit(1); + } + catch (IncorrectFormatException e) { + System.err.println(e); + System.exit(1); + } + + objTrans.addChild(scene.getSceneGroup()); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Create the rotate behavior node + MouseRotate behavior = new MouseRotate(); + behavior.setTransformGroup(objTrans); + objTrans.addChild(behavior); + behavior.setSchedulingBounds(bounds); + + // Create the zoom behavior node + MouseZoom behavior2 = new MouseZoom(); + behavior2.setTransformGroup(objTrans); + objTrans.addChild(behavior2); + behavior2.setSchedulingBounds(bounds); + + // Create the translate behavior node + MouseTranslate behavior3 = new MouseTranslate(); + behavior3.setTransformGroup(objTrans); + objTrans.addChild(behavior3); + behavior3.setSchedulingBounds(bounds); + + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f); + Background bgNode = new Background(bgColor); + bgNode.setApplicationBounds(bounds); + objRoot.addChild(bgNode); + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + objRoot.addChild(ambientLightNode); + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f); + Color3f light2Color = new Color3f(0.3f, 0.3f, 0.4f); + Vector3f light2Direction = new Vector3f(-6.0f, -2.0f, -1.0f); + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + objRoot.addChild(light1); + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + objRoot.addChild(light2); + + return objRoot; + } + + private void usage() { + System.out.println("Usage: java PrintCanvas3D <.obj file>"); + System.exit(0); + } // End of usage + + private OffScreenCanvas3D createOffScreenCanvas(Canvas3D onScreenCanvas3D) { + // Create the off-screen Canvas3D object + // request an offscreen Canvas3D with a single buffer configuration + GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); + template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY); + GraphicsConfiguration gc = + GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getBestConfiguration(template); + + offScreenCanvas3D = new OffScreenCanvas3D(gc, true); + // Set the off-screen size based on a scale factor times the + // on-screen size + Screen3D sOn = onScreenCanvas3D.getScreen3D(); + Screen3D sOff = offScreenCanvas3D.getScreen3D(); + Dimension dim = sOn.getSize(); + dim.width *= OFF_SCREEN_SCALE; + dim.height *= OFF_SCREEN_SCALE; + sOff.setSize(dim); + sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth() * + OFF_SCREEN_SCALE); + sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight() * + OFF_SCREEN_SCALE); + + // attach the offscreen canvas to the view + univ.getViewer().getView().addCanvas3D(offScreenCanvas3D); + + return offScreenCanvas3D; + + } + + private Canvas3D createUniverse() { + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + + univ = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + univ.getViewingPlatform().setNominalViewingTransform(); + + // Ensure at least 5 msec per frame (i.e., < 200Hz) + univ.getViewer().getView().setMinimumFrameCycleTime(5); + + return c; + } + + /** + * Creates new form PrintCanvas3D + */ + public PrintCanvas3D(String args[]) { + + if (args.length == 0) { + usage(); + } else { + for (int i = 0 ; i < args.length ; i++) { + if (args[i].startsWith("-")) { + System.err.println("Argument '" + args[i] + "' ignored."); + } else { + filename = args[i]; + } + } + } + + if (filename == null) { + usage(); + } + + // Initialize the GUI components + JPopupMenu.setDefaultLightWeightPopupEnabled(false); + initComponents(); + + // Create Canvas3D and SimpleUniverse; add canvas to drawing panel + onScreenCanvas3D = createUniverse(); + drawingPanel.add(onScreenCanvas3D, java.awt.BorderLayout.CENTER); + + // Create the content branch and add it to the universe + BranchGroup scene = createSceneGraph(args); + + // Create the off-screen Canvas3D object + createOffScreenCanvas(onScreenCanvas3D); + + univ.addBranchGraph(scene); + } + + // ---------------------------------------------------------------- + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //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(); + }// //GEN-END:initComponents + + private void printMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_printMenuItemActionPerformed + Point loc = onScreenCanvas3D.getLocationOnScreen(); + offScreenCanvas3D.setOffScreenLocation(loc); + Dimension dim = onScreenCanvas3D.getSize(); + dim.width *= OFF_SCREEN_SCALE; + dim.height *= OFF_SCREEN_SCALE; + BufferedImage bImage = + offScreenCanvas3D.doRender(dim.width, dim.height); + + new ImagePrinter(bImage).print(); + + }//GEN-LAST:event_printMenuItemActionPerformed + + private void snapShotMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_snapShotMenuItemActionPerformed + Point loc = onScreenCanvas3D.getLocationOnScreen(); + offScreenCanvas3D.setOffScreenLocation(loc); + Dimension dim = onScreenCanvas3D.getSize(); + dim.width *= OFF_SCREEN_SCALE; + dim.height *= OFF_SCREEN_SCALE; + BufferedImage bImage = + offScreenCanvas3D.doRender(dim.width, dim.height); + + new ImageDisplayer(bImage); + + + }//GEN-LAST:event_snapShotMenuItemActionPerformed + + private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed + System.exit(0); + }//GEN-LAST:event_exitMenuItemActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(final String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new PrintCanvas3D(args).setVisible(true);; + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel drawingPanel; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JMenu fileMenu; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JMenuItem printMenuItem; + private javax.swing.JMenuItem snapShotMenuItem; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java b/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java new file mode 100644 index 0000000..72e5bdd --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediate.java @@ -0,0 +1,151 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.pure_immediate; + +import java.applet.Applet; +import java.awt.BorderLayout; +import java.awt.GraphicsConfiguration; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/** + * Pure immediate mode example program. In pure immediate mode, the + * renderer must be stopped on the Canvas being rendered into. In our + * example, this is done immediately after the canvas is created. A + * separate thread is started up to do the immediate mode rendering. + */ +public class PureImmediate extends Applet implements Runnable { + + private Canvas3D canvas; + private GraphicsContext3D gc = null; + private Geometry cube = null; + private Transform3D cmt = new Transform3D(); + + // One rotation (2*PI radians) every 6 seconds + private Alpha rotAlpha = new Alpha(-1, 6000); + + private SimpleUniverse u = null; + + // + // Renders a single frame by clearing the canvas, drawing the + // geometry, and swapping the draw and display buffer. + // + public void render() { + if (gc == null) { + // Set up Graphics context + gc = canvas.getGraphicsContext3D(); + gc.setAppearance(new Appearance()); + + // Set up geometry + cube = new ColorCube(0.4).getGeometry(); + } + + // Compute angle of rotation based on alpha value + double angle = rotAlpha.value() * 2.0*Math.PI; + cmt.rotY(angle); + + // Render the geometry for this frame + gc.clear(); + gc.setModelTransform(cmt); + gc.draw(cube); + canvas.swap(); + } + + + // + // Run method for our immediate mode rendering thread. + // + public void run() { + System.out.println("PureImmediate.run: starting main loop"); + while (true) { + render(); + Thread.yield(); + } + } + + + public PureImmediate() { + } + + // + // init: create the canvas, stop the renderer, + // create the universe, and start the drawing thread. + // + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + canvas = new Canvas3D(config); + canvas.stopRenderer(); + add("Center", canvas); + + // Create the universe and viewing branch + u = new SimpleUniverse(canvas); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + // Start a new thread that will continuously render + new Thread(this).start(); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows PureImmediate to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new PureImmediate(), 256, 256); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java b/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java new file mode 100644 index 0000000..8c52509 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/pure_immediate/PureImmediateStereo.java @@ -0,0 +1,266 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.pure_immediate; + +import java.applet.Applet; +import java.awt.*; +import java.util.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.geometry.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/** + * Pure immediate mode stereo example program for stereo. In pure + * immediate mode, the renderer must be stopped on the Canvas being + * rendered into. In our example, this is done immediately after the + * canvas is created. A separate thread is started up to do the + * immediate mode rendering. + */ +public class PureImmediateStereo extends Applet implements Runnable { + + // Set this to true when the graphics card use shared z buffer + // in stereo mode. + public static String defaultSharedStereoZbuffer = Boolean.TRUE.toString(); + + private boolean sharedStereoZbuffer; + private boolean stereoSupport; + private Canvas3D canvas; + private GraphicsContext3D gc; + private Shape3D leftConeBody, rightConeBody; + private Shape3D leftConeCap, rightConeCap; + private Transform3D cmt = new Transform3D(); + private Vector3f leftTrans, rightTrans; + + // One rotation (2*PI radians) every 6 seconds + private Alpha rotAlpha = new Alpha(-1, 6000); + private SimpleUniverse u = null; + private double angle; + + // Compute data which is common for both + // left and right eye + void computeSharedData() { + // Compute angle of rotation based on alpha value + angle = rotAlpha.value() * 2.0*Math.PI; + cmt.rotY(angle); + } + + // Render the geometry in right eye + void renderLeft() { + cmt.setTranslation(leftTrans); + gc.setModelTransform(cmt); + + if (sharedStereoZbuffer) { + // Graphics card shared same z buffer in stereo mode, + // in this case we have to explicitly clearing both + // frame buffers. + gc.clear(); + } + gc.draw(leftConeBody); + gc.draw(leftConeCap); + } + + // Render the geometry for right eye + void renderRight() { + cmt.setTranslation(rightTrans); + gc.setModelTransform(cmt); + + if (sharedStereoZbuffer) { + // Graphics card shared same z buffer in stereo mode, + // in this case we have to explicitly clearing both + // frame buffers. + gc.clear(); + } + gc.draw(rightConeBody); + gc.draw(rightConeCap); + } + + // + // Run method for our immediate mode rendering thread. + // + public void run() { + // Set up Graphics context + gc = canvas.getGraphicsContext3D(); + + // We always need to set this for PureImmediate + // stereo mode + gc.setBufferOverride(true); + + Color3f lightColor = new Color3f(1, 1, 1); + Vector3f lightDir = new Vector3f(0, 0, -1); + DirectionalLight light = new DirectionalLight(lightColor, + lightDir); + + gc.addLight(light); + + Appearance redApp = new Appearance(); + Appearance greenApp = new Appearance(); + Color3f ambientColor = new Color3f(0, 0, 0); + Color3f emissiveColor = new Color3f(0, 0, 0); + Color3f diffuseColor = new Color3f(1, 0, 0); + Color3f specularColor = new Color3f(1, 1, 1); + redApp.setMaterial(new Material(ambientColor, emissiveColor, + diffuseColor, specularColor, 5)); + diffuseColor = new Color3f(0, 1, 0); + + greenApp.setMaterial(new Material(ambientColor, emissiveColor, + diffuseColor, specularColor, 5)); + + // Set up geometry + Cone leftCone = new Cone(0.4f, 0.6f, + Primitive.GENERATE_NORMALS, redApp); + Cone rightCone = new Cone(0.4f, 0.6f, + Primitive.GENERATE_NORMALS, greenApp); + leftConeBody = leftCone.getShape(Cone.BODY); + leftConeCap = leftCone.getShape(Cone.CAP); + + rightConeBody = rightCone.getShape(Cone.BODY); + rightConeCap = rightCone.getShape(Cone.CAP); + leftTrans = new Vector3f(-0.6f, 0, 0); + rightTrans = new Vector3f(0.6f, 0, 0); + + + while (true) { + // compute data which is can be used + // for both left and right eye + computeSharedData(); + + if (stereoSupport) { + if (!sharedStereoZbuffer) { + gc.setStereoMode(GraphicsContext3D.STEREO_BOTH); + // This clear both left and right buffers, we + // must set STEREO_BOTH before it. Otherwise + // it only clear LEFT or RIGHT buffer unless + // this is invoke twice for each buffer. + gc.clear(); + } + + gc.setStereoMode(GraphicsContext3D.STEREO_LEFT); + renderLeft(); + + gc.setStereoMode(GraphicsContext3D.STEREO_RIGHT); + renderRight(); + } else { + gc.clear(); + renderLeft(); + } + + // This swap both left and right buffers so + // there is no need to set STEREO_BOTH before it + canvas.swap(); + + // Be polite to other threads ! + Thread.yield(); + } + } + + + public PureImmediateStereo() { + } + + // + // init: create the canvas, stop the renderer, + // create the universe, and start the drawing thread. + // + public void init() { + setLayout(new BorderLayout()); + + // Preferred to use Stereo + GraphicsConfigTemplate3D gct = new GraphicsConfigTemplate3D(); + gct.setStereo(GraphicsConfigTemplate3D.PREFERRED); + + GraphicsConfiguration config = + GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(gct); + + canvas = new Canvas3D(config); + Map map = canvas.queryProperties(); + + stereoSupport = canvas.getStereoAvailable(); + + if (stereoSupport) { + System.out.println("This machine support stereo, you should see a red cone on the left and green cone on the right."); + // User can overide the above default behavior using + // java3d property. + String str = System.getProperty("j3d.sharedstereozbuffer", + defaultSharedStereoZbuffer); + sharedStereoZbuffer = (new Boolean(str)).booleanValue(); + } else { + System.out.println("Stereo is not support, you should only see the left red cone."); + } + + if (!canvas.getDoubleBufferAvailable()) { + System.out.println("Double buffer is not support !"); + } + + // we must stop the Renderer in PureImmediate mode + canvas.stopRenderer(); + add("Center", canvas); + + // Create the universe and viewing branch + u = new SimpleUniverse(canvas); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + // Start a new thread that will continuously render + (new Thread(this)).start(); + } + + // Cleanup all Java3D threads and memory when this applet exit + public void destroy() { + u.cleanup(); + } + + // + // The following allows PureImmediateStereo to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new PureImmediateStereo(), 512, 256); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/read_raster/ReadRaster.java b/src/classes/org/jdesktop/j3d/examples/read_raster/ReadRaster.java new file mode 100644 index 0000000..a6be8f3 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/read_raster/ReadRaster.java @@ -0,0 +1,224 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.read_raster; + +import java.applet.Applet; +import java.awt.BorderLayout; +import java.awt.event.*; +import java.awt.image.DataBufferInt; +import java.awt.image.BufferedImage; +import java.awt.GraphicsConfiguration; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; + +public class ReadRaster extends Applet { + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph(BufferedImage bImage, + Raster readRaster) { + + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Raster shape. Add it to the root of the subgraph + + ImageComponent2D drawImageComponent = new ImageComponent2D( + ImageComponent.FORMAT_RGB, bImage); + + Raster drawRaster= new Raster(new Point3f(0.0f, 0.0f, 0.0f), + Raster.RASTER_COLOR, 0, 0, bImage.getWidth(), + bImage.getHeight(), drawImageComponent, null); + Shape3D shape = new Shape3D(drawRaster); + drawRaster.setCapability(Raster.ALLOW_IMAGE_WRITE); + objRoot.addChild(shape); + + // Ceate the transform greup node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + + TransformGroup cubeScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setTranslation(new Vector3d(-0.5, 0.5, 0.0)); + cubeScale.setTransform(t3d); + + cubeScale.addChild(objTrans); + objRoot.addChild(cubeScale); + + // Create a simple shape leaf node, add it to the scene graph. + objTrans.addChild(new ColorCube(0.3)); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into + // the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + myRotationInterpolator rotator = + new myRotationInterpolator(drawRaster, readRaster, + rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + + // Have Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public ReadRaster() { + } + + public void init() { + + int width = 128; + int height = 128; + + ImageComponent2D readImageComponent = new ImageComponent2D( + ImageComponent.FORMAT_RGB, width, height); + + Raster readRaster = new Raster(new Point3f(0.0f,0.0f,0.0f), + Raster.RASTER_COLOR, 0, 0, width, + height, readImageComponent, null); + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new myCanvas3D(config, readRaster); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BufferedImage bImage = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + + BranchGroup scene = createSceneGraph(bImage, readRaster); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows ReadRaster to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new ReadRaster(), 256, 256); + } +} + + +class myCanvas3D extends Canvas3D { + + Raster readRaster; + GraphicsContext3D gc; + + public myCanvas3D(GraphicsConfiguration graphicsConfiguration, + Raster readRaster) { + + super(graphicsConfiguration); + this.readRaster = readRaster; + gc = getGraphicsContext3D(); + } + + public void postSwap() { + super.postSwap(); + synchronized(readRaster) { + gc.readRaster(readRaster); + } + } +} + + +class myRotationInterpolator extends RotationInterpolator { + Point3f wPos = new Point3f(0.025f, -0.025f, 0.0f); + Raster drawRaster; + Raster readRaster; + BufferedImage bImage; + ImageComponent2D newImageComponent; + + public myRotationInterpolator(Raster drawRaster, Raster readRaster, + Alpha alpha, + TransformGroup target, + Transform3D axisOfRotation, + float minimumAngle, + float maximumAngle) { + + super(alpha, target, axisOfRotation, minimumAngle, maximumAngle); + this.drawRaster = drawRaster; + this.readRaster = readRaster; + } + + public void processStimulus(Enumeration criteria) { + + synchronized(readRaster) { + bImage = readRaster.getImage().getImage(); + } + newImageComponent = new ImageComponent2D(ImageComponent.FORMAT_RGB, + bImage); + drawRaster.setImage(newImageComponent); + super.processStimulus(criteria); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/sound/AudioBehaviorMoveOne.java b/src/classes/org/jdesktop/j3d/examples/sound/AudioBehaviorMoveOne.java new file mode 100644 index 0000000..e5fc463 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/sound/AudioBehaviorMoveOne.java @@ -0,0 +1,106 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.sound; + +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; + +// User defined audio behavior class +public class AudioBehaviorMoveOne extends Behavior { + WakeupOnElapsedTime wt; + WakeupOnBehaviorPost wp; + PointSound psound = new PointSound(); + static int WAKEUP_SOUND = 0; + long dur; + // long time; + // long lastTime = -1; + boolean first_loop = true; + String fileName; + + // Override Behavior's initialize method to setup wakeup criteria + public void initialize() { + MediaContainer sample = new MediaContainer(); + sample.setCapability(MediaContainer.ALLOW_URL_WRITE); + sample.setCapability(MediaContainer.ALLOW_URL_READ); + sample.setURLString(fileName); + psound.setSoundData(sample); + // exaggerate the sound position now that viewPlatform + // tranform is taken into account + Point3f soundPos = new Point3f(-20.0f, 0.0f, 0.0f); + psound.setPosition(soundPos); + WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000); + wakeupOn(wp); + } + + // Override Behavior's stimulus method to handle the event + public void processStimulus(Enumeration criteria) { + // time = System.currentTimeMillis(); + if (first_loop) { + first_loop = false; + dur = psound.getDuration(); + if (dur == Sound.DURATION_UNKNOWN) + dur = 2000; // Force iterations every 2 seconds + // System.out.println(" sound duration time " + dur); + wt = new WakeupOnElapsedTime(dur); + } + else { + // System.out.println(" time between setEnables calls "+ + // (time - lastTime)); + psound.setEnable(false) ; + } + psound.setEnable(true); + // lastTime = time; + wakeupOn(wt); + } + + // + // Constructor for rotation behavior. Parameter: front and back Sound nodes + // + public AudioBehaviorMoveOne(PointSound psound, String filename) { + this.psound = psound; + this.fileName = filename; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/sound/AudioReverberate.java b/src/classes/org/jdesktop/j3d/examples/sound/AudioReverberate.java new file mode 100644 index 0000000..1d83702 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/sound/AudioReverberate.java @@ -0,0 +1,171 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.sound; + +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; + +/* + * Pick the JavaSound reverb type that matches the input parameters + * as best as possible. + * + * Hae Reverb Types Size Persistance Delay + * ================ ----------- ------------ ----------- + * 1 None (dry) + * 2 "Closet" very small very short <.5 fast smooth + * 3 "Garage" med. large medium 1.0 medium + * 4 "Acoustic Lab" med. small short .5 med. fast + * 5 "Cavern" large long >2.0 very slow + * 6 "Dungeon" medium med. long 1.5 med. slow + * + * + * Order is NOT controllable, nor does it have a natural parallel. + * For this reason Order and Reflection are tied together as to + * affect 'Decay Speed'. This speed paired with the size of the + * space implied by the Delay parameter determine the JavaSound + * Reverb type that is set: + * + * | Short: Long: + * Speed | Coeff <= 0.9 Coeff > 0.9 + * Size | Order <= 8 Order > 8 + * --------------------------------------------------------------- + * small (<100ms) | 2 "Closet" 4 "Acoustic Lab" + * medium (<500ms) | 3 "Garage" 6 "Dungeon" + * large (>500ms) | 6 "Dungeon" 5 "Cavern" + */ +// User defined audio behavior class +public class AudioReverberate extends Behavior { + WakeupOnElapsedTime wt; + WakeupOnBehaviorPost wp; + PointSound psound = new PointSound(); + AuralAttributes sScape = null; + static int WAKEUP_SOUND = 0; + long dur; + long time; + boolean firstTime = true; + String fileName; + int lCount = 0; + int loopCount = 0; + + // Override Behavior's initialize method to setup wakeup criteria + public void initialize() { + MediaContainer sample = new MediaContainer(); + sample.setCacheEnable(true); + sample.setURLString(fileName); + psound.setSoundData(sample); + Point3f soundPos = new Point3f(-23.0f, 0.0f, 0.0f); + psound.setPosition(soundPos); + psound.setLoop(3); + firstTime = true; + System.out.println("Reverb Name Size Reflect Order Delay "); + System.out.println("----------- ---- ------- ----- ----- "); + WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000); + wakeupOn(wp); + } + + // Override Behavior's stimulus method to handle the event + public void processStimulus(Enumeration criteria) { + // time = System.currentTimeMillis(); + if (firstTime) { + wt = new WakeupOnElapsedTime(10000); + firstTime = false; + } + else + psound.setEnable(false) ; + + if (++lCount > 6) + lCount = 1; + + if (lCount == 1) { + sScape.setReverbDelay(10.0f) ; + sScape.setReflectionCoefficient(0.5f) ; + sScape.setReverbOrder(5) ; + System.out.println("Closet sm 0.5 5 10.0 "); + } + else if (lCount == 2) { + sScape.setReverbDelay(10.0f) ; + sScape.setReflectionCoefficient(0.999f) ; + sScape.setReverbOrder(9) ; + System.out.println("Acoustic Lab sm 0.999 9 10.0 "); + } + else if (lCount == 3) { + sScape.setReverbDelay(200.0f) ; + sScape.setReflectionCoefficient(0.4f) ; + sScape.setReverbOrder(3) ; + System.out.println("Garage med 0.4 3 200.0 "); + } + else if (lCount == 4) { + sScape.setReverbDelay(200.0f) ; + sScape.setReflectionCoefficient(0.99f) ; + sScape.setReverbOrder(10) ; + System.out.println("Dungeon med 0.99 10 200.0 "); + } + else if (lCount == 5) { + sScape.setReverbDelay(600.0f) ; + sScape.setReflectionCoefficient(0.33f) ; + sScape.setReverbOrder(7) ; + System.out.println("Dungeon lrg 0.33 7 600.0 "); + } + else if (lCount == 6) { + sScape.setReverbDelay(600.0f) ; + sScape.setReflectionCoefficient(1.0f) ; + sScape.setReverbOrder(20) ; + System.out.println("Cavern lrg 1.0 20 600.0 "); + } + psound.setEnable(true); + wakeupOn(wt); + } + + // + // Constructor for rotation behavior. Parameter: front and back Sound nodes + // + public AudioReverberate(PointSound psound, String filename, + AuralAttributes sscape) { + this.psound = psound; + this.fileName = filename; + this.sScape = sscape; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/sound/MoveAppBoundingLeaf.java b/src/classes/org/jdesktop/j3d/examples/sound/MoveAppBoundingLeaf.java new file mode 100644 index 0000000..7de3b46 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/sound/MoveAppBoundingLeaf.java @@ -0,0 +1,389 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.sound; + +/* + * This Java3D program: + * Creates an instance of the JavaSoundMixer AudioDevice, initializing it + * and attaching it to the PhysicalEnvironment with a special version + * of UniverseBuilder (UniverseBuildJS). + * Creates one Point sound sources. + * Creates two Soundscapes with their own aural attributes. Each + * of these Soundscapes defines its own bounding leaf region. + * Creates and executes a custom behavior (AudioBehaviorMoveOne) that + * starts sound playing and transforms the AuralAttribute positions + * by modifying the TransformGroup that contains both soundscape + * nodes. + * Usage: java MoveAppBoundingLeaf [ URLpath [ name ]] + * + * The first optional command line parameter is the URL path to directory + * containing: + * (1) the files that will be named on the command line, or + * (2) the javaone/data/sounds directory that contains the default files + * If not given the default path is: + * file:/net/java3d/export/java3d/javaone/data/sounds + * NOTE: This default path is only valid on Solaris Eng Menlo Park network. + * A path must be supplied if sound files to be used are in a different + * directory location. + * NOTE: When running on Java3D Menlo Park Test WinTel platform path should + * be set to + * file:/java3d/export/java3d/javaone/data/sounds + * + * The second thru fourth optional command line parameters are sound file names + * If not given the default file name is: + * unicycle_close.au + */ + +import java.applet.Applet; +import java.net.URL; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.universe.*; +import java.io.File; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class MoveAppBoundingLeaf extends Applet { + + // File name of sound sample + private static int filenamesGiven = 0; + private static URL[] url = new URL[1]; + private static String[] filename = new String[1]; + private static String path = null; + private static boolean filenamesSet = false; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the subgraph + BranchGroup objRoot = new BranchGroup(); + + // Create the transform group node and initialize it to the identity. + // Enable the TRANSFORM_WRITE capability so that our behavior code + // can modify it at runtime. Add it to the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node and add it into the scene graph. + objTrans.addChild(new ColorCube(0.7)); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 20000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator = + new RotationInterpolator(rotation, + objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + // + // Create a sound node and add it to the scene graph + // + PointSound sound = new PointSound(); + sound.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE); + sound.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE); + sound.setCapability(PointSound.ALLOW_RELEASE_WRITE); + sound.setCapability(PointSound.ALLOW_DURATION_READ); + sound.setCapability(PointSound.ALLOW_IS_PLAYING_READ); + sound.setCapability(PointSound.ALLOW_POSITION_WRITE); + sound.setCapability(PointSound.ALLOW_LOOP_WRITE); + + BoundingSphere soundBounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + sound.setSchedulingBounds(soundBounds); + objTrans.addChild(sound); + + /* + * Spheres denoting aural attribute regions + */ + TransformGroup objTransChild1 = new TransformGroup(); + TransformGroup objTransChild2 = new TransformGroup(); + objTransChild1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTransChild2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + Transform3D translate1 = new Transform3D(); + Transform3D translate2 = new Transform3D(); + Vector3f vector1 = new Vector3f( 2.0f, 0.0f, 0.0f); + Vector3f vector2 = new Vector3f(-2.0f, 0.0f, 0.0f); + translate1.setTranslation(vector1); + translate2.setTranslation(vector2); + objTransChild1.setTransform(translate1); + objTransChild2.setTransform(translate2); + Sphere sphere1 = new Sphere(0.42f); + Sphere sphere2 = new Sphere(0.38f); + + Appearance app = new Appearance(); + app.setCapability( Appearance.ALLOW_POLYGON_ATTRIBUTES_WRITE ); + sphere1.setAppearance( app ); + sphere2.setAppearance( app ); + objTransChild1.addChild(sphere1); + objTransChild2.addChild(sphere2); + + objTrans.addChild(objTransChild1); + objTrans.addChild(objTransChild2); + /** + * Define Soundscapes/AuralAttributes + */ + // First Aural Attributes + Point2f[] distanceFilter = new Point2f[2]; + distanceFilter[0] = new Point2f(6.0f, 6000f); + distanceFilter[1] = new Point2f(17.0f, 700f); + AuralAttributes attributes = new AuralAttributes(1.0f, 2.0f, 0.3f, + 4.0f, 5, distanceFilter, 0.8f, 0.0f); + attributes.setReverbDelay(90.0f) ; + attributes.setReflectionCoefficient(0.999f) ; + attributes.setReverbOrder(9) ; + + // SoundScape + BoundingSphere bounds1 = + new BoundingSphere(new Point3d(2.0,0.0,0.0), 3.5); + + BoundingLeaf sScapeBounds1 = new BoundingLeaf(bounds1); + Soundscape soundScape = new Soundscape(null, attributes); + soundScape.setApplicationBoundingLeaf(sScapeBounds1); + /** addChild of BoundingLeaf as well**/ + objTrans.addChild(sScapeBounds1); + + AuralAttributes queryAttribs = new AuralAttributes(); + if (queryAttribs == null) + System.out.println(" new AuralAttributes returned NULL"); + // else + // System.out.println(" new AuralAttributes returned " + queryAttribs); + queryAttribs = soundScape.getAuralAttributes(); + if (queryAttribs == null) + System.out.println("getAuralAttributes returned NULL"); + // else + // System.out.println("AuralAttributes for Soundscape 1:"); + float tmpFloat = queryAttribs.getAttributeGain(); + // System.out.println(" Gain = " + tmpFloat); + tmpFloat = queryAttribs.getRolloff(); + // System.out.println(" Rolloff = " + tmpFloat); + tmpFloat = queryAttribs.getReflectionCoefficient(); + // System.out.println(" Reflection Coeff = " + tmpFloat); + tmpFloat = queryAttribs.getReverbDelay(); + // System.out.println(" Delay = " + tmpFloat); + int tmpInt = queryAttribs.getReverbOrder(); + // System.out.println(" Order = " + tmpInt); + int length = queryAttribs.getDistanceFilterLength(); + // System.out.println(" Filter length = " + length); + Point2f[] tmpPoint = new Point2f[length]; + tmpPoint = new Point2f[length]; + for (int i=0; i< length; i++) + tmpPoint[i] = new Point2f(); + queryAttribs.getDistanceFilter(tmpPoint); + // for (int i=0; i< length; i++) + // System.out.println(" Distance Filter = (" + tmpPoint[i].x + + // ", " + tmpPoint[i].y + ")" ); + tmpFloat = queryAttribs.getFrequencyScaleFactor(); + // System.out.println(" Freq scalefactor = " + tmpFloat); + tmpFloat = queryAttribs.getVelocityScaleFactor(); + // System.out.println(" Velocity scalefactor= " + tmpFloat); + objTrans.addChild(soundScape); + + // System.out.println("SoundScape2**********************************"); + Soundscape soundScape2 = new Soundscape(); + distanceFilter = new Point2f[2]; + distanceFilter[0] = new Point2f(2.0f, 20000.0f); + distanceFilter[1] = new Point2f(20.0f, 2000.0f); + AuralAttributes attributes2 = new AuralAttributes(); + attributes2.setAttributeGain(1.2f); + attributes2.setRolloff(2.2f); + attributes2.setReverbDelay(1313.0f) ; + attributes2.setReflectionCoefficient(1.0f) ; + attributes2.setReverbOrder(15) ; + distanceFilter[0] = new Point2f(5.0f, 15000.0f); + distanceFilter[1] = new Point2f(15.0f, 500.0f); + attributes2.setDistanceFilter(distanceFilter); + attributes2.setFrequencyScaleFactor(0.8f); + attributes2.setVelocityScaleFactor(0.0f); + BoundingSphere bounds2 = + new BoundingSphere(new Point3d(-2.0,0.0,0.0), 0.38); + BoundingLeaf sScapeBounds2 = new BoundingLeaf(bounds2); + soundScape2.setApplicationBoundingLeaf(sScapeBounds2); + // set BoundingLeaf as a child of transform node + objTrans.addChild(sScapeBounds2); + soundScape2.setAuralAttributes(attributes2); + + queryAttribs = soundScape2.getAuralAttributes(); + if (queryAttribs == null) + System.out.println(" new AuralAttributes returned NULL"); + // else + // System.out.println(" new AuralAttributes returned " + queryAttribs); + // System.out.println("AuralAttributes for Soundscape 2:"); + tmpFloat = queryAttribs.getAttributeGain(); + // System.out.println(" Gain = " + tmpFloat); + tmpFloat = queryAttribs.getRolloff(); + // System.out.println(" Rolloff = " + tmpFloat); + tmpFloat = queryAttribs.getReflectionCoefficient(); + // System.out.println(" Reflection Coeff = " + tmpFloat); + tmpFloat = queryAttribs.getReverbDelay(); + // System.out.println(" Delay = " + tmpFloat); + tmpInt = queryAttribs.getReverbOrder(); + // System.out.println(" Order = " + tmpInt); + length = queryAttribs.getDistanceFilterLength(); + // System.out.println(" Filter length = " + length); + tmpPoint = new Point2f[length]; + for (int i=0; i< length; i++) + tmpPoint[i] = new Point2f(); + queryAttribs.getDistanceFilter(tmpPoint); + // for (int i=0; i< length; i++) + // System.out.println(" Distance Filter = (" + tmpPoint[i].x + + // ", " + tmpPoint[i].y + ")" ); + tmpFloat = queryAttribs.getFrequencyScaleFactor(); + // System.out.println(" Freq scalefactor = " + tmpFloat); + tmpFloat = queryAttribs.getVelocityScaleFactor(); + // System.out.println(" Velocity scalefactor= " + tmpFloat); + objTrans.addChild(soundScape2); + + // + // Create a new Behavior object that will play the sound + // + AudioBehaviorMoveOne player = new AudioBehaviorMoveOne(sound, + filename[0]); + player.setSchedulingBounds(soundBounds); + objTrans.addChild(player); + + return objRoot; + } + + public MoveAppBoundingLeaf() { + } + + public void init() { + if (!filenamesSet) { + // path is null if started from applet + if (path == null) { + path = getCodeBase().toString(); + } + + /* + * append given file name to given URL path + */ + if (filenamesGiven > 0) { + filename[0] = new String(path + "/" + filename[0]); + } + else { + // fill in default file names if all three not given + filename[0] = new String(path + "/techno_machine.au"); + } + filenamesSet = true; + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + /* + * Change filenames into URLs + */ + String substr = filename[0].substring(0,4); + try { + url[0] = new URL(filename[0]); + } + catch (Exception e) { + return; + } + /* + * Create a simple scene and attach it to the virtual universe + */ + u = new SimpleUniverse(c); + AudioDevice audioDev = u.getViewer().createAudioDevice(); + BranchGroup scene = createSceneGraph(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows AuralAttributes to be run as an application + // as well as an applet + // + public static void main(String[] args) { + if (args.length > 0) { + if ( (args[0].startsWith("file"+File.pathSeparator)) || + (args[0].startsWith("http"+File.pathSeparator)) ) { + path = args[0]; + } + else { + path = "file:" + args[0]; + } + } + else { + path = "file:."; + } + + if (args.length > 1) { + filename[0] = args[1]; + if (filename[0] != null) { + filenamesGiven++ ; + } + } + + new MainFrame(new MoveAppBoundingLeaf(), 256, 256); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/sound/ReverberateSound.java b/src/classes/org/jdesktop/j3d/examples/sound/ReverberateSound.java new file mode 100644 index 0000000..ad6a2e3 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/sound/ReverberateSound.java @@ -0,0 +1,222 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.sound; + +/* + * ReverberateSound + * + * Same as MoveSound except this calls UniverseBuilderJS to use the + * JavaSoundMixer AudioDevice rather than the HolosketchMixer device. + * + * NOTE: To run this anywhere but the Solaris Eng Menlo Park network + * the URL path must be set to the java3d/javaone directory. + */ + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import java.io.File; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class ReverberateSound extends Applet { + + // File name of sound sample + private static String[] filename = new String[1]; + private static String path = null; + private static int filenamesGiven = 0; + private static boolean filenamesSet = false; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the subgraph + BranchGroup objRoot = new BranchGroup(); + + // Create the transform group node and initialize it to the identity. + // Enable the TRANSFORM_WRITE capability so that our behavior code + // can modify it at runtime. Add it to the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node and add it into the scene graph. + objTrans.addChild(new ColorCube(0.4)); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 20000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator = + new RotationInterpolator(rotation, + objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + + // + // Create an AuralAttribute with reverb params set + // + Soundscape soundScape2 = new Soundscape(); + AuralAttributes attributes2 = new AuralAttributes(); + attributes2.setReverbOrder(6); + attributes2.setCapability(AuralAttributes.ALLOW_REVERB_ORDER_WRITE); + attributes2.setCapability(AuralAttributes.ALLOW_REVERB_DELAY_WRITE); + attributes2.setCapability(AuralAttributes.ALLOW_REFLECTION_COEFFICIENT_WRITE); + soundScape2.setApplicationBounds(bounds); + soundScape2.setAuralAttributes(attributes2); + objRoot.addChild(soundScape2); + + // + // Create a sound node and add it to the scene graph + // + PointSound sound = new PointSound(); + sound.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound.setCapability(PointSound.ALLOW_DURATION_READ); + sound.setCapability(PointSound.ALLOW_POSITION_WRITE); + sound.setCapability(PointSound.ALLOW_LOOP_WRITE); + sound.setSchedulingBounds(bounds); + + objTrans.addChild(sound); + // + // Create a new Behavior object that will play the sound + // + AudioReverberate player = new AudioReverberate(sound, filename[0], + attributes2); + player.setSchedulingBounds(bounds); + objTrans.addChild(player); + + + return objRoot; + } + + public ReverberateSound() { + } + + public void init() { + if (!filenamesSet) { + // path is null if started from applet + if (path == null) { + // the path for an applet + path = getCodeBase().toString(); + } + + /* + * append given file name to given URL path + */ + if (filenamesGiven > 0) { + filename[0] = new String(path + "/" + filename[0]); + } + else { + // fill in default file names if all three not given + filename[0] = new String(path + "/hello_universe.au"); + } + filenamesSet = true; + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + /* + * Create a simple scene and attach it to the virtual universe + */ + u = new SimpleUniverse(c); + AudioDevice audioDev = u.getViewer().createAudioDevice(); + BranchGroup scene = createSceneGraph(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows ReverberateSound to be run as an application + // as well as an applet + // + public static void main(String[] args) { + if (args.length > 0) { + if ( (args[0].startsWith("file"+File.pathSeparator)) || + (args[0].startsWith("http"+File.pathSeparator)) ) { + path = args[0]; + } + else { + path = "file:" + args[0]; + } + } + else { + path = "file:."; + } + + if (args.length > 1) { + filename[0] = args[1]; + if (filename[0] != null) { + filenamesGiven++ ; + } + } + + new MainFrame(new ReverberateSound(), 256, 256); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/sound/SimpleSounds.java b/src/classes/org/jdesktop/j3d/examples/sound/SimpleSounds.java new file mode 100644 index 0000000..d7c8c49 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/sound/SimpleSounds.java @@ -0,0 +1,294 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.sound; + +import java.applet.Applet; +import java.net.URL; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.ColorCube; +import com.sun.j3d.utils.universe.*; +import java.io.File; +import java.security.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/* + * This Java3D program: + * Creates an instance of the JavaSoundMixer AudioDevice, initializing it + * and attaching it to the PhysicalEnvironment by using + * SimpleUniverse. + * Creates one cached Background and two cached Point sound sources. + * Creates and executes a custom behavior (SimpleSoundsBehavior) that + * starts the sound playing and transforms the PointSound source + * by modifying the TransformGroup that contains the Sound nodes. + * + * Usage: + * java SimpleSounds [URLpath [name1 [name2 [name2]]]] + * + * The first optional command line parameter is the URL path to directory + * containing "file:" or "http:" and then directory path string. + * If you are using the suppled default sound files in the same directory + * as this test program then only the URLpath need be supplied on the + * command line. + * If this parameter is not included then the current path to the directory + * this program is running in is used for an application + * and the codebase is used for an applet. + * The second thru fourth optional command line parameters are sound file names + * If not given, the default file names are: + * techno_machine.au + * hello_universe.au + * roar.au + * that correspond to the 3 'voice' quality, 8-bit, u-law, 8-kHz samples + * included in the same directory as this test program. + * + * Java Sound engine has been advertised to support the following 8- and 16- + * bit, linear and u-law, mono and stereo sound sample file formats: AU, + * AIFF, WAV, and PCM. Non-cached MIDI and RMF files are also supported. + * Neither compressed formats (DVI, GSM, MOD) nor A-law formated files are + * supported at this time, but they will be converted. + */ + +public class SimpleSounds extends Applet { + + // File name of sound sample + private static int filenamesGiven = 0; + private static URL[] url = new URL[3]; + private static String[] filename = new String[3]; + private static String path = null; + private static boolean filenamesSet = false; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the subgraph + BranchGroup objRoot = new BranchGroup(); + + // Create the transform group node and initialize it to the identity. + // Enable the TRANSFORM_WRITE capability so that our behavior code + // can modify it at runtime. Add it to the root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node and add it into the scene graph. + objTrans.addChild(new ColorCube(0.4)); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotation = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 20000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator = + new RotationInterpolator(rotation, + objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + /* + * Create a sound node and add it to the scene graph + */ + BackgroundSound sound1 = new BackgroundSound(); + PointSound sound2 = new PointSound(); + PointSound sound3 = new PointSound(); + sound1.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound1.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound1.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound1.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE); + sound1.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE); + sound1.setCapability(PointSound.ALLOW_RELEASE_WRITE); + sound1.setCapability(PointSound.ALLOW_DURATION_READ); + sound1.setCapability(PointSound.ALLOW_IS_PLAYING_READ); + sound1.setCapability(PointSound.ALLOW_LOOP_WRITE); + sound2.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound2.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound2.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound2.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE); + sound2.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE); + sound2.setCapability(PointSound.ALLOW_RELEASE_WRITE); + sound2.setCapability(PointSound.ALLOW_DURATION_READ); + sound2.setCapability(PointSound.ALLOW_IS_PLAYING_READ); + sound2.setCapability(PointSound.ALLOW_POSITION_WRITE); + sound2.setCapability(PointSound.ALLOW_LOOP_WRITE); + sound3.setCapability(PointSound.ALLOW_ENABLE_WRITE); + sound3.setCapability(PointSound.ALLOW_INITIAL_GAIN_WRITE); + sound3.setCapability(PointSound.ALLOW_SOUND_DATA_WRITE); + sound3.setCapability(PointSound.ALLOW_SCHEDULING_BOUNDS_WRITE); + sound3.setCapability(PointSound.ALLOW_CONT_PLAY_WRITE); + sound3.setCapability(PointSound.ALLOW_RELEASE_WRITE); + sound3.setCapability(PointSound.ALLOW_DURATION_READ); + sound3.setCapability(PointSound.ALLOW_IS_PLAYING_READ); + sound3.setCapability(PointSound.ALLOW_POSITION_WRITE); + + BoundingSphere soundBounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + sound1.setSchedulingBounds(soundBounds); + sound2.setSchedulingBounds(soundBounds); + sound3.setSchedulingBounds(soundBounds); + objTrans.addChild(sound1); + objTrans.addChild(sound2); + objTrans.addChild(sound3); + + + /* + * Create a new Behavior object that will play the sound + */ + SimpleSoundsBehavior player = new SimpleSoundsBehavior( + sound1, sound2, sound3, + url[0], url[1], url[2], soundBounds); + player.setSchedulingBounds(soundBounds); + objTrans.addChild(player); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public SimpleSounds() { + } + + public void init() { + if (!filenamesSet) { + // path is null if started from appletviewer/browser + if (path == null) { + // the path for an applet + path = getCodeBase().toString(); + } + int j; + /* + * append given file name to given URL path + */ + for (j=0; j 0) { + if ( (args[0].startsWith("file"+File.pathSeparator)) || + (args[0].startsWith("http"+File.pathSeparator)) ) { + path = args[0]; + } + else { + path = "file:" + args[0]; + } + } + else { + path = "file:."; + } + + for (int i=0; i<3; i++) { + if (args.length > (i+1)) { + filename[i] = args[i+1]; + if (filename[i] != null) { + filenamesGiven++ ; + } + } + else + break; + } + new MainFrame(new SimpleSounds(), args, 256, 256); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java b/src/classes/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java new file mode 100644 index 0000000..862881f --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/sound/SimpleSoundsBehavior.java @@ -0,0 +1,179 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.sound; + +import javax.media.j3d.*; +import javax.vecmath.*; +import java.net.URL; +import java.util.Enumeration; + +// User defined audio behavior class +public class SimpleSoundsBehavior extends Behavior { + WakeupOnElapsedTime wt; + WakeupOnBehaviorPost wp; + BackgroundSound sound1 = new BackgroundSound(); + PointSound sound2 = new PointSound(); + PointSound sound3 = new PointSound(); + static int WAKEUP_SOUND = 0; + int soundIndex = 0; + URL URLName1; + URL URLName2; + URL URLName3; + BoundingSphere bounds; + + // Override Behavior's initialize method to setup wakeup criteria + public void initialize() { + MediaContainer sample1 = new MediaContainer(); + MediaContainer sample2 = new MediaContainer(); + MediaContainer sample3 = new MediaContainer(); + sample1.setCapability(MediaContainer.ALLOW_URL_WRITE); + sample1.setCapability(MediaContainer.ALLOW_URL_READ); + sample1.setURLObject(URLName1); + //sample1.setCacheEnable(false); + sound1.setLoop(0); + sound1.setContinuousEnable(false); + sound1.setReleaseEnable(false); + sound1.setSoundData(sample1); + sound1.setInitialGain(0.7f); + sample2.setCapability(MediaContainer.ALLOW_URL_WRITE); + sample2.setCapability(MediaContainer.ALLOW_URL_READ); + sample2.setURLObject(URLName2); + sound2.setLoop(Sound.INFINITE_LOOPS); + sound2.setContinuousEnable(false); + sound2.setReleaseEnable(false); + sound2.setSoundData(sample2); + sound2.setInitialGain(2.0f); + Point3f sound2Pos = new Point3f(-30.0f, 0.0f, 0.0f); + sound2.setPosition(sound2Pos); + sample3.setCapability(MediaContainer.ALLOW_URL_WRITE); + sample3.setCapability(MediaContainer.ALLOW_URL_READ); + sample3.setURLObject(URLName3); + sound3.setContinuousEnable(false); + sound3.setReleaseEnable(false); + sound3.setSoundData(sample3); + sound3.setInitialGain(4.0f); + Point3f sound3Pos = new Point3f(30.0f, 0.0f, 0.0f); + sound3.setPosition(sound3Pos); + + wt = new WakeupOnElapsedTime(2000); + WakeupOnElapsedTime wp = new WakeupOnElapsedTime(5000); + wakeupOn(wp); + } + + // Override Behavior's stimulus method to handle the event + public void processStimulus(Enumeration criteria) { + + switch (soundIndex) + { + // Active + case 0: + // System.out.println("****Enable First Sound"); + sound1.setEnable(true); + wakeupOn(wt); + break; + case 1: + // System.out.println("********Enable Second Sound"); + sound2.setEnable(true); + wakeupOn(wt); + break; + case 2: + case 4: + case 6: + case 8: + case 10: + // System.out.println("************Enable Third Sound"); + sound3.setEnable(true); + wakeupOn(wt); + break; + case 3: + case 5: + case 7: + case 9: + // System.out.println("************Disable Third Sound"); + sound3.setEnable(false); + wakeupOn(wt); + break; + + case 11: + // System.out.println("********Disable Second Sound"); + sound2.setEnable(false) ; + wakeupOn(wt); + break; + case 12: + // System.out.println("****Disable First Sound"); + sound1.setEnable(false) ; + System.out.println("SimpleSounds: test complete"); + wt = new WakeupOnElapsedTime(400000); + wakeupOn(wt); + break; + + default: + break; + } + soundIndex++; + } + + // + // Constructor for rotation behavior. + // Parameters: sound node + // sample file name + // sound node's bounds + // + public SimpleSoundsBehavior(BackgroundSound sound1, + PointSound sound2, + PointSound sound3, + URL urlName1, + URL urlName2, + URL urlName3, + BoundingSphere soundBounds) { + this.sound1 = sound1; + this.sound2 = sound2; + this.sound3 = sound3; + this.URLName1 = urlName1; + this.URLName2 = urlName2; + this.URLName3 = urlName3; + this.bounds = (BoundingSphere)soundBounds.clone(); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java b/src/classes/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java new file mode 100644 index 0000000..49b3293 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/sphere_motion/SphereMotion.java @@ -0,0 +1,303 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.sphere_motion; + +import java.applet.Applet; +import java.awt.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.Sphere; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.Enumeration; + +public class SphereMotion extends Applet { + + // Constants for type of light to use + private static final int DIRECTIONAL_LIGHT = 0; + private static final int POINT_LIGHT = 1; + private static final int SPOT_LIGHT = 2; + + // Flag indicates type of lights: directional, point, or spot + // lights. This flag is set based on command line argument + private static int lightType = POINT_LIGHT; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph(SimpleUniverse u) { + Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f); + Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f); + Color3f objColor = new Color3f(0.6f, 0.6f, 0.6f); + Color3f lColor1 = new Color3f(1.0f, 0.0f, 0.0f); + Color3f lColor2 = new Color3f(0.0f, 1.0f, 0.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + + Transform3D t; + + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create a bounds for the background and lights + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // Set up the background + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + objScale.addChild(bg); + + // Create a Sphere object, generate one copy of the sphere, + // and add it into the scene graph. + Material m = new Material(objColor, eColor, objColor, sColor, 100.0f); + Appearance a = new Appearance(); + m.setLightingEnable(true); + a.setMaterial(m); + Sphere sph = new Sphere(1.0f, Sphere.GENERATE_NORMALS, 80, a); + objScale.addChild(sph); + + // Create the transform group node for the each light and initialize + // it to the identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add them to the root + // of the subgraph. + TransformGroup l1RotTrans = new TransformGroup(); + l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(l1RotTrans); + + TransformGroup l2RotTrans = new TransformGroup(); + l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objScale.addChild(l2RotTrans); + + // Create transformations for the positional lights + t = new Transform3D(); + Vector3d lPos1 = new Vector3d(0.0, 0.0, 2.0); + t.set(lPos1); + TransformGroup l1Trans = new TransformGroup(t); + l1RotTrans.addChild(l1Trans); + + t = new Transform3D(); + Vector3d lPos2 = new Vector3d(0.5, 0.8, 2.0); + t.set(lPos2); + TransformGroup l2Trans = new TransformGroup(t); + l2RotTrans.addChild(l2Trans); + + // Create Geometry for point lights + ColoringAttributes caL1 = new ColoringAttributes(); + ColoringAttributes caL2 = new ColoringAttributes(); + caL1.setColor(lColor1); + caL2.setColor(lColor2); + Appearance appL1 = new Appearance(); + Appearance appL2 = new Appearance(); + appL1.setColoringAttributes(caL1); + appL2.setColoringAttributes(caL2); + l1Trans.addChild(new Sphere(0.05f, appL1)); + l2Trans.addChild(new Sphere(0.05f, appL2)); + + // Create lights + AmbientLight aLgt = new AmbientLight(alColor); + + Light lgt1 = null; + Light lgt2 = null; + + Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f); + Point3f atten = new Point3f(1.0f, 0.0f, 0.0f); + Vector3f lDirect1 = new Vector3f(lPos1); + Vector3f lDirect2 = new Vector3f(lPos2); + lDirect1.negate(); + lDirect2.negate(); + + switch (lightType) { + case DIRECTIONAL_LIGHT: + lgt1 = new DirectionalLight(lColor1, lDirect1); + lgt2 = new DirectionalLight(lColor2, lDirect2); + break; + case POINT_LIGHT: + lgt1 = new PointLight(lColor1, lPoint, atten); + lgt2 = new PointLight(lColor2, lPoint, atten); + break; + case SPOT_LIGHT: + lgt1 = new SpotLight(lColor1, lPoint, atten, lDirect1, + 25.0f * (float)Math.PI / 180.0f, 10.0f); + lgt2 = new SpotLight(lColor2, lPoint, atten, lDirect2, + 25.0f * (float)Math.PI / 180.0f, 10.0f); + break; + } + + // Set the influencing bounds + aLgt.setInfluencingBounds(bounds); + lgt1.setInfluencingBounds(bounds); + lgt2.setInfluencingBounds(bounds); + + // Add the lights into the scene graph + objScale.addChild(aLgt); + l1Trans.addChild(lgt1); + l2Trans.addChild(lgt2); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator1 = + new RotationInterpolator(rotor1Alpha, + l1RotTrans, + yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator1.setSchedulingBounds(bounds); + l1RotTrans.addChild(rotator1); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into the + // scene graph. + Alpha rotor2Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 1000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator2 = + new RotationInterpolator(rotor2Alpha, + l2RotTrans, + yAxis, + 0.0f, 0.0f); + bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator2.setSchedulingBounds(bounds); + l2RotTrans.addChild(rotator2); + + // Create a position interpolator and attach it to the view + // platform + TransformGroup vpTrans = + u.getViewingPlatform().getViewPlatformTransform(); + Transform3D axisOfTranslation = new Transform3D(); + Alpha transAlpha = new Alpha(-1, + Alpha.INCREASING_ENABLE | + Alpha.DECREASING_ENABLE, + 0, 0, + 5000, 0, 0, + 5000, 0, 0); + axisOfTranslation.rotY(-Math.PI/2.0); + PositionInterpolator translator = + new PositionInterpolator(transAlpha, + vpTrans, + axisOfTranslation, + 2.0f, 3.5f); + translator.setSchedulingBounds(bounds); + objScale.addChild(translator); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public SphereMotion() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + u = new SimpleUniverse(c); + BranchGroup scene = createSceneGraph(u); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows SphereMotion to be run as an application + // as well as an applet + // + public static void main(String[] args) { + // Parse the Input Arguments + String usage = "Usage: java SphereMotion [-point | -spot | -dir]"; + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("-")) { + if (args[i].equals("-point")) { + System.out.println("Using point lights"); + lightType = POINT_LIGHT; + } + else if (args[i].equals("-spot")) { + System.out.println("Using spot lights"); + lightType = SPOT_LIGHT; + } + else if (args[i].equals("-dir")) { + System.out.println("Using directional lights"); + lightType = DIRECTIONAL_LIGHT; + } + else { + System.out.println(usage); + System.exit(0); + } + } + else { + System.out.println(usage); + System.exit(0); + } + } + + new MainFrame(new SphereMotion(), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java b/src/classes/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java new file mode 100644 index 0000000..1e5c965 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/spline_anim/SplineAnim.java @@ -0,0 +1,603 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.spline_anim; + +import java.io.*; +import java.applet.Applet; +import java.awt.FlowLayout; +import java.awt.*; +import java.awt.event.*; +import java.util.Hashtable; +import javax.media.j3d.*; +import javax.vecmath.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.*; +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.loaders.Scene; +import com.sun.j3d.loaders.objectfile.ObjectFile; +import com.sun.j3d.loaders.ParsingErrorException; +import com.sun.j3d.loaders.IncorrectFormatException; +import com.sun.j3d.utils.behaviors.vp.*; +import com.sun.j3d.utils.behaviors.interpolators.*; + + + +/* + * This program demonstrates the use of KBRotPosScaleSplinePathInterpolator + * in order to to do spline animation paths using Kochanek-Bartels (also + * known as TCB or Tension-Continuity-Bias ) splines. A cone red cone + * is animated along a spline path specified by 5 knot points, which + * are showns as cyan spheres. + * + * Use the left mouse button to changes orientation of scene. + * Use the middle mouse button to zoom in/out + * Use the right mouse button to pan the scene + */ +public class SplineAnim extends Applet implements ActionListener, + AdjustmentListener, + ItemListener { + + // 3D Canvas + Canvas3D canvas; + + // UI Components + Panel controlPanel; + Panel canvasPanel; + Button animateButton; + Choice interpChoice; + Scrollbar speedSlider; + Label speedLabel; + Label interpLabel; + + // Scene Graph + BoundingSphere bounds; + BranchGroup root; + BranchGroup behaviorBranch; + Transform3D sceneTransform; + TransformGroup sceneTransformGroup; + Transform3D objTransform; + TransformGroup objTransformGroup; + Transform3D lightTransform1; + Transform3D lightTransform2; + TransformGroup light1TransformGroup; + TransformGroup light2TransformGroup; + + // Key Frames & Interpolator + int duration = 5000; + Alpha animAlpha; + Transform3D yAxis; + KBKeyFrame[] linearKeyFrames = new KBKeyFrame[6]; + KBKeyFrame[] splineKeyFrames = new KBKeyFrame[6]; + KBRotPosScaleSplinePathInterpolator splineInterpolator; + KBRotPosScaleSplinePathInterpolator linearInterpolator; + + // Data: Knot positions & transform groups + Vector3f pos0 = new Vector3f(-5.0f, -5.0f, 0.0f); + Vector3f pos1 = new Vector3f(-5.0f, 5.0f, 0.0f); + Vector3f pos2 = new Vector3f( 0.0f, 5.0f, 0.0f); + Vector3f pos3 = new Vector3f( 0.0f, -5.0f, 0.0f); + Vector3f pos4 = new Vector3f( 5.0f, -5.0f, 0.0f); + Vector3f pos5 = new Vector3f( 5.0f, 5.0f, 0.0f); + TransformGroup k0TransformGroup; + TransformGroup k1TransformGroup; + TransformGroup k2TransformGroup; + TransformGroup k3TransformGroup; + TransformGroup k4TransformGroup; + TransformGroup k5TransformGroup; + + // Flags + boolean animationOn = true; + boolean linear = false; + + private SimpleUniverse u = null; + + public SplineAnim() { + } + + public void init() { + this.setLayout(new FlowLayout()); + + // Create the canvas and the UI + canvasPanel = new Panel(); + controlPanel = new Panel(); + createCanvasPanel(canvasPanel); + this.add(canvasPanel); + createControlPanel(controlPanel); + this.add(controlPanel); + + // Create the scene. + BranchGroup scene = createSceneGraph(); + + // Setup keyframe data for our animation + setupSplineKeyFrames (); + setupLinearKeyFrames (); + + // Setup alpha, create the interpolators and start them. We + // create both a linear and a spline interpolator and turn on + // one depending on user selection. The default is spline. + setupAnimationData (); + createInterpolators(); + startInterpolator(); + + // Add viewing platform + u = new SimpleUniverse(canvas); + + // add mouse behaviors to ViewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + viewingPlatform.setNominalViewingTransform(); + + // add orbit behavior to the ViewingPlatform + OrbitBehavior orbit = new OrbitBehavior(canvas, + OrbitBehavior.REVERSE_ALL); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + /* + * This creates the control panel which contains a choice menu to + * toggle between spline and linear interpolation, a slider to + * adjust the speed of the animation and a animation start/stop + * button. + */ + private void createControlPanel(Panel p) { + + GridBagLayout gl = new GridBagLayout(); + GridBagConstraints gbc = new GridBagConstraints(); + + p.setLayout (gl); + gbc.weightx = 100; gbc.weighty = 100; + gbc.fill = GridBagConstraints.BOTH; + + gbc.gridx = 0; gbc.gridy = 0; + gbc.gridwidth = 1; gbc.gridheight = 1; + interpLabel = new Label("Interpolation Type", Label.LEFT); + p.add(interpLabel, gbc); + + gbc.gridx = 1; gbc.gridy = 0; + gbc.gridwidth = 1; gbc.gridheight = 1; + interpChoice = new Choice(); + interpChoice.add("Spline"); + interpChoice.add("Linear"); + p.add(interpChoice, gbc); + interpChoice.addItemListener (this); + + gbc.gridx = 0; gbc.gridy = 2; + gbc.gridwidth = 2; gbc.gridheight = 1; + speedSlider = new Scrollbar(Scrollbar.HORIZONTAL, 2, 1, 0, 11); + speedSlider.setUnitIncrement (1); + p.add(speedSlider, gbc); + speedSlider.addAdjustmentListener(this); + + gbc.gridx = 0; gbc.gridy = 3; + gbc.gridwidth = 2; gbc.gridheight = 1; + speedLabel = new Label(" - Animation Speed +", Label.CENTER); + p.add(speedLabel, gbc); + + gbc.gridx = 0; gbc.gridy = 5; + gbc.gridwidth = 2; gbc.gridheight = 1; + animateButton = new Button("Stop Animation"); + p.add(animateButton, gbc); + animateButton.addActionListener (this); + + + } + + /* + * This creates the Java3D canvas + */ + private void createCanvasPanel(Panel p) { + + GridBagLayout gl = new GridBagLayout(); + GridBagConstraints gbc = new GridBagConstraints(); + + p.setLayout(gl); + gbc.gridx = 0; gbc.gridy = 0; + gbc.gridwidth = 5; gbc.gridheight = 5; + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + canvas = new Canvas3D(config); + canvas.setSize(490,490); + p.add(canvas,gbc); + + } + + /* + * This creates the scene with 5 knot points represented by cyan + * spheres, a cone obejct that will be transformed, and two directional + * lights + and ambient light. + */ + public BranchGroup createSceneGraph() { + + // Colors for lights and objects + Color3f aColor = new Color3f(0.2f, 0.2f, 0.2f); + Color3f eColor = new Color3f(0.0f, 0.0f, 0.0f); + Color3f sColor = new Color3f(1.0f, 1.0f, 1.0f); + Color3f coneColor = new Color3f(0.9f, 0.1f, 0.1f); + Color3f sphereColor= new Color3f(0.1f, 0.7f, 0.9f); + Color3f bgColor = new Color3f(0.0f, 0.0f, 0.0f); + Color3f lightColor = new Color3f(1.0f, 1.0f, 1.0f); + + // Root of the branch grsph + BranchGroup root = new BranchGroup(); + + // Create transforms such that all objects appears in the scene + sceneTransform = new Transform3D(); + sceneTransform.setScale(0.14f); + Transform3D yrot = new Transform3D(); + yrot.rotY(-Math.PI/5.0d); + sceneTransform.mul(yrot); + sceneTransformGroup = new TransformGroup(sceneTransform); + sceneTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + sceneTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + root.addChild(sceneTransformGroup); + + // Create bounds for the background and lights + bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0f); + + // Set up the background + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + sceneTransformGroup.addChild(bg); + + // Create the transform group node for the lights + lightTransform1 = new Transform3D(); + lightTransform2 = new Transform3D(); + Vector3d lightPos1 = new Vector3d(0.0, 0.0, 2.0); + Vector3d lightPos2 = new Vector3d(1.0, 0.0, -2.0); + lightTransform1.set(lightPos1); + lightTransform2.set(lightPos2); + light1TransformGroup = new TransformGroup(lightTransform1); + light2TransformGroup = new TransformGroup(lightTransform2); + sceneTransformGroup.addChild(light1TransformGroup); + sceneTransformGroup.addChild(light2TransformGroup); + + // Create lights + AmbientLight ambLight = new AmbientLight(aColor); + Light dirLight1; + Light dirLight2; + + Vector3f lightDir1 = new Vector3f(lightPos1); + Vector3f lightDir2 = new Vector3f(lightPos2); + lightDir1.negate(); + lightDir2.negate(); + dirLight1 = new DirectionalLight(lightColor, lightDir1); + dirLight2 = new DirectionalLight(lightColor, lightDir2); + + // Set the influencing bounds + ambLight.setInfluencingBounds(bounds); + dirLight1.setInfluencingBounds(bounds); + dirLight2.setInfluencingBounds(bounds); + + // Add the lights into the scene graph + sceneTransformGroup.addChild(ambLight); + sceneTransformGroup.addChild(dirLight1); + sceneTransformGroup.addChild(dirLight2); + + // Create a cone and add it to the scene graph. + objTransform = new Transform3D(); + objTransformGroup = new TransformGroup(objTransform); + objTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + sceneTransformGroup.addChild(objTransformGroup); + + Material m = new Material(coneColor, eColor, coneColor, sColor, 100.0f); + Appearance a = new Appearance(); + m.setLightingEnable(true); + a.setMaterial(m); + Cone cone = new Cone(0.4f, 1.0f); + cone.setAppearance(a); + objTransformGroup.addChild(cone); + + // Create transform groups for each knot point + // knot point 0 + Transform3D t3dKnot = new Transform3D(); + t3dKnot.set (pos0); + TransformGroup k0TransformGroup = new TransformGroup(t3dKnot); + sceneTransformGroup.addChild(k0TransformGroup); + + // knot point 1 + t3dKnot = new Transform3D(); + t3dKnot.set (pos1); + TransformGroup k1TransformGroup = new TransformGroup(t3dKnot); + sceneTransformGroup.addChild(k1TransformGroup); + + // knot point 2 + t3dKnot = new Transform3D(); + t3dKnot.set (pos2); + TransformGroup k2TransformGroup = new TransformGroup(t3dKnot); + sceneTransformGroup.addChild(k2TransformGroup); + + // knot point 3 + t3dKnot = new Transform3D(); + t3dKnot.set (pos3); + TransformGroup k3TransformGroup = new TransformGroup(t3dKnot); + sceneTransformGroup.addChild(k3TransformGroup); + + // knot point 4 + t3dKnot = new Transform3D(); + t3dKnot.set (pos4); + TransformGroup k4TransformGroup = new TransformGroup(t3dKnot); + sceneTransformGroup.addChild(k4TransformGroup); + + // knot point 5 + t3dKnot = new Transform3D(); + t3dKnot.set (pos5); + TransformGroup k5TransformGroup = new TransformGroup(t3dKnot); + sceneTransformGroup.addChild(k5TransformGroup); + + // Create spheres for each knot point's transform group + ColoringAttributes sphereColorAttr = new ColoringAttributes(); + sphereColorAttr.setColor(sphereColor); + Appearance sphereAppearance = new Appearance(); + sphereAppearance.setColoringAttributes(sphereColorAttr); + k0TransformGroup.addChild(new Sphere(0.10f, sphereAppearance)); + k1TransformGroup.addChild(new Sphere(0.10f, sphereAppearance)); + k2TransformGroup.addChild(new Sphere(0.10f, sphereAppearance)); + k3TransformGroup.addChild(new Sphere(0.10f, sphereAppearance)); + k4TransformGroup.addChild(new Sphere(0.10f, sphereAppearance)); + k5TransformGroup.addChild(new Sphere(0.10f, sphereAppearance)); + + return root; + } + + /* + * This sets up the key frame data for the spline interpolator. Each knot + * point has a scale and rotation component specified. The second argument + * to KBKeyFrame (in this case 0) tells the interpolator that this is + * to be interpolated using splines. The last three arguments to + * KBKeyFrame are Tension, Continuity, and Bias components for each + * key frame. + */ + private void setupSplineKeyFrames () { + // Prepare spline keyframe data + Point3f p = new Point3f (pos0); // position + float head = (float)Math.PI/2.0f; // heading + float pitch = 0.0f; // pitch + float bank = 0.0f; // bank + Point3f s = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale + splineKeyFrames[0] = + new KBKeyFrame(0.0f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos1); + head = 0.0f; // heading + pitch = 0.0f; // pitch + bank = (float)-Math.PI/2.0f; // bank + s = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale + splineKeyFrames[1] = + new KBKeyFrame(0.2f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos2); + head = 0.0f; // heading + pitch = 0.0f; // pitch + bank = 0.0f; // bank + s = new Point3f(0.7f, 0.7f, 0.7f); // uniform scale + splineKeyFrames[2] = + new KBKeyFrame(0.4f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos3); + head = (float)Math.PI/2.0f; // heading + pitch = 0.0f; // pitch + bank = (float)Math.PI/2.0f; // bank + s = new Point3f(0.5f, 0.5f, 0.5f); // uniform scale + splineKeyFrames[3] = + new KBKeyFrame(0.6f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos4); + head = (float)-Math.PI/2.0f; // heading + pitch = (float)-Math.PI/2.0f; // pitch + bank = (float)Math.PI/2.0f; // bank + s = new Point3f(0.4f, 0.4f, 0.4f); // uniform scale + splineKeyFrames[4] = + new KBKeyFrame(0.8f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos5); + head = 0.0f; // heading + pitch = 0.0f; // pitch + bank = 0.0f; // bank + s = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale + splineKeyFrames[5] = + new KBKeyFrame(1.0f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + } + + /* + * This sets up the key frame data for the linear interpolator. Each knot + * point has a scale and rotation component specified. The second argument + * to KBKeyFrame (in this case 1) tells the interpolator that this is + * to be interpolated linearly. The last three arguments to TCBKeyFrame + * are Tension, Continuity, and Bias components for each key frame. + */ + private void setupLinearKeyFrames () { + // Prepare linear keyframe data + Point3f p = new Point3f (pos0); + float head = 0.0f; // heading + float pitch = 0.0f; // pitch + float bank = 0.0f; // bank + Point3f s = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale + linearKeyFrames[0] = + new KBKeyFrame(0.0f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos1); + linearKeyFrames[1] = + new KBKeyFrame(0.2f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos2); + linearKeyFrames[2] = + new KBKeyFrame(0.4f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos3); + linearKeyFrames[3] = + new KBKeyFrame(0.6f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos4); + linearKeyFrames[4] = + new KBKeyFrame(0.8f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + + p = new Point3f (pos5); + linearKeyFrames[5] = + new KBKeyFrame(1.0f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); + } + + + /* + * This sets up alpha for the interpolator + */ + private void setupAnimationData () { + yAxis = new Transform3D(); + animAlpha = new Alpha (-1,Alpha.INCREASING_ENABLE,0,0,duration,0,0,0,0,0); + } + + /* + * create a spline and a linear interpolator, but we will activate only + * one in startInterpolator() + */ + private void createInterpolators () { + + behaviorBranch = new BranchGroup(); + + // create spline interpolator + splineInterpolator = + new KBRotPosScaleSplinePathInterpolator(animAlpha, objTransformGroup, + yAxis, splineKeyFrames); + splineInterpolator.setSchedulingBounds(bounds); + behaviorBranch.addChild(splineInterpolator); + + // create linear interpolator + linearInterpolator = + new KBRotPosScaleSplinePathInterpolator(animAlpha, objTransformGroup, + yAxis, linearKeyFrames); + linearInterpolator.setSchedulingBounds(bounds); + behaviorBranch.addChild(linearInterpolator); + objTransformGroup.addChild(behaviorBranch); + + } + + /* + * This activates one of the interpolators depending on the state of the + * linear boolean flag which may be toggled by the user using the choice + * menu. + */ + public void startInterpolator () { + if (animationOn) { + if (linear) { + splineInterpolator.setEnable(false); + linearInterpolator.setEnable(true); + } else { + linearInterpolator.setEnable(false); + splineInterpolator.setEnable(true); + } + } + } + + + /* + * Toggle animation + */ + public void actionPerformed (ActionEvent event) { + Object source = event.getSource(); + if (source == animateButton) { + try { + // toggle animation + if (animationOn) { + animationOn = false; + splineInterpolator.setEnable(false); + linearInterpolator.setEnable(false); + animateButton.setLabel("Start Animation"); + } else { + animationOn = true; + startInterpolator(); + animateButton.setLabel("Stop Animation"); + } + } catch (Exception e) { + System.err.println ("Exception " + e); + } + } + } + + /* + * Toggle the interpolators + */ + public void itemStateChanged (ItemEvent event) { + Object source = event.getSource(); + ItemSelectable ie = event.getItemSelectable(); + if (source == interpChoice) { + try { + if (ie.getSelectedObjects()[0] == "Spline") { + linear = false; + } + if (ie.getSelectedObjects()[0] == "Linear") { + linear = true; + } + startInterpolator(); + } catch (Exception e) { + System.err.println ("Exception " + e); + } + } + } + + + /* + * Adjust the speed of the animations + */ + public void adjustmentValueChanged (AdjustmentEvent e) { + int value = e.getValue(); + duration = 6000 - (500 * value); + animAlpha.setIncreasingAlphaDuration(duration); + } + + + + public static void main(String[] args) { + Frame frame = new MainFrame(new SplineAnim(), 500, 600); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form b/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form new file mode 100644 index 0000000..591580c --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.form @@ -0,0 +1,82 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java b/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java new file mode 100644 index 0000000..cde026b --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/swing_interaction/SwingInteraction.java @@ -0,0 +1,252 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.swing_interaction; + +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.geometry.ColorCube; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.GraphicsConfiguration; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; +import java.util.Enumeration; +import javax.swing.JPopupMenu; + +/** + * Simple Java 3D test program created in NetBeans to illustrate interacting + * with a Java 3D scene graph from an Swing-based program. + */ +public class SwingInteraction extends javax.swing.JFrame { + + private SimpleUniverse univ = null; + private BranchGroup scene = null; + + private TransformGroup objTrans; + private RotateBehavior awtBehavior; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create a simple shape leaf node, add it to the scene graph. + objTrans.addChild(new ColorCube(0.4)); + + // create the RotateBehavior + awtBehavior = new RotateBehavior(objTrans); + BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), + 100.0); + awtBehavior.setSchedulingBounds(bounds); + objRoot.addChild(awtBehavior); + + return objRoot; + } + + private Canvas3D createUniverse() { + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + + univ = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + univ.getViewingPlatform().setNominalViewingTransform(); + + // Ensure at least 5 msec per frame (i.e., < 200Hz) + univ.getViewer().getView().setMinimumFrameCycleTime(5); + + return c; + } + + /** + * Creates new form SwingInteraction + */ + public SwingInteraction() { + // Initialize the GUI components + JPopupMenu.setDefaultLightWeightPopupEnabled(false); + initComponents(); + + // Create Canvas3D and SimpleUniverse; add canvas to drawing panel + Canvas3D c = createUniverse(); + drawingPanel.add(c, java.awt.BorderLayout.CENTER); + + // Create the content branch and add it to the universe + scene = createSceneGraph(); + univ.addBranchGraph(scene); + } + + /** + * Behavior class that waits for a behavior post from the AWT event handler + */ + class RotateBehavior extends Behavior { + + private TransformGroup transformGroup; + private Transform3D trans = new Transform3D(); + private WakeupCriterion criterion; + private float angle = 0.0f; + + private final int ROTATE = 1; + + // create a new RotateBehavior + RotateBehavior(TransformGroup tg) { + transformGroup = tg; + } + + // initialize behavior to wakeup on a behavior post with id = ROTATE + public void initialize() { + criterion = new WakeupOnBehaviorPost(this, ROTATE); + wakeupOn(criterion); + } + + // processStimulus to rotate the cube + public void processStimulus(Enumeration criteria) { + angle += Math.toRadians(10.0); + trans.rotY(angle); + transformGroup.setTransform(trans); + wakeupOn(criterion); + } + + // when the mouse is clicked, postId for the behavior + void rotate() { + postId(ROTATE); + } + } + + // ---------------------------------------------------------------- + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + // //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(); + }// //GEN-END:initComponents + + private void rotateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rotateButtonActionPerformed + awtBehavior.rotate(); + }//GEN-LAST:event_rotateButtonActionPerformed + + private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed + System.exit(0); + }//GEN-LAST:event_exitMenuItemActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new SwingInteraction().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel drawingPanel; + private javax.swing.JMenuItem exitMenuItem; + private javax.swing.JMenu fileMenu; + private javax.swing.JPanel guiPanel; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JButton rotateButton; + // End of variables declaration//GEN-END:variables + +} diff --git a/src/classes/org/jdesktop/j3d/examples/text2d/MoverBehavior.java b/src/classes/org/jdesktop/j3d/examples/text2d/MoverBehavior.java new file mode 100644 index 0000000..c73f5e1 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/text2d/MoverBehavior.java @@ -0,0 +1,141 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.text2d; + +import java.awt.event.*; +import java.awt.AWTEvent; +import javax.media.j3d.*; +import java.util.Enumeration; +import javax.vecmath.*; + +// Mover behavior class - used to allow viewer to move using arrow keys +class MoverBehavior extends Behavior +{ + WakeupOnAWTEvent w1 = new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED); + WakeupCriterion[] w2 = {w1}; + WakeupCondition w = new WakeupOr(w2); + TransformGroup viewTransformGroup; + double rotation = 0.0; // holds current rotation radians + + public void initialize() { + // Establish initial wakeup criteria + wakeupOn(w); + } + + + /** + * Override Behavior's stimulus method to handle the event. + */ + public void processStimulus(Enumeration criteria) { + WakeupOnAWTEvent ev; + WakeupCriterion genericEvt; + AWTEvent[] events; + + while (criteria.hasMoreElements()) { + genericEvt = (WakeupCriterion) criteria.nextElement(); + if (genericEvt instanceof WakeupOnAWTEvent) { + ev = (WakeupOnAWTEvent) genericEvt; + events = ev.getAWTEvent(); + processManualEvent(events); + } + } + // Set wakeup criteria for next time + wakeupOn(w); + } + + + /** + * Process a keyboard event to move or rotate the viewer. + */ + void processManualEvent(AWTEvent[] events) { + + for (int i = 0; i < events.length; ++i) { + if (events[i] instanceof KeyEvent) { + KeyEvent event = (KeyEvent)events[i]; + if (event.getKeyCode() == KeyEvent.VK_EQUALS) { + continue; + } + Transform3D t = new Transform3D(); + viewTransformGroup.getTransform(t); + Vector3f viewDir = new Vector3f(0f, 0f, -1f); + Vector3f translation = new Vector3f(); + t.get(translation); + t.transform(viewDir); + if (event.getKeyCode() == KeyEvent.VK_UP) { + translation.x += viewDir.x; + translation.y += viewDir.y; + translation.z += viewDir.z; + } + else if (event.getKeyCode() == KeyEvent.VK_DOWN) { + translation.x -= viewDir.x; + translation.y -= viewDir.y; + translation.z -= viewDir.z; + } + else if (event.getKeyCode() == KeyEvent.VK_RIGHT) { + rotation += -.1; + } + else if (event.getKeyCode() == KeyEvent.VK_LEFT) { + rotation += .1; + } + t.rotY(rotation); + t.setTranslation(translation); + viewTransformGroup.setTransform(t); + } + } + } + + + /** + * Constructor + */ + public MoverBehavior(TransformGroup trans) { + viewTransformGroup = trans; + Bounds bound = new BoundingSphere(new Point3d(0.0,0.0,0.0),10000.0); + this.setSchedulingBounds(bound); + } +} + + + diff --git a/src/classes/org/jdesktop/j3d/examples/text2d/Text2DTest.java b/src/classes/org/jdesktop/j3d/examples/text2d/Text2DTest.java new file mode 100644 index 0000000..a6c6275 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/text2d/Text2DTest.java @@ -0,0 +1,193 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.text2d; + +import java.applet.Applet; +import java.awt.*; +import java.awt.Font; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.geometry.Text2D; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Text2DTest extends Applet { + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + TransformGroup textTranslationGroup; + Transform3D textTranslation; + float yPos = -.5f; + Shape3D textObject = new Text2D("Rotating Yellow Text", + new Color3f(1f, 1f, 0f), + "Serif", + 60, + Font.BOLD); + Appearance app = textObject.getAppearance(); + + PolygonAttributes pa = app.getPolygonAttributes(); + if (pa == null) + pa = new PolygonAttributes(); + pa.setCullFace(PolygonAttributes.CULL_NONE); + if (app.getPolygonAttributes() == null) + app.setPolygonAttributes(pa); + objTrans.addChild(textObject); + + + textTranslation = new Transform3D(); + textTranslation.setTranslation(new Vector3f(0f, yPos, 0f)); + textTranslationGroup = new TransformGroup(textTranslation); + textTranslationGroup.addChild(objTrans); + objScale.addChild(textTranslationGroup); + yPos += .5f; + + /* Blue 40point text*/ + textObject = new Text2D("Blue 40point Text", + new Color3f(0f, 0f, 1f), + "Serif", + 40, + Font.BOLD); + textTranslation = new Transform3D(); + textTranslation.setTranslation(new Vector3f(0f, yPos, 0f)); + textTranslationGroup = new TransformGroup(textTranslation); + textTranslationGroup.addChild(textObject); + objScale.addChild(textTranslationGroup); + yPos += .5f; + + /* Green italic text*/ + textObject = new Text2D("Green Italic Text", + new Color3f(0f, 1f, 0f), + "Serif", + 70, + Font.ITALIC); + textTranslation = new Transform3D(); + textTranslation.setTranslation(new Vector3f(0f, yPos, 0f)); + textTranslationGroup = new TransformGroup(textTranslation); + textTranslationGroup.addChild(textObject); + objScale.addChild(textTranslationGroup); + yPos += .5f; + + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into + // the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + + return objRoot; + } + + public Text2DTest() { + } + + public void init() { + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + MoverBehavior navigator = + new MoverBehavior(u.getViewingPlatform().getViewPlatformTransform()); + scene.addChild(navigator); + + // Have Java 3D perform optimizations on this scene graph. + scene.compile(); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows HelloUniverse to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new Text2DTest(), 256, 256); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/text3d/Text3DLoad.java b/src/classes/org/jdesktop/j3d/examples/text3d/Text3DLoad.java new file mode 100644 index 0000000..3ff6955 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/text3d/Text3DLoad.java @@ -0,0 +1,286 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.text3d; + +import com.sun.j3d.loaders.objectfile.*; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.io.*; +import com.sun.j3d.utils.behaviors.vp.*; +import com.sun.j3d.utils.behaviors.keyboard.*; + +public class Text3DLoad extends Applet implements ActionListener { + + private String fontName = "TestFont"; + private String textString = null; + private double tessellation = 0.0; + + private SimpleUniverse u; + + private Button button; + private boolean behaviorsOn = false; + private OrbitBehavior orbit; + + public BranchGroup createSceneGraph() { + float sl = textString.length(); + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + // Assuming uniform size chars, set scale to fit string in view + t3d.setScale(1.2/sl); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + objScale.addChild(objTrans); + + Font3D f3d; + if (tessellation > 0.0) { + f3d = new Font3D(new Font(fontName, Font.PLAIN, 2), + tessellation, + new FontExtrusion()); + } + else { + f3d = new Font3D(new Font(fontName, Font.PLAIN, 2), + new FontExtrusion()); + } + Text3D txt = new Text3D(f3d, textString, + new Point3f( -sl/2.0f, -1.f, -1.f)); + Shape3D sh = new Shape3D(); + Appearance app = new Appearance(); + Material mm = new Material(); + mm.setLightingEnable(true); + app.setMaterial(mm); + sh.setGeometry(txt); + sh.setAppearance(app); + objTrans.addChild(sh); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + if (false) { + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + } + + // Set up the background + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f); + Background bgNode = new Background(bgColor); + bgNode.setApplicationBounds(bounds); + objRoot.addChild(bgNode); + + // Set up the ambient light + Color3f ambientColor = new Color3f(0.3f, 0.3f, 0.3f); + AmbientLight ambientLightNode = new AmbientLight(ambientColor); + ambientLightNode.setInfluencingBounds(bounds); + objRoot.addChild(ambientLightNode); + + // Set up the directional lights + Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f); + Color3f light2Color = new Color3f(1.0f, 1.0f, 0.9f); + Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f); + + DirectionalLight light1 + = new DirectionalLight(light1Color, light1Direction); + light1.setInfluencingBounds(bounds); + objRoot.addChild(light1); + + DirectionalLight light2 + = new DirectionalLight(light2Color, light2Direction); + light2.setInfluencingBounds(bounds); + objRoot.addChild(light2); + + return objRoot; + } + + private void usage() + { + System.out.println( + "Usage: java Text3DLoad [-f fontname] [-t tessellation] []"); + System.exit(0); + } // End of usage + + public Text3DLoad() {} + + public Text3DLoad(String args[]) { + + if (args.length == 0) { +// usage(); + textString = "Java3D"; + } + else { + for (int i = 0 ; i < args.length ; i++) { + if (args[i].startsWith("-")) { + if (args[i].equals("-f")) { + if (i < args.length - 1) { + fontName = args[++i]; + } + else { + usage(); + } + } + else if (args[i].equals("-t")) { + if (i < args.length - 1) { + tessellation = Double.parseDouble(args[++i]); + } + else { + usage(); + } + } + else { + System.err.println("Argument '" + args[i] + + "' ignored."); + } + } + else { + textString = args[i]; + } + } + } + + if (textString == null) { + usage(); + } + + } + + public void init() { + + if (textString == null) { + textString = "Java3D"; + } + setLayout(new BorderLayout()); + + button = new Button("remove behaviors"); + button.addActionListener(this); + Panel p = new Panel(); + p.add(button); + add("South", p); + + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + + // create a SimpleUniverse with 4 TransformGroups for the mouse + // behaviors + u = new SimpleUniverse(c); + + // add the behaviors to the ViewingPlatform + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + + viewingPlatform.setNominalViewingTransform(); + + // add orbit behavior to ViewingPlatform + orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL | + OrbitBehavior.STOP_ZOOM); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + behaviorsOn = true; + + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == button) { + ViewingPlatform v = u.getViewingPlatform(); + if (behaviorsOn) { + v.setViewPlatformBehavior(null); + button.setLabel("add behaviors"); + behaviorsOn = false; + } + else { + v.setViewPlatformBehavior(orbit); + button.setLabel("remove behaviors"); + behaviorsOn = true; + } + } + } + + // + // The following allows Text3DLoad to be run as an application + // as well as an applet + // + public static void main(String[] args) { + new MainFrame(new Text3DLoad(args), 700, 700); + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/texture/MultiTextureTest.java b/src/classes/org/jdesktop/j3d/examples/texture/MultiTextureTest.java new file mode 100644 index 0000000..026cfe9 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/texture/MultiTextureTest.java @@ -0,0 +1,320 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.texture; + +import com.sun.j3d.utils.image.TextureLoader; +import com.sun.j3d.utils.geometry.Box; +import com.sun.j3d.utils.behaviors.vp.*; +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.image.BufferedImage; + +public class MultiTextureTest extends Applet implements ItemListener{ + + Choice choice; + TextureUnitState textureUnitState[] = new TextureUnitState[2]; + Texture stoneTex; + Texture skyTex; + Texture lightTex; + + private java.net.URL stoneImage = null; + private java.net.URL skyImage = null; + + private SimpleUniverse u = null; + + public Texture createLightMap(){ + + int width = 128; + int height = 128; + BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + int [] rgbArray = new int[width * height]; + int index, index2; + int rgbInc = 256 / (width / 2 - 20); + int rgbValue = 0; + int k = width/2 - 5; + int i, j, rgb; + + rgb = 0xff; + rgbValue = rgb | (rgb << 8) | (rgb << 16) | (rgb << 24); + for ( i = width / 2 - 1, j = 0; j < 10; j++, i--) { + rgbArray[i] = rgbValue; + } + + for (; i > 8; i--, rgb -= rgbInc) { + rgbValue = rgb | (rgb << 8) | (rgb << 16) | (rgb << 24); + rgbArray[i] = rgbValue; + } + + for (; i >= 0; i--) { + rgbArray[i] = rgbValue; + } + + for (i = 0; i < width/2; i++) { + rgbValue = rgbArray[i]; + index = i; + index2 = (width - i - 1); + for (j = 0; j < height; j++) { + rgbArray[index] = rgbArray[index2] = rgbValue; + index += width; + index2 += width; + } + } + + bimage.setRGB(0, 0, width, height, rgbArray, 0, width); + + + ImageComponent2D grayImage = new ImageComponent2D(ImageComponent.FORMAT_RGB, bimage); + + lightTex = new Texture2D(Texture.BASE_LEVEL, Texture.RGB, width, height); + lightTex.setImage(0, grayImage); + + return lightTex; + } + + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create a Transformgroup to scale all objects so they + // appear in the scene. + TransformGroup objScale = new TransformGroup(); + Transform3D t3d = new Transform3D(); + t3d.setScale(0.4); + objScale.setTransform(t3d); + objRoot.addChild(objScale); + + TransformGroup objTrans = new TransformGroup(); + //write-enable for behaviors + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objTrans.setCapability( TransformGroup.ALLOW_TRANSFORM_READ ); + objTrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING); + objScale.addChild(objTrans); + + Appearance ap = new Appearance(); + + // load textures + TextureAttributes texAttr1 = new TextureAttributes(); + texAttr1.setTextureMode(TextureAttributes.DECAL); + TextureAttributes texAttr2 = new TextureAttributes(); + texAttr2.setTextureMode(TextureAttributes.MODULATE); + + TextureLoader tex = new TextureLoader(stoneImage, new String("RGB"), this); + if (tex == null) + return null; + stoneTex = tex.getTexture(); + + tex = new TextureLoader(skyImage, new String("RGB"), this); + if (tex == null) + return null; + skyTex = tex.getTexture(); + + lightTex = createLightMap(); + + + textureUnitState[0] = new TextureUnitState(stoneTex, texAttr1, null); + textureUnitState[0].setCapability(TextureUnitState.ALLOW_STATE_WRITE); + + textureUnitState[1] = new TextureUnitState(lightTex, texAttr2, null); + textureUnitState[1].setCapability(TextureUnitState.ALLOW_STATE_WRITE); + + ap.setTextureUnitState(textureUnitState); + + //Create a Box + Box BoxObj = new Box(1.5f, 1.5f, 0.8f, Box.GENERATE_NORMALS | + Box.GENERATE_TEXTURE_COORDS, ap, 2); + // add it to the scene graph. + objTrans.addChild(BoxObj); + + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + //Shine it with two lights. + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Color3f lColor2 = new Color3f(0.2f, 0.2f, 0.1f); + Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f); + Vector3f lDir2 = new Vector3f(0.0f, 0.0f, -1.0f); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2); + lgt1.setInfluencingBounds(bounds); + lgt2.setInfluencingBounds(bounds); + objScale.addChild(lgt1); + objScale.addChild(lgt2); + + // Let Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public MultiTextureTest (){ + } + + public MultiTextureTest(java.net.URL stoneURL, java.net.URL skyURL) { + stoneImage = stoneURL; + skyImage = skyURL; + } + + public void init() { + if (stoneImage == null) { + // the path to the image for an applet + try { + stoneImage = new java.net.URL(getCodeBase().toString() + + "../images/stone.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + if (skyImage == null) { + // the path to the image for an applet + try { + skyImage = new java.net.URL(getCodeBase().toString() + + "../images/bg.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + ViewingPlatform viewingPlatform = u.getViewingPlatform(); + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + viewingPlatform.setNominalViewingTransform(); + + // add orbit behavior but disable translate + OrbitBehavior orbit = + new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL | + OrbitBehavior.DISABLE_TRANSLATE); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); + orbit.setSchedulingBounds(bounds); + viewingPlatform.setViewPlatformBehavior(orbit); + + u.addBranchGraph(scene); + + // create the gui + choice = new Choice(); + choice.addItem("stone + light"); + choice.addItem("stone"); + choice.addItem("lightMap"); + choice.addItem("sky"); + choice.addItem("stone + sky"); + choice.addItemListener(this); + add("North", choice); + + } + + public void destroy() { + // Cleanup reference to Java3D + textureUnitState = new TextureUnitState[2]; + u.cleanup(); + } + + public void itemStateChanged(ItemEvent e) + { + int index = choice.getSelectedIndex(); + + switch (index) { + case 0 : /* stone + light */ + textureUnitState[0].setTexture(stoneTex); + textureUnitState[1].setTexture(lightTex); + break; + case 1 : /* stone */ + textureUnitState[0].setTexture(stoneTex); + textureUnitState[1].setTexture(null); + break; + case 2 : /* light */ + textureUnitState[0].setTexture(null); + textureUnitState[1].setTexture(lightTex); + break; + case 3 : /* sky */ + textureUnitState[0].setTexture(null); + textureUnitState[1].setTexture(skyTex); + break; + case 4 : /* stone + sky */ + textureUnitState[0].setTexture(stoneTex); + textureUnitState[1].setTexture(skyTex); + break; + default: /* both */ + break; + } + } + + public static void main(String argv[]) + { + java.net.URL stoneURL = null; + java.net.URL skyURL = null; + // the path to the image for an application + try { + stoneURL = new java.net.URL("file:../images/stone.jpg"); + skyURL = new java.net.URL("file:../images/bg.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + new MainFrame(new MultiTextureTest(stoneURL, skyURL), 750, 750); + } +} + diff --git a/src/classes/org/jdesktop/j3d/examples/texture/TextureImage.java b/src/classes/org/jdesktop/j3d/examples/texture/TextureImage.java new file mode 100644 index 0000000..b6ab08f --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/texture/TextureImage.java @@ -0,0 +1,180 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.texture; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import com.sun.j3d.utils.image.TextureLoader; +import com.sun.j3d.utils.geometry.Box; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class TextureImage extends Applet { + + private java.net.URL texImage = null; + + private SimpleUniverse u = null; + + public BranchGroup createSceneGraph() { + // Create the root of the branch graph + BranchGroup objRoot = new BranchGroup(); + + // Create the transform group node and initialize it to the + // identity. Enable the TRANSFORM_WRITE capability so that + // our behavior code can modify it at runtime. Add it to the + // root of the subgraph. + TransformGroup objTrans = new TransformGroup(); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // Create appearance object for textured cube + Appearance app = new Appearance(); + Texture tex = new TextureLoader(texImage, this).getTexture(); + app.setTexture(tex); + TextureAttributes texAttr = new TextureAttributes(); + texAttr.setTextureMode(TextureAttributes.MODULATE); + app.setTextureAttributes(texAttr); + + // Create textured cube and add it to the scene graph. + Box textureCube = new Box(0.4f, 0.4f, 0.4f, + Box.GENERATE_TEXTURE_COORDS, app); + objTrans.addChild(textureCube); + + // Create a new Behavior object that will perform the desired + // operation on the specified transform object and add it into + // the scene graph. + Transform3D yAxis = new Transform3D(); + Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + + RotationInterpolator rotator = + new RotationInterpolator(rotationAlpha, objTrans, yAxis, + 0.0f, (float) Math.PI*2.0f); + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + + // Have Java 3D perform optimizations on this scene graph. + objRoot.compile(); + + return objRoot; + } + + public TextureImage() { + } + + public TextureImage(java.net.URL url) { + texImage = url; + } + + public void init() { + if (texImage == null) { + // the path to the image for an applet + try { + texImage = new java.net.URL(getCodeBase().toString() + + "../images/stone.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + setLayout(new BorderLayout()); + GraphicsConfiguration config = + SimpleUniverse.getPreferredConfiguration(); + + Canvas3D c = new Canvas3D(config); + add("Center", c); + + // Create a simple scene and attach it to the virtual universe + BranchGroup scene = createSceneGraph(); + u = new SimpleUniverse(c); + + // This will move the ViewPlatform back a bit so the + // objects in the scene can be viewed. + u.getViewingPlatform().setNominalViewingTransform(); + + u.addBranchGraph(scene); + } + + public void destroy() { + u.cleanup(); + } + + // + // The following allows TextureImage to be run as an application + // as well as an applet + // + public static void main(String[] args) { + java.net.URL url = null; + if (args.length > 0) { + try { + url = new java.net.URL("file:" + args[0]); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + else { + // the path to the image for an application + try { + url = new java.net.URL("file:../images/stone.jpg"); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + new MainFrame(new TextureImage(url), 256, 256); + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java new file mode 100644 index 0000000..66c9fef --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/AnimateTexturesBehavior.java @@ -0,0 +1,317 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.texture_by_ref; + +import javax.media.j3d.*; +import java.awt.image.BufferedImage; +import java.awt.*; +import com.sun.j3d.utils.image.TextureLoader; +import java.util.Enumeration; + +public class AnimateTexturesBehavior extends Behavior { + + + // what image are we on + private int current; + private int max; + + // the images + private ImageComponent2D[] images; + + // the target + private Texture2D texture; + private Appearance appearance; + + // the wakeup criterion + private WakeupCriterion wakeupC; + + // are the images flipped? + private boolean flip; + + // need the current type because by copy changes all images + // to TYPE_INT_ARGB + private int currentType; + + // for custom types + public static final int TYPE_CUSTOM_RGBA = 0x01; + public static final int TYPE_CUSTOM_RGB = 0x02; + + private int customType; + + // create a new AnimateTextureBehavior + // initialize the images + public AnimateTexturesBehavior(Texture2D texP, + java.net.URL[] fnames, + Appearance appP, + TextureByReference applet) { + int size = fnames.length; + images = new ImageComponent2D[size]; + BufferedImage bImage; + TextureLoader loader; + for (int i = 0; i < size; i++) { + loader = new TextureLoader(fnames[i], + TextureLoader.BY_REFERENCE | + TextureLoader.Y_UP, applet); + images[i] = loader.getImage(); + bImage = images[i].getImage(); + + // convert the image to TYPE_4BYTE_ABGR + currentType = BufferedImage.TYPE_4BYTE_ABGR; + bImage = ImageOps.convertImage(bImage, currentType); + // flip the image + flip = true; + ImageOps.flipImage(bImage); + + // set the image on the ImageComponent to the new one + images[i].set(bImage); + + images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ); + images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ); + } + texture = texP; + current = 0; + max = size; + wakeupC = new WakeupOnElapsedFrames(20); + appearance = appP; + } + + // initialize to the first image + public void initialize() { + texture.setImage(0, images[current]); + if (current < max-1) current++; + else current = 0; + wakeupOn(wakeupC); + } + + // procesStimulus changes the ImageComponent of the texture + public void processStimulus(Enumeration criteria) { + // ImageOps.printType(images[current].getImage()); + texture.setImage(0, images[current]); + appearance.setTexture(texture); + if (current < max-1) current++; + else current = 0; + wakeupOn(wakeupC); + } + + // flip the image -- useful depending on yUp + public void setFlipImages(boolean b) { + // double check that flipping is necessary + if (b != flip) { + BufferedImage bImage; + + // these are the same for all images so get info once + int format = images[0].getFormat(); + boolean byRef = images[0].isByReference(); + boolean yUp = images[0].isYUp(); + + // flip all the images + // have to new ImageComponents because can't set the image at runtime + for (int i = 0; i < images.length; i++) { + bImage = images[i].getImage(); + ImageOps.flipImage(bImage); + // if we are byRef and the bImage type does not match currentType + // we need to convert it. If we are not byRef we will + // save converting until it is changed to byRef + if (byRef && bImage.getType() != currentType) { + if (currentType != BufferedImage.TYPE_CUSTOM) { + bImage = ImageOps.convertImage(bImage, currentType); + } + else if (customType == this.TYPE_CUSTOM_RGBA) { + bImage = ImageOps.convertToCustomRGBA(bImage); + } + else { + bImage = ImageOps.convertToCustomRGB(bImage); + } + } + images[i] = new ImageComponent2D(format, bImage, byRef, yUp); + images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ); + images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ); + } + + // set flip to new value + flip = b; + } + } + + // create new ImageComponents with yUp set to the parameter. yUp on + // an ImageComponent cannot be changed at runtim + public void setYUp(boolean b) { + // double check that changing yUp is necessary + if (b != images[0].isYUp()) { + + // these are the same for all images so get info once + int format = images[0].getFormat(); + boolean byRef = images[0].isByReference(); + + // reset yUp on all the images -- have to new ImageComponents because + // cannot change the value at runtime + for (int i = 0; i < images.length; i++) { + // if we are byRef and the bImage type does not match currentType + // we need to convert it. If we are not byRef we will + // save converting until it is changed to byRef + BufferedImage bImage = images[i].getImage(); + if (byRef && bImage.getType() != currentType) { + // bImage = ImageOps.convertImage(bImage, currentType); + if (currentType != BufferedImage.TYPE_CUSTOM) { + bImage = ImageOps.convertImage(bImage, currentType); + } + else if (customType == this.TYPE_CUSTOM_RGBA) { + bImage = ImageOps.convertToCustomRGBA(bImage); + } + else { + bImage = ImageOps.convertToCustomRGB(bImage); + } + } + images[i] = new ImageComponent2D(format, bImage, + byRef, b); + images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ); + images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ); + } + } + } + + // create new ImageComponents with ByReference set by parameter. + // by reference cannot be changed on an image component at runtime + public void setByReference(boolean b) { + // double check that changing is necessary + if (b != images[0].isByReference()) { + + // these are the same for all images so get info once + int format = images[0].getFormat(); + boolean yUp = images[0].isYUp(); + + // reset yUp on all the images + // have to new ImageComponents because cannot set value + for (int i = 0; i < images.length; i++) { + // if the bImage type does not match currentType and we are setting + // to byRef we need to convert it + BufferedImage bImage = images[i].getImage(); + if (bImage.getType() != currentType && b) { + // bImage = ImageOps.convertImage(bImage, currentType); + if (currentType != BufferedImage.TYPE_CUSTOM) { + bImage = ImageOps.convertImage(bImage, currentType); + } + else if (customType == this.TYPE_CUSTOM_RGBA) { + bImage = ImageOps.convertToCustomRGBA(bImage); + } + else { + bImage = ImageOps.convertToCustomRGB(bImage); + } + } + images[i] = new ImageComponent2D(format, bImage, b, yUp); + images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ); + images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ); + } + } + } + + // make a new wakeup criterion object based on the new delay time + public void setFrameDelay(int delay) { + wakeupC = new WakeupOnElapsedFrames(delay); + } + + //change the type of image + public void setImageType(int newType) { + currentType = newType; + + // only need to change the images if we are byRef otherwise will change + // them when we chnage to byRef + if (images[0].isByReference() == true) { + // this information is the same for all + int format = images[0].getFormat(); + boolean yUp = images[0].isYUp(); + boolean byRef = true; + for (int i = 0; i < images.length; i++) { + BufferedImage bImage = images[i].getImage(); + bImage = ImageOps.convertImage(bImage, currentType); + images[i] = new ImageComponent2D(format, bImage, byRef, yUp); + images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ); + images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ); + } + } + } + + public void setImageTypeCustomRGBA() { + currentType = BufferedImage.TYPE_CUSTOM; + customType = this.TYPE_CUSTOM_RGBA; + + // only need to change images if we are byRef otherwise will change + // them when we change to byRef + if (images[0].isByReference()) { + // this information is the same for all + int format = images[0].getFormat(); + boolean yUp = images[0].isYUp(); + boolean byRef = true; + for (int i = 0; i < images.length; i++) { + BufferedImage bImage = images[i].getImage(); + bImage = ImageOps.convertToCustomRGBA(bImage); + images[i] = new ImageComponent2D(format, bImage, byRef, yUp); + images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ); + images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ); + } + } + } + + public void setImageTypeCustomRGB() { + currentType = BufferedImage.TYPE_CUSTOM; + customType = this.TYPE_CUSTOM_RGB; + + // only need to change images if we are byRef otherwise will change + // them when we change to byRef + if (images[0].isByReference()) { + // this information is the same for all + int format = images[0].getFormat(); + boolean yUp = images[0].isYUp(); + boolean byRef = true; + for (int i = 0; i < images.length; i++) { + BufferedImage bImage = images[i].getImage(); + bImage = ImageOps.convertToCustomRGB(bImage); + images[i] = new ImageComponent2D(format, bImage, byRef, yUp); + images[i].setCapability(ImageComponent.ALLOW_IMAGE_READ); + images[i].setCapability(ImageComponent.ALLOW_FORMAT_READ); + } + } + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java new file mode 100644 index 0000000..97d5387 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/ImageOps.java @@ -0,0 +1,175 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.texture_by_ref; + +import java.awt.*; +import java.awt.image.*; +import java.awt.color.*; + +// some useful, static image operations + +public class ImageOps { + + // flip the image + public static void flipImage(BufferedImage bImage) { + int width = bImage.getWidth(); + int height = bImage.getHeight(); + int[] rgbArray = new int[width*height]; + bImage.getRGB(0, 0, width, height, rgbArray, 0, width); + int[] tempArray = new int[width*height]; + int y2 = 0; + for (int y = height-1; y >= 0; y--) { + for (int x = 0; x < width; x++) { + tempArray[y2*width+x] = rgbArray[y*width+x]; + } + y2++; + } + bImage.setRGB(0, 0, width, height, tempArray, 0, width); + } + + + // convert the image to a specified BufferedImage type and return it + public static BufferedImage convertImage(BufferedImage bImage, int type) { + int width = bImage.getWidth(); + int height = bImage.getHeight(); + BufferedImage newImage = new BufferedImage(width, height, type); + int[] rgbArray = new int[width*height]; + bImage.getRGB(0, 0, width, height, rgbArray, 0, width); + newImage.setRGB(0, 0, width, height, rgbArray, 0, width); + return newImage; + } + + // print out some of the types of BufferedImages + static void printType(BufferedImage bImage) { + int type = bImage.getType(); + if (type == BufferedImage.TYPE_4BYTE_ABGR) { + System.out.println("TYPE_4BYTE_ABGR"); + } + else if (type == BufferedImage.TYPE_INT_ARGB) { + System.out.println("TYPE_INT_ARGB"); + } + else if (type == BufferedImage.TYPE_3BYTE_BGR) { + System.out.println("TYPE_3BYTE_BGR"); + } + else if (type == BufferedImage.TYPE_CUSTOM) { + System.out.println("TYPE_CUSTOM"); + } + else System.out.println(type); + } + + public static BufferedImage convertToCustomRGBA(BufferedImage bImage) { + if (bImage.getType() != BufferedImage.TYPE_INT_ARGB) { + ImageOps.convertImage(bImage, BufferedImage.TYPE_INT_ARGB); + } + + int width = bImage.getWidth(); + int height = bImage.getHeight(); + + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8, 8}; + ColorModel cm = new ComponentColorModel(cs, nBits, true, false, + Transparency.OPAQUE, 0); + int[] bandOffset = {0, 1, 2, 3}; + + WritableRaster newRaster = + Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, + width*4, 4, bandOffset, null); + byte[] byteData = ((DataBufferByte)newRaster.getDataBuffer()).getData(); + Raster origRaster = bImage.getData(); + int[] pixel = new int[4]; + int k = 0; + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + pixel = origRaster.getPixel(i, j, pixel); + byteData[k++] = (byte)(pixel[0]); + byteData[k++] = (byte)(pixel[1]); + byteData[k++] = (byte)(pixel[2]); + byteData[k++] = (byte)(pixel[3]); + } + } + BufferedImage newImage = new BufferedImage(cm, newRaster, false, null); +// if (newImage.getType() == BufferedImage.TYPE_CUSTOM) { +// System.out.println("Type is custom"); +// } + return newImage; + } + + public static BufferedImage convertToCustomRGB(BufferedImage bImage) { + if (bImage.getType() != BufferedImage.TYPE_INT_ARGB) { + ImageOps.convertImage(bImage, BufferedImage.TYPE_INT_ARGB); + } + + int width = bImage.getWidth(); + int height = bImage.getHeight(); + + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); + int[] nBits = {8, 8, 8}; + ColorModel cm = new ComponentColorModel(cs, nBits, false, false, + Transparency.OPAQUE, 0); + int[] bandOffset = {0, 1, 2}; + + WritableRaster newRaster = + Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, + width*3, 3, bandOffset, null); + byte[] byteData = ((DataBufferByte)newRaster.getDataBuffer()).getData(); + Raster origRaster = bImage.getData(); + int[] pixel = new int[4]; + int k = 0; + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + pixel = origRaster.getPixel(i, j, pixel); + byteData[k++] = (byte)(pixel[0]); + byteData[k++] = (byte)(pixel[1]); + byteData[k++] = (byte)(pixel[2]); + } + } + BufferedImage newImage = new BufferedImage(cm, newRaster, false, null); +// if (newImage.getType() == BufferedImage.TYPE_CUSTOM) { +// System.out.println("Type is custom"); +// } + return newImage; + } +} + diff --git a/src/classes/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java new file mode 100644 index 0000000..bd564a7 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/Tetrahedron.java @@ -0,0 +1,223 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.texture_by_ref; + +import javax.media.j3d.*; +import javax.vecmath.*; + + +public class Tetrahedron extends Shape3D { + + private static final float sqrt3 = (float) Math.sqrt(3.0); + private static final float sqrt3_3 = sqrt3 / 3.0f; + private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f; + + private static final float ycenter = 0.5f * sqrt24_3; + private static final float zcenter = -sqrt3_3; + + private static final Point3f p1 = new Point3f(-1.0f, -ycenter, -zcenter); + private static final Point3f p2 = new Point3f(1.0f, -ycenter, -zcenter); + private static final Point3f p3 = new Point3f(0.0f, -ycenter, -sqrt3 - zcenter); + private static final Point3f p4 = new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f); + + private static final Point3f[] verts = { + p1, p2, p4, // front face + p1, p4, p3, // left, back face + p2, p3, p4, // right, back face + p1, p3, p2, // bottom face + }; + + private Point2f texCoord[] = { + new Point2f(-0.25f, 0.0f), + new Point2f(1.25f, 0.0f), + new Point2f(0.5f, 2.0f), + }; + + private TriangleArray geometryByRef; + private TriangleArray geometryByCopy; + + // for geometry by reference + private Point3f[] verticesArray = new Point3f[12]; + private TexCoord2f[] textureCoordsArray = new TexCoord2f[12]; + private Vector3f[] normalsArray = new Vector3f[12]; + + // default to geometry by copy + public Tetrahedron() { + this(false); + } + + // creates a tetrahedron with geometry by reference or by copy depending on + // the byRef parameter + public Tetrahedron(boolean byRef) { + if (byRef) { + createGeometryByRef(); + this.setGeometry(geometryByRef); + } + else { + createGeometryByCopy(); + this.setGeometry(geometryByCopy); + } + this.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + this.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + setAppearance(new Appearance()); + } + + // create the geometry by reference and + // store it in the geometryByRef variable + public void createGeometryByRef() { +// System.out.println("createGeometryByRef"); + geometryByRef = new TriangleArray(12, TriangleArray.COORDINATES | + TriangleArray.NORMALS | + TriangleArray.TEXTURE_COORDINATE_2 | + TriangleArray.BY_REFERENCE); + + int i; + + // the coordinates + for (i = 0; i < 12; i++) { + verticesArray[i] = new Point3f(verts[i]); + } + geometryByRef.setCoordRef3f(verticesArray); +// System.out.println("coordinates set"); +// Point3f[] temp1 = geometryByRef.getCoordRef3f(); +// for (i = 0; i < 12; i++) { +// System.out.println(temp1[i]); +// } + + // the texture coordinates + for (i = 0; i < 12; i++) { + textureCoordsArray[i] = new TexCoord2f(texCoord[i%3]); + } + geometryByRef.setTexCoordRef2f(0, textureCoordsArray); +// System.out.println("texture coords set"); +// TexCoord2f[] temp2 = geometryByRef.getTexCoordRef2f(0); +// for (i = 0; i < 12; i++) { +// System.out.println(temp2[i]); +// } + + // the normals + Vector3f normal = new Vector3f(); + Vector3f v1 = new Vector3f(); + Vector3f v2 = new Vector3f(); + Point3f[] pts = new Point3f[3]; + for (int face = 0; face < 4; face++) { + pts[0] = new Point3f(verts[face*3]); + pts[1] = new Point3f(verts[face*3+1]); + pts[2] = new Point3f(verts[face*3+2]); + v1.sub(pts[1], pts[0]); + v2.sub(pts[2], pts[0]); + normal.cross(v1, v2); + normal.normalize(); + for (i = 0; i < 3; i++) { + normalsArray[face*3+i] = new Vector3f(normal); + } + } + geometryByRef.setNormalRef3f(normalsArray); +// System.out.println("normals set"); +// Vector3f[] temp3 = geometryByRef.getNormalRef3f(); +// for (i = 0; i < 12; i++) { +// System.out.println(temp3[i]); +// } + } + + // create the geometry by copy and store it in the geometryByCopy variable + public void createGeometryByCopy() { + int i; + geometryByCopy = new TriangleArray(12, TriangleArray.COORDINATES | + TriangleArray.NORMALS | + TriangleArray.TEXTURE_COORDINATE_2); + + geometryByCopy.setCoordinates(0, verts); + + for (i = 0; i < 12; i++) { + geometryByCopy.setTextureCoordinate(0, i, + new TexCoord2f(texCoord[i%3])); + } + + int face; + Vector3f normal = new Vector3f(); + Vector3f v1 = new Vector3f(); + Vector3f v2 = new Vector3f(); + Point3f [] pts = new Point3f[3]; + for (i = 0; i < 3; i++) pts[i] = new Point3f(); + + for (face = 0; face < 4; face++) { + geometryByCopy.getCoordinates(face*3, pts); + v1.sub(pts[1], pts[0]); + v2.sub(pts[2], pts[0]); + normal.cross(v1, v2); + normal.normalize(); + for (i = 0; i < 3; i++) { + geometryByCopy.setNormal((face * 3 + i), normal); + } + } + } + + // set the geometry to geometryByRef or geometryByCopy depending on the + // parameter. Create geometryByRef or geometryByCopy if necessary + public void setByReference(boolean b) { +// System.out.println("Tetrahedron.setByReference " + b); + // by reference is true + if (b) { + // if there is no geometryByRef, create it + if (geometryByRef == null) { + createGeometryByRef(); + } + // set the geometry + this.setGeometry(geometryByRef); + } + // by reference is false + else { + // if there is no geometryByCopy, create it + if (geometryByCopy == null) { + createGeometryByCopy(); + } + // set the geometry + this.setGeometry(geometryByCopy); + } + } +} + + diff --git a/src/classes/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java new file mode 100644 index 0000000..1faad7e --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/texture_by_ref/TextureByReference.java @@ -0,0 +1,532 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.texture_by_ref; + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import com.sun.j3d.utils.applet.MainFrame; +import com.sun.j3d.utils.universe.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.image.*; +import java.awt.color.ColorSpace; +import com.sun.j3d.utils.image.TextureLoader; +import javax.swing.*; +import javax.swing.event.*; + + +public class TextureByReference extends Applet +implements ItemListener, ActionListener, ChangeListener { + + // need reference to animation behavior + private AnimateTexturesBehavior animate; + + // need reference to tetrahedron + private Tetrahedron tetra; + + // the gui buttons + private JCheckBox flipB; + private JRadioButton texByRef; + private JRadioButton texByCopy; + private JRadioButton geomByRef; + private JRadioButton geomByCopy; + private JRadioButton img4ByteABGR; + private JRadioButton img3ByteBGR; + private JRadioButton imgIntARGB; + private JRadioButton imgCustomRGBA; + private JRadioButton imgCustomRGB; + private JRadioButton yUp; + private JRadioButton yDown; + private JButton animationB; + private JSlider frameDelay; + + private SimpleUniverse universe = null; + + // image files used for the Texture animation for the applet, + // or if no parameters are passed in for the application + public static final String[] defaultFiles = { + "../images/animation1.gif", + "../images/animation2.gif", + "../images/animation3.gif", + "../images/animation4.gif", + "../images/animation5.gif", + "../images/animation6.gif", + "../images/animation7.gif", + "../images/animation8.gif", + "../images/animation9.gif", + "../images/animation10.gif"}; + + private java.net.URL[] urls = null; + + + public TextureByReference() { + } + + public TextureByReference(java.net.URL[] fnamesP) { + urls = fnamesP; + } + + public void init() { + if (urls == null) { + urls = new java.net.URL[defaultFiles.length]; + for (int i = 0; i < defaultFiles.length; i++) { + try { + urls[i] = new java.net.URL(getCodeBase().toString() + + defaultFiles[i]); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + } + setLayout(new BorderLayout()); + GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); + + Canvas3D canvas = new Canvas3D(config); + + add("Center", canvas); + + // create a simple scene graph and attach it to a simple universe + BranchGroup scene = createSceneGraph(); + universe = new SimpleUniverse(canvas); + universe.getViewingPlatform().setNominalViewingTransform(); + universe.addBranchGraph(scene); + + // create the gui + JPanel gui = buildGui(); + + this.add("South", gui); + } + + public void destroy() { + universe.cleanup(); + } + + public JPanel buildGui() { + flipB = new JCheckBox("flip image", true); + flipB.addItemListener(this); + javax.swing.Box flipBox = new javax.swing.Box(BoxLayout.Y_AXIS); + flipBox.add(flipB); + Component strut1 = flipBox.createVerticalStrut(flipB.getPreferredSize().height); + Component strut2 = flipBox.createVerticalStrut(flipB.getPreferredSize().height); + Component strut3 = flipBox.createVerticalStrut(flipB.getPreferredSize().height); + Component strut4 = flipBox.createVerticalStrut(flipB.getPreferredSize().height); + Component strut5 = flipBox.createVerticalStrut(flipB.getPreferredSize().height); + flipBox.add(strut1); + flipBox.add(strut2); + flipBox.add(strut3); + flipBox.add(strut4); + flipBox.add(strut5); + + yUp = new JRadioButton("y up"); + yUp.addActionListener(this); + yUp.setSelected(true); + yDown = new JRadioButton("y down"); + yDown.addActionListener(this); + ButtonGroup yGroup = new ButtonGroup(); + yGroup.add(yUp); + yGroup.add(yDown); + JLabel yLabel = new JLabel("Image Orientation:"); + javax.swing.Box yBox = new javax.swing.Box(BoxLayout.Y_AXIS); + yBox.add(yLabel); + yBox.add(yUp); + yBox.add(yDown); + strut1 = yBox.createVerticalStrut(yUp.getPreferredSize().height); + strut2 = yBox.createVerticalStrut(yUp.getPreferredSize().height); + strut3 = yBox.createVerticalStrut(yUp.getPreferredSize().height); + yBox.add(strut1); + yBox.add(strut2); + yBox.add(strut3); + + texByRef = new JRadioButton("by reference"); + texByRef.addActionListener(this); + texByRef.setSelected(true); + texByCopy = new JRadioButton("by copy"); + texByCopy.addActionListener(this); + ButtonGroup texGroup = new ButtonGroup(); + texGroup.add(texByRef); + texGroup.add(texByCopy); + JLabel texLabel = new JLabel("Texture:*"); + javax.swing.Box texBox = new javax.swing.Box(BoxLayout.Y_AXIS); + texBox.add(texLabel); + texBox.add(texByRef); + texBox.add(texByCopy); + strut1 = texBox.createVerticalStrut(texByRef.getPreferredSize().height); + strut2 = texBox.createVerticalStrut(texByRef.getPreferredSize().height); + strut3 = texBox.createVerticalStrut(texByRef.getPreferredSize().height); + texBox.add(strut1); + texBox.add(strut2); + texBox.add(strut3); + + geomByRef = new JRadioButton("by reference"); + geomByRef.addActionListener(this); + geomByRef.setSelected(true); + geomByCopy = new JRadioButton("by copy"); + geomByCopy.addActionListener(this); + ButtonGroup geomGroup = new ButtonGroup(); + geomGroup.add(geomByRef); + geomGroup.add(geomByCopy); + JLabel geomLabel = new JLabel("Geometry:"); + javax.swing.Box geomBox = new javax.swing.Box(BoxLayout.Y_AXIS); + geomBox.add(geomLabel); + geomBox.add(geomByRef); + geomBox.add(geomByCopy); + strut1 = geomBox.createVerticalStrut(geomByRef.getPreferredSize().height); + strut2 = geomBox.createVerticalStrut(geomByRef.getPreferredSize().height); + strut3 = geomBox.createVerticalStrut(geomByRef.getPreferredSize().height); + geomBox.add(strut1); + geomBox.add(strut2); + geomBox.add(strut3); + + img4ByteABGR = new JRadioButton("TYPE_4BYTE_ABGR"); + img4ByteABGR.addActionListener(this); + img4ByteABGR.setSelected(true); + img3ByteBGR = new JRadioButton("TYPE_3BYTE_BGR"); + img3ByteBGR.addActionListener(this); + imgIntARGB = new JRadioButton("TYPE_INT_ARGB"); + imgIntARGB.addActionListener(this); + imgCustomRGBA = new JRadioButton("TYPE_CUSTOM RGBA"); + imgCustomRGBA.addActionListener(this); + imgCustomRGB = new JRadioButton("TYPE_CUSTOM RGB"); + imgCustomRGB.addActionListener(this); + ButtonGroup imgGroup = new ButtonGroup(); + imgGroup.add(img4ByteABGR); + imgGroup.add(img3ByteBGR); + imgGroup.add(imgIntARGB); + imgGroup.add(imgCustomRGBA); + imgGroup.add(imgCustomRGB); + JLabel imgLabel = new JLabel("Image Type:*"); + javax.swing.Box imgBox = new javax.swing.Box(BoxLayout.Y_AXIS); + imgBox.add(imgLabel); + imgBox.add(img4ByteABGR); + imgBox.add(img3ByteBGR); + imgBox.add(imgIntARGB); + imgBox.add(imgCustomRGBA); + imgBox.add(imgCustomRGB); + + javax.swing.Box topBox = new javax.swing.Box(BoxLayout.X_AXIS); + topBox.add(flipBox); + topBox.add(texBox); + topBox.add(geomBox); + topBox.add(yBox); + Component strut = topBox.createRigidArea(new Dimension(10, 10)); + topBox.add(strut); + topBox.add(imgBox); + + frameDelay = new JSlider(0, 50, 0); + frameDelay.addChangeListener(this); + frameDelay.setSnapToTicks(true); + frameDelay.setPaintTicks(true); + frameDelay.setPaintLabels(true); + frameDelay.setMajorTickSpacing(10); + frameDelay.setMinorTickSpacing(1); + frameDelay.setValue(20); + JLabel delayL = new JLabel("frame delay"); + javax.swing.Box delayBox = new javax.swing.Box(BoxLayout.X_AXIS); + delayBox.add(delayL); + delayBox.add(frameDelay); + + animationB = new JButton(" stop animation "); + animationB.addActionListener(this); + + JLabel texInfo1 = new JLabel("*To use ImageComponent by reference feature, use TYPE_4BYTE_ABGR on Solaris"); + JLabel texInfo2 = new JLabel("and TYPE_3BYTE_BGR on Windows"); + + JPanel buttonP = new JPanel(); + GridBagLayout gridbag = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + buttonP.setLayout(gridbag); + c.anchor = GridBagConstraints.CENTER; + c.gridwidth = GridBagConstraints.REMAINDER; + gridbag.setConstraints(topBox, c); + buttonP.add(topBox); + gridbag.setConstraints(delayBox, c); + buttonP.add(delayBox); + gridbag.setConstraints(animationB, c); + buttonP.add(animationB); + gridbag.setConstraints(texInfo1, c); + buttonP.add(texInfo1); + gridbag.setConstraints(texInfo2, c); + buttonP.add(texInfo2); + + return buttonP; + + } + + public BranchGroup createSceneGraph() { + + // create the root of the branch group + BranchGroup objRoot = new BranchGroup(); + + // create the transform group node and initialize it + // enable the TRANSFORM_WRITE capability so that it can be modified + // at runtime. Add it to the root of the subgraph + Transform3D rotate = new Transform3D(); + TransformGroup objTrans = new TransformGroup(rotate); + objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + objRoot.addChild(objTrans); + + // bounds + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); + + // set up some light + Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f); + Vector3f lDir1 = new Vector3f(-1.0f, -0.5f, -1.0f); + Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f); + + AmbientLight aLgt = new AmbientLight(alColor); + aLgt.setInfluencingBounds(bounds); + DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1); + lgt1.setInfluencingBounds(bounds); + objRoot.addChild(aLgt); + objRoot.addChild(lgt1); + + + Appearance appearance = new Appearance(); + + // enable the TEXTURE_WRITE so we can modify it at runtime + appearance.setCapability(Appearance.ALLOW_TEXTURE_WRITE); + + // load the first texture + TextureLoader loader = new TextureLoader(urls[0], + TextureLoader.BY_REFERENCE | + TextureLoader.Y_UP, + this); + // get the texture from the loader + Texture2D tex = (Texture2D)loader.getTexture(); + + // get the BufferedImage to convert to TYPE_4BYTE_ABGR and flip + // get the ImageComponent because we need it anyway + ImageComponent2D imageComp = (ImageComponent2D)tex.getImage(0); + BufferedImage bImage = imageComp.getImage(); + // convert the image + bImage = ImageOps.convertImage(bImage, BufferedImage.TYPE_4BYTE_ABGR); + // flip the image + ImageOps.flipImage(bImage); + imageComp.set(bImage); + + tex.setCapability(Texture.ALLOW_IMAGE_WRITE); + tex.setBoundaryModeS(Texture.CLAMP); + tex.setBoundaryModeT(Texture.CLAMP); + tex.setBoundaryColor(1.0f, 1.0f, 1.0f, 1.0f); + + // set the image of the texture + tex.setImage(0, imageComp); + + // set the texture on the appearance + appearance.setTexture(tex); + + // set texture attributes + TextureAttributes texAttr = new TextureAttributes(); + texAttr.setTextureMode(TextureAttributes.MODULATE); + appearance.setTextureAttributes(texAttr); + + // set material properties + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + appearance.setMaterial(new Material(white, black, white, black, 1.0f)); + + // create a scale transform + Transform3D scale = new Transform3D(); + scale.set(.6); + TransformGroup objScale = new TransformGroup(scale); + objTrans.addChild(objScale); + + tetra = new Tetrahedron(true); + tetra.setAppearance(appearance); + objScale.addChild(tetra); + + // create the behavior + animate = new AnimateTexturesBehavior(tex, + urls, + appearance, + this); + animate.setSchedulingBounds(bounds); + + objTrans.addChild(animate); + + // add a rotation behavior so we can see all sides of the tetrahedron + Transform3D yAxis = new Transform3D(); + Alpha rotorAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, + 0, 0, + 4000, 0, 0, + 0, 0, 0); + RotationInterpolator rotator = + new RotationInterpolator(rotorAlpha, + objTrans, + yAxis, + 0.0f, (float) Math.PI*2.0f); + rotator.setSchedulingBounds(bounds); + objTrans.addChild(rotator); + + + // have java3d perform optimizations on this scene graph + objRoot.compile(); + + return objRoot; + } + + // callback for the animation button and delay text field + public void actionPerformed(ActionEvent e) { + Object o = e.getSource(); + + // for the animation button + if (o == animationB) { + if (animate.getEnable()) { + animate.setEnable(false); + animationB.setText("start animation"); + } + else { + animate.setEnable(true); + animationB.setText(" stop animation "); + } + } + + // for the texByRef button + else if (o == texByRef && texByRef.isSelected()) { + animate.setByReference(true); + } + // texByCopy button + else if (o == texByCopy && texByCopy.isSelected()) { + animate.setByReference(false); + } + // yUp button + else if (o == yUp && yUp.isSelected()) { + animate.setYUp(true); + } + // ydown button + else if (o == yDown && yDown.isSelected()) { + animate.setYUp(false); + } + //geomByRef button + else if (o == geomByRef) { + tetra.setByReference(true); + } + // geomByCopy button + else if (o == geomByCopy) { + tetra.setByReference(false); + } + // TYPE_INT_ARGB + else if (o == imgIntARGB) { + animate.setImageType(BufferedImage.TYPE_INT_ARGB); + } + // TYPE_4BYTE_ABGR + else if (o == img4ByteABGR) { + animate.setImageType(BufferedImage.TYPE_4BYTE_ABGR); + } + // TYPE_3BYTE_BGR + else if (o == img3ByteBGR) { + animate.setImageType(BufferedImage.TYPE_3BYTE_BGR); + } + // TYPE_CUSTOM RGBA + else if (o == imgCustomRGBA) { + animate.setImageTypeCustomRGBA(); + } + // TYPE_CUSTOM RGB + else if (o == imgCustomRGB) { + animate.setImageTypeCustomRGB(); + } + } + + // callback for the checkboxes + public void itemStateChanged(ItemEvent e) { + Object o = e.getSource(); + // for the flip checkbox + if (o == flipB) { + if (e.getStateChange() == ItemEvent.DESELECTED) { + animate.setFlipImages(false); + } + else animate.setFlipImages(true); + } + } + + // callback for the slider + public void stateChanged(ChangeEvent e) { + Object o = e.getSource(); + // for the frame delay + if (o == frameDelay) { + animate.setFrameDelay(frameDelay.getValue()); + } + } + + // allows TextureByReference to be run as an application as well as an applet + public static void main(String[] args) { + java.net.URL fnames[] = null; + if (args.length > 1) { + fnames = new java.net.URL[args.length]; + for (int i = 0; i < args.length; i++) { + try { + fnames[i] = new java.net.URL("file:" + args[i]); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + } + } + } + else { + fnames = new java.net.URL[TextureByReference.defaultFiles.length]; + for (int i = 0; i < TextureByReference.defaultFiles.length; i++) { + try { + fnames[i] = new java.net.URL("file:" + + TextureByReference.defaultFiles[i]); + } + catch (java.net.MalformedURLException ex) { + System.out.println(ex.getMessage()); + System.exit(1); + } + } + } + new MainFrame((new TextureByReference(fnames)), 650, 750); + } +} + + + + + + diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java new file mode 100644 index 0000000..b10e59b --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/ButtonPositionControls.java @@ -0,0 +1,209 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.virtual_input_device; + +import java.awt.*; +import java.awt.event.*; +import javax.vecmath.*; +import javax.media.j3d.*; + +public class ButtonPositionControls extends Panel implements PositionControls, MouseListener { + private final static int STILL=0; + private final static int MOVING_UP=1; + private final static int MOVING_DOWN=2; + private final static int MOVING_LEFT=3; + private final static int MOVING_RIGHT=4; + private final static int MOVING_FORWARD=5; + private final static int MOVING_BACK=6; + + // initial mode + private int mode = STILL; + + Vector3f position = new Vector3f(); + Vector3f orig_position = new Vector3f(); + + private Button leftB = new Button("Move Left"); + private Button rightB = new Button("Move Right"); + private Button upB = new Button("Move Up"); + private Button downB = new Button("Move Down"); + + private Button forwardB = new Button("Move Forward"); + private Button backwardB = new Button("Move Back"); + + private Button reset = new Button("Reset"); + private InputDevice device; + + private float step_rate = 0.0023f; // movement rate per millisecond + private long time_last_state_change = System.currentTimeMillis(); + + // the constructor arguments are the intitial X, Y, and Z positions + public ButtonPositionControls( float x, float y, float z ) { + + // up, down, right, and left movement buttons + Panel panPanel = new Panel(); + panPanel.setLayout( new BorderLayout() ); + panPanel.add("North", upB); + panPanel.add("East", rightB); + panPanel.add("South", downB); + panPanel.add("West", leftB); + + // forward, backward, and reset buttons + Panel p = new Panel(); + p.setLayout( new GridLayout(0,1,0,0) ); + p.add(forwardB); + p.add(backwardB); + p.add(reset); + + // set the initial position + position.x = x; + position.y = y; + position.z = z; + orig_position.set(position); + + // add a mouse listener to each button + upB.addMouseListener(this); + downB.addMouseListener(this); + leftB.addMouseListener(this); + rightB.addMouseListener(this); + forwardB.addMouseListener(this); + backwardB.addMouseListener(this); + reset.addMouseListener(this); + + this.setLayout( new BorderLayout() ); + add("East", p ); + add("West", panPanel ); + } + + public void setDevice ( InputDevice device) { + this.device = device; + } + + public void getPosition(Vector3f pos ) { + calculateMotion(); + pos.set(position); + } + + public void setPosition(Vector3f pos ) { + position.set(pos); + } + + public void setStepRate( float stepRate ) { + step_rate = stepRate; + } + + private void calculateMotion() { + + long current_time = System.currentTimeMillis(); + long elapsed_time = current_time - time_last_state_change; + + switch(mode) { + case STILL: + break; + case MOVING_LEFT: + position.x = orig_position.x - step_rate*elapsed_time; + break; + case MOVING_RIGHT: + position.x = orig_position.x + step_rate*elapsed_time; + break; + case MOVING_UP: + position.y = orig_position.y + step_rate*elapsed_time; + break; + case MOVING_DOWN: + position.y = orig_position.y - step_rate*elapsed_time; + break; + case MOVING_FORWARD: + position.z = orig_position.z - step_rate*elapsed_time; + break; + case MOVING_BACK: + position.z = orig_position.z + step_rate*elapsed_time; + break; + default: + throw( new RuntimeException("Unknown motion")); + } + } + + public void mouseClicked( MouseEvent e ) { + } + + public void mouseEntered( MouseEvent e ) { + } + + public void mouseExited( MouseEvent e ) { + } + + public void mousePressed( MouseEvent e ) { + if (e.getSource()==leftB && mode != MOVING_LEFT) { + time_last_state_change = System.currentTimeMillis(); + mode = MOVING_LEFT; + orig_position.set(position); + } else if (e.getSource()==rightB && mode != MOVING_RIGHT) { + time_last_state_change = System.currentTimeMillis(); + mode = MOVING_RIGHT; + orig_position.set(position); + } else if (e.getSource()==upB && mode != MOVING_UP) { + time_last_state_change = System.currentTimeMillis(); + mode = MOVING_UP; + orig_position.set(position); + } else if (e.getSource()==downB && mode != MOVING_DOWN) { + time_last_state_change = System.currentTimeMillis(); + mode = MOVING_DOWN; + orig_position.set(position); + } else if (e.getSource()==forwardB && mode != MOVING_FORWARD) { + time_last_state_change = System.currentTimeMillis(); + mode = MOVING_FORWARD; + orig_position.set(position); + } else if (e.getSource()==backwardB && mode != MOVING_BACK) { + time_last_state_change = System.currentTimeMillis(); + mode = MOVING_BACK; + orig_position.set(position); + } else if (e.getSource()==reset) { + device.setNominalPositionAndOrientation(); + } + } + + public void mouseReleased( MouseEvent e ) { + mode = STILL; + } +} diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java new file mode 100644 index 0000000..6c83eb8 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/PositionControls.java @@ -0,0 +1,70 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.virtual_input_device; + +import java.awt.Component; +import javax.vecmath.Vector3f; + +// Classes that implement this interface must be a +// subclass of java.awt.Component +public interface PositionControls { + + /** + * Get the position + */ + public void getPosition( Vector3f pos); + + /** + * Set the position + */ + public void setPosition( Vector3f pos); + + /** + * Increment added to position each time mouse is pressed + * or if the mouse is held down each time the Sensor is + * read + */ + public void setStepRate( float stepRate ); +} diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/README.txt b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/README.txt new file mode 100644 index 0000000..f769dac --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/README.txt @@ -0,0 +1,195 @@ + Java 3D (TM) Input Device Driver Development Guide + +Topics + + * Write Once, Run Anywhere (TM) + * Overview of the InputDevice and Sensor APIs + * Recipe for an Application Program that Uses Input Devices + * Location for Installation of Device Drivers + * Using a Preexistent Native Driver + * Package Naming Conventions + * Device Driver Constructor + * Driver Scheduling and Blocking Semantics + + +Write Once, Run Anywhere + +Platform independence is the cornerstone of the Java (TM) platform. +This vision now extends to external input devices as well. The +overarching goal of the Java 3D input device architecture is to enable +Java programs that use devices to run in a platform independent +manner. + +We encourage developers to use Java APIs for their drivers. APIs such +as the javax.comm API allow platform independent access to serial and +parallel ports. However, even if a driver is partially written with +native code, the Java 3D InputDevice interface is layered on top of the +driver such that once the native portion of the driver has been +installed into the local JRE, the application code is platform +independent. + +In a future release, the Java 3D team is going to release a registry +mechanism that will reside in the JRE as part of the Java 3D +installation and allow registration of device drivers. The +SimpleUniverse utility will be modified to allow querying of devices by +generic characteristics, and will subsequently look up and instantiate +the appropriate device driver registered with the registry mechanism. +The Java 3D team also expects to release a set of generic mappings for +devices. This will enable applications to count on the same behavior +from different drivers for similar types of devices. There will also +be personalized profiles that enable a user to specify device mappings +for features like dominant hand preference and eye position. + + +Overview of the InputDevice and Sensor APIs + +Java 3D abstracts the concept of a device via the InputDevice +interface. The developer's implementation of the InputDevice interface +is layered on top of the device driver. The device may be a real +device such as a joystick or it may be a virtual device such as a piece +of Java code that does transform calculations. + +A device sends data back to Java 3D by placing values into Sensor +objects which the device code manages and updates. The Sensor class +encapsulates a transform and a timestamp. The transform is specified +in the TrackerBase coordinate system. + +Java 3D schedules calls to the device's pollAndProcessInput routine, +which is a method in the InputDevice interface. This method is +responsible for updating the devices sensor values. The sensors' +values and time stamps are read by a user's behavior code and/or each +frame (by the Java 3D implementation) when head tracking is enabled. +There are several options for scheduling, and they are detailed in the +InputDevice javadoc and in the section below entitled "Driver +Scheduling and Blocking Semantics." + +Please read the javadocs for InputDevice and Sensor for more detailed +information. There is also a sample program in the Java 3D release +called VirtualInputDevice, which implements these concepts in Java code. + + +Recipe for an Application Program that Uses Input Devices + +Please see the Java 3D example program in the examples directory called +VirtualInputDevice for an example of using this code recipe: + 1) Implement the InputDevice interface with a class of your own + 2) Call the device's constructor from your main program + 3) Call initialize() on the device + 4) Call PhysicalEnvironment.addInputDevice(InputDevice) or if you are + using SimpleUniverse, call SimpleUniverse.getViewer(). + getPhysicalEnvironment().addInputDevice(InputDevice) + 5) Assuming you want to modify the viewer's transform with the device: + add a WakeupOnElapsedFrames behavior to your scene graph that wakes + up every frame and in the processStimulus method modify the view + transform with the transform you pull out of Sensor.getRead. + +In a future release, it will be possible to replace steps 2, 3, & 4 with +a single method call to the SimpleUniverse utility. + + +Location for Installation of Device Drivers + +There are two suggested ways to package and distribute drivers. + +If a driver is written entirely in Java and if it is tightly coupled +with a particular application without the expectation of reuse in other +applications, then it should be bundled and distributed with the +application itself. + +If a driver is not associated with any particular application program, +if it contains any native code, or if it is expected to be used by more +than one application program, then it should be installed directly into +the end user's local JRE. It is expected that most drivers for real +devices fall into this category. On the Solaris platform, the Java +portion of the driver should be installed into jre/lib/ext as a +uniquely named jar file and if there is native code it should be +compiled into a shared object and installed into jre/lib/sparc. On the +Win32 platform, the Java portion of the driver should be installed into +jre\lib\ext as a uniquely named jar file and if there is native code it +should be compiled into a standard dynamically linked library (dll) and +installed into jre\bin. + + +Using a Preexistent Native Driver + +It is possible to make a Java 3D driver out of a preexistent native +driver. In order to do this, you need to create an InputDevice +interface that uses JNI to access the associated native driver methods +whenever the corresponding InputDevice interface method is called from +Java 3D. The native portion of the driver must be installed into the +target JRE. + + +Package Naming Conventions + +All device drivers that are installed into the JRE should be part of a +package that follows both standard Java and Java 3D naming +conventions. For instance, an input device driver should be placed +into a package called +com..j3d.drivers.input.. The package should +be jarred up into a jar file that has a unique name. + +Any native .so or .dll files installed into the JRE should be uniquely +named. + + +Device Driver Constructor + +The constructor arguments for a device driver must be an array of +strings. So a driver should have a single public constructor that +takes an array of strings. The idea behind this requirement is that +eventually the Java 3D registry will contain an array of string +arguments to be sent to the device constructor at instantiation time. +The SimpleUniverse API will also make a provision for optional String +arguments to be added to the array of String arguments found in the +registry. + + +Driver Scheduling and Blocking Semantics + +When a device is registered with Java 3D via the +PhysicalEnvironment.addInputDevice(InputDevice) method call, +InputDevice.getProcessingMode() is called on the registered device. +This method should return one of the three processing modes defined in +the InputDevice interface: BLOCKING, NON_BLOCKING, and DEMAND_DRIVEN. + + BLOCKING signifies that the driver for a device is a blocking driver + and that it should be scheduled for regular reads by Java 3D. A + blocking driver is defined as a driver that can cause the thread + accessing the driver (the Java 3D implementation thread calling the + pollAndProcessInput method) to block while the data is being accessed + from the driver. + + NON_BLOCKING signifies that the driver for a device is a non-blocking + driver and that it should be scheduled for regular reads by Java 3D. + A non-blocking driver is defined as a driver that does not cause the + calling thread to block while data is being retrieved from the + driver. If no data is available from the device, pollAndProcessInput + should return without updating the sensor read value. + + DEMAND_DRIVEN signifies that the Java 3D implementation should not + schedule regular reads on the sensors of this device; the Java 3D + implementation will only call pollAndProcessInput when one of the + device's sensors' getRead methods is called. A DEMAND_DRIVEN driver + must always provide the current value of the sensor on demand + whenever pollAndProcessInput is called. This means that DEMAND_DRIVEN + drivers are non-blocking by definition. + +It is important that you correctly classify your driver. If it is a +NON_BLOCKING driver, most Java 3D implementations will choose to add +inertia inside the scheduling thread to avoid starvation of the other +Java 3D threads. If it is a BLOCKING driver, most Java 3D +implementations will choose to spawn a separate scheduling thread for +each BLOCKING device. If your driver is a DEMAND_DRIVEN driver, your +driver must always provide the current value upon request along with +the current time stamp. + +When running drivers with the Solaris operating system using the +Solaris reference 1.2 JRE and green threads, you should be aware that +there is a bug that forces all drivers to be BLOCKING. Thus, you +should be careful to always use native threads on the Solaris reference +1.2 JRE in order to get the expected behavior. This is not an issue +with the Solaris 1.2 Performance JRE release, which is native threads +only. + + diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java new file mode 100644 index 0000000..22fa5e3 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/RotationControls.java @@ -0,0 +1,73 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.virtual_input_device; + +import java.awt.Component; + +// Classes that implement this interface must be a subclass +// of java.awt.Component + +public interface RotationControls { + + /** + * Get the angle of Rotation around the X Axis + */ + public abstract float getXAngle(); + + /** + * Get the angle or Rotation around the Y Axis + */ + public abstract float getYAngle(); + + /** + * Get the angle or Rotation around the Z Axis + */ + public abstract float getZAngle(); + + /** + * Reset angles to original angle. + */ + public abstract void reset(); +} diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java new file mode 100644 index 0000000..4194599 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/SensorBehavior.java @@ -0,0 +1,72 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.virtual_input_device; + +import javax.media.j3d.*; +import java.util.*; + +public class SensorBehavior extends Behavior { + + private WakeupOnElapsedFrames conditions = new WakeupOnElapsedFrames(0); + private TransformGroup transformGroup; + private Sensor sensor; + private Transform3D transform = new Transform3D(); + + public SensorBehavior( TransformGroup tg, Sensor sensor ) { + transformGroup = tg; + this.sensor = sensor; + } + + public void initialize() { + wakeupOn( conditions ); + } + + public void processStimulus( Enumeration criteria ) { + sensor.getRead( transform ); + transformGroup.setTransform( transform ); + wakeupOn( conditions ); + } + +} diff --git a/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java new file mode 100644 index 0000000..5d71a42 --- /dev/null +++ b/src/classes/org/jdesktop/j3d/examples/virtual_input_device/VirtualInputDevice.java @@ -0,0 +1,260 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package org.jdesktop.j3d.examples.virtual_input_device; + +import javax.media.j3d.*; +import javax.vecmath.*; +import java.awt.*; +import java.awt.event.*; + +public class VirtualInputDevice implements InputDevice { + + private Vector3f position = new Vector3f(); + private Transform3D newTransform = new Transform3D(); + Sensor sensors[] = new Sensor[1]; + + // The wheel controls control the view platform orientation + private RotationControls rotControls; + + // The button position controls control the view platform position + private PositionControls positionControls; + + private Transform3D rotTransX = new Transform3D(); + private Transform3D rotTransY = new Transform3D(); + private Transform3D rotTransZ = new Transform3D(); + + private Vector3f initPos = new Vector3f(); + + private int processingMode; + private SensorRead sensorRead = new SensorRead(); + + // These are the settable parameters. + private boolean printvalues; + private int xscreeninitloc; + private int yscreeninitloc; + private int xscreensize; + private int yscreensize; + private float xobjinitloc; + private float yobjinitloc; + private float zobjinitloc; + private float xaxisrotinit; + private float yaxisrotinit; + private float zaxisrotinit; + + /* + * Create a device, and use the string arguments in args to construct + * the device with user preferences. + */ + public VirtualInputDevice( String[] args ) { + + // default user-definable values + printvalues = false; + xscreeninitloc = 400; + yscreeninitloc = 0; + xscreensize = 400; + yscreensize = 200; + xobjinitloc = 0.0f; + yobjinitloc = 0.0f; + zobjinitloc = 2.2f; + xaxisrotinit = 0.0f; + yaxisrotinit = 0.0f; + zaxisrotinit = 0.0f; + + + for(int i=0 ; i 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*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.width0) + 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 (float)Math.PI*2 ) return angle-(float)Math.PI*2; + if ( angle < 0.0f) return angle+(float)Math.PI*2; + return angle; + } +} -- cgit v1.2.3