diff --git a/src/sg/SpaceGame2.java b/src/sg/SpaceGame2.java index 8e5b5ef..094250c 100644 --- a/src/sg/SpaceGame2.java +++ b/src/sg/SpaceGame2.java @@ -87,6 +87,11 @@ public class SpaceGame2 extends BaseGame { /** Get a high resolution timer for FPS updates. */ timer = Timer.getTimer(); + + GameStateManager.create(); + KeyBindingManager manager = KeyBindingManager.getKeyBindingManager(); + manager.set("mem_report", KeyInput.KEY_TAB); + manager.set("exit", KeyInput.KEY_ESCAPE); /** Sets the title of our display. */ display.setTitle( TITLE ); @@ -95,6 +100,7 @@ public class SpaceGame2 extends BaseGame { @Override protected void initGame() { + GameStateManager.getInstance().cleanup(); GameStateManager.getInstance().attachChild(new MenuState("menu")); GameStateManager.getInstance().attachChild(new InGameState("ingame")); @@ -151,8 +157,7 @@ public class SpaceGame2 extends BaseGame { @Override protected void reinit() { - // TODO Auto-generated method stub - + } /** diff --git a/src/sg/states/InGameState.java b/src/sg/states/InGameState.java index 938c06f..892908b 100644 --- a/src/sg/states/InGameState.java +++ b/src/sg/states/InGameState.java @@ -12,6 +12,7 @@ import com.jme.renderer.Renderer; import com.jme.scene.Node; import com.jme.system.DisplaySystem; import com.jmex.game.state.CameraGameState; +import com.jmex.game.state.GameStateManager; import com.jmex.game.state.load.LoadingGameState; import com.jmex.physics.DynamicPhysicsNode; import com.jmex.physics.PhysicsDebugger; @@ -32,6 +33,7 @@ public class InGameState extends CameraGameState { super(name); LoadingGameState loader = new LoadingGameState(2); + GameStateManager.getInstance().attachChild(loader); loader.setActive(true); // ***************** Load the Game ********************************** @@ -62,6 +64,7 @@ public class InGameState extends CameraGameState { // ***************** Done loading ********************************** loader.setActive(false); + GameStateManager.getInstance().detachChild(loader); this.setActive(true); } diff --git a/src/sg/test/TestCapsule.java b/src/sg/test/TestCapsule.java new file mode 100644 index 0000000..bcb8827 --- /dev/null +++ b/src/sg/test/TestCapsule.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package sg.test; + +import com.jme.app.SimpleGame; +import com.jme.bounding.BoundingBox; +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.scene.shape.Capsule; + +public class TestCapsule extends SimpleGame { + + private Capsule capsule; + + private Quaternion rotQuat = new Quaternion(); + + private float angle = 0; + + private Vector3f axis = new Vector3f(0, 1, 0); + + public static void main(String[] args) { + TestCapsule app = new TestCapsule(); + app.setConfigShowMode(ConfigShowMode.AlwaysShow); + app.start(); + } + + /** + * Rotates the dome + */ + protected void simpleUpdate() { + if (tpf < 1) { + angle = angle + (tpf * 1); + if (angle > 360) { + angle = 0; + } + } + rotQuat.fromAngleAxis(angle, axis); + capsule.setLocalRotation(rotQuat); + } + + /* + * (non-Javadoc) + * + * @see com.jme.app.SimpleGame#initGame() + */ + protected void simpleInitGame() { + display.setTitle("jME - Capsule"); + + capsule = new Capsule("capsule", 20, 20, 20, 10, 30); + capsule.setLocalTranslation(new Vector3f(0, 0, -40)); + capsule.setModelBound(new BoundingBox()); + capsule.updateModelBound(); + + rootNode.attachChild(capsule); + } +} \ No newline at end of file diff --git a/src/sg/test/TestDirectionalShadowMapPass.java b/src/sg/test/TestDirectionalShadowMapPass.java new file mode 100644 index 0000000..436a8d3 --- /dev/null +++ b/src/sg/test/TestDirectionalShadowMapPass.java @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package sg.test; + +import java.util.HashMap; + +import javax.swing.ImageIcon; + +import com.jme.app.SimplePassGame; +import com.jme.bounding.BoundingBox; +import com.jme.image.Texture; +import com.jme.input.ChaseCamera; +import com.jme.input.ThirdPersonHandler; +import com.jme.light.DirectionalLight; +import com.jme.light.PointLight; +import com.jme.math.FastMath; +import com.jme.math.Vector3f; +import com.jme.renderer.ColorRGBA; +import com.jme.renderer.Renderer; +import com.jme.renderer.pass.DirectionalShadowMapPass; +import com.jme.renderer.pass.RenderPass; +import com.jme.scene.Node; +import com.jme.scene.VBOInfo; +import com.jme.scene.shape.Box; +import com.jme.scene.shape.PQTorus; +import com.jme.scene.state.CullState; +import com.jme.scene.state.FogState; +import com.jme.scene.state.TextureState; +import com.jme.util.TextureManager; +import com.jmex.terrain.TerrainPage; +import com.jmex.terrain.util.FaultFractalHeightMap; +import com.jmex.terrain.util.ProceduralTextureGenerator; + +/** + * TestDirectionShadowMapPass + * + * @author Joshua Slack + * @version $Revision: 1.15 $ + * + * @author kevglass - updated to test shadow mapping + */ +public class TestDirectionalShadowMapPass extends SimplePassGame { + private Node m_character; + private Node occluders; + private ChaseCamera chaser; + private TerrainPage page; + private FogState fs; + private Vector3f normal = new Vector3f(); + private static DirectionalShadowMapPass sPass; + + /** + * Entry point for the test, + * + * @param args + */ + public static void main(String[] args) { + TestDirectionalShadowMapPass app = new TestDirectionalShadowMapPass(); + + app.setConfigShowMode(ConfigShowMode.AlwaysShow); + app.start(); + } + + TestDirectionalShadowMapPass() { + } + + /** + * builds the scene. + * + * @see com.jme.app.BaseGame#initGame() + */ + protected void simpleInitGame() { + display.setTitle("jME - Shadow Mapping Pass Test"); + display.getRenderer().setBackgroundColor(ColorRGBA.gray.clone()); + + setupCharacter(); + setupTerrain(); + setupChaseCamera(); + setupInput(); + setupOccluders(); + + rootNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE); + + RenderPass rPass = new RenderPass(); + rPass.add(statNode); + rPass.add(rootNode); + pManager.add(rPass); + + sPass = new DirectionalShadowMapPass(new Vector3f(-1, -2, -1)); + sPass.setViewDistance(500); + sPass.add(rootNode); + sPass.addOccluder(m_character); + sPass.addOccluder(occluders); + pManager.add(sPass); + } + + protected void simpleUpdate() { + chaser.update(tpf); + float characterMinHeight = page.getHeight(m_character + .getLocalTranslation()) + + ((BoundingBox) m_character.getWorldBound()).yExtent; + if (!Float.isInfinite(characterMinHeight) + && !Float.isNaN(characterMinHeight)) { + m_character.getLocalTranslation().y = characterMinHeight; + } + + float camMinHeight = characterMinHeight + 150f; + if (!Float.isInfinite(camMinHeight) && !Float.isNaN(camMinHeight) + && cam.getLocation().y <= camMinHeight) { + cam.getLocation().y = camMinHeight; + cam.update(); + } + sPass.setViewTarget(cam.getLocation()); + } + + private void setupCharacter() { + PQTorus b = new PQTorus("torus - target", 2, 3, 2.0f, 1.0f, 64, 12); + b.setModelBound(new BoundingBox()); + b.updateModelBound(); + b.setVBOInfo(new VBOInfo(true)); + m_character = new Node("char node"); + rootNode.attachChild(m_character); + m_character.attachChild(b); + m_character.updateWorldBound(); // We do this to allow the camera setup + // access to the world bound in our + // setup code. + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + ts.setTexture(TextureManager.loadTexture( + TestDirectionalShadowMapPass.class.getClassLoader() + .getResource("jmetest/data/images/Monkey.jpg"), + Texture.MinificationFilter.BilinearNearestMipMap, + Texture.MagnificationFilter.Bilinear)); + m_character.setRenderState(ts); + } + + private void setupTerrain() { + + DirectionalLight dr = new DirectionalLight(); + dr.setEnabled(true); + dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); + dr.setAmbient(new ColorRGBA(.2f, .2f, .2f, .3f)); + dr.setDirection(new Vector3f(0.5f, -0.4f, 0).normalizeLocal()); + dr.setShadowCaster(true); + + PointLight pl = new PointLight(); + pl.setEnabled(true); + pl.setDiffuse(new ColorRGBA(.7f, .7f, .7f, 1.0f)); + pl.setAmbient(new ColorRGBA(.25f, .25f, .25f, .25f)); + pl.setLocation(new Vector3f(0, 500, 0)); + + DirectionalLight dr2 = new DirectionalLight(); + dr2.setEnabled(true); + dr2.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); + dr2.setAmbient(new ColorRGBA(.2f, .2f, .2f, .4f)); + dr2.setDirection(new Vector3f(-0.2f, -0.3f, .2f).normalizeLocal()); + dr2.setShadowCaster(true); + + CullState cs = display.getRenderer().createCullState(); + cs.setCullFace(CullState.Face.Back); + cs.setEnabled(true); + rootNode.setRenderState(cs); + + lightState.detachAll(); + lightState.attach(dr); + lightState.attach(dr2); + lightState.attach(pl); + lightState.setGlobalAmbient(new ColorRGBA(0.6f, 0.6f, 0.6f, 1.0f)); + + FaultFractalHeightMap heightMap = new FaultFractalHeightMap(257, 32, 0, + 255, 0.55f); + Vector3f terrainScale = new Vector3f(10, 1, 10); + heightMap.setHeightScale(0.001f); + page = new TerrainPage("Terrain", 33, heightMap.getSize(), + terrainScale, heightMap.getHeightMap()); + + page.setDetailTexture(1, 16); + rootNode.attachChild(page); + + ProceduralTextureGenerator pt = new ProceduralTextureGenerator( + heightMap); + pt.addTexture(new ImageIcon(TestDirectionalShadowMapPass.class + .getClassLoader() + .getResource("jmetest/data/texture/grassb.png")), -128, 0, 128); + pt.addTexture( + new ImageIcon(TestDirectionalShadowMapPass.class + .getClassLoader().getResource( + "jmetest/data/texture/dirt.jpg")), 0, 128, 255); + pt.addTexture(new ImageIcon(TestDirectionalShadowMapPass.class + .getClassLoader().getResource( + "jmetest/data/texture/highest.jpg")), 128, 255, 384); + + pt.createTexture(512); + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(), + Texture.MinificationFilter.Trilinear, + Texture.MagnificationFilter.Bilinear, true); + ts.setTexture(t1, 0); + + Texture t2 = TextureManager.loadTexture( + TestDirectionalShadowMapPass.class.getClassLoader() + .getResource("jmetest/data/texture/Detail.jpg"), + Texture.MinificationFilter.Trilinear, + Texture.MagnificationFilter.Bilinear); + ts.setTexture(t2, 1); + t2.setWrap(Texture.WrapMode.Repeat); + + t1.setApply(Texture.ApplyMode.Combine); + t1.setCombineFuncRGB(Texture.CombinerFunctionRGB.Modulate); + t1.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture); + t1.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor); + t1.setCombineSrc1RGB(Texture.CombinerSource.PrimaryColor); + t1.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor); + + t2.setApply(Texture.ApplyMode.Combine); + t2.setCombineFuncRGB(Texture.CombinerFunctionRGB.AddSigned); + t2.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture); + t2.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor); + t2.setCombineSrc1RGB(Texture.CombinerSource.Previous); + t2.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor); + rootNode.setRenderState(ts); + + fs = display.getRenderer().createFogState(); + fs.setDensity(0.5f); + fs.setEnabled(true); + fs.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f)); + fs.setEnd(1000); + fs.setStart(500); + fs.setDensityFunction(FogState.DensityFunction.Linear); + fs.setQuality(FogState.Quality.PerVertex); + rootNode.setRenderState(fs); + } + + private void setupOccluders() { + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + ts.setTexture(TextureManager.loadTexture( + TestDirectionalShadowMapPass.class.getClassLoader() + .getResource("jmetest/data/texture/rust.jpg"), + Texture.MinificationFilter.Trilinear, + Texture.MagnificationFilter.Bilinear)); + + occluders = new Node("occs"); + occluders.setRenderState(ts); + rootNode.attachChild(occluders); + for (int i = 0; i < 50; i++) { + Box b = new Box("box", new Vector3f(), 8, 50, 8); + b.setModelBound(new BoundingBox()); + b.updateModelBound(); + float x = (float) Math.random() * 2000 - 1000; + float z = (float) Math.random() * 2000 - 1000; + b + .setLocalTranslation(new Vector3f(x, + page.getHeight(x, z) + 50, z)); + page.getSurfaceNormal(b.getLocalTranslation(), normal); + if (normal != null) + b.rotateUpTo(normal); + occluders.attachChild(b); + } + occluders.lock(); + } + + private void setupChaseCamera() { + Vector3f targetOffset = new Vector3f(); + targetOffset.y = ((BoundingBox) m_character.getWorldBound()).yExtent * 1.5f; + chaser = new ChaseCamera(cam, m_character); + chaser.setTargetOffset(targetOffset); + chaser.getMouseLook().setMinRollOut(150); + chaser.setMaxDistance(300); + } + + private void setupInput() { + HashMap handlerProps = new HashMap(); + handlerProps.put(ThirdPersonHandler.PROP_DOGRADUAL, "true"); + handlerProps.put(ThirdPersonHandler.PROP_TURNSPEED, "" + + (.5f * FastMath.PI)); + handlerProps.put(ThirdPersonHandler.PROP_LOCKBACKWARDS, "true"); + handlerProps.put(ThirdPersonHandler.PROP_CAMERAALIGNEDMOVE, "true"); + handlerProps.put(ThirdPersonHandler.PROP_ROTATEONLY, "true"); + input = new ThirdPersonHandler(m_character, cam, handlerProps); + input.setActionSpeed(100f); + } +} diff --git a/src/sg/test/TestDiscreteLOD.java b/src/sg/test/TestDiscreteLOD.java new file mode 100644 index 0000000..9210a39 --- /dev/null +++ b/src/sg/test/TestDiscreteLOD.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package sg.test; + +import jmetest.renderer.TestBoxColor; + +import com.jme.app.SimpleGame; +import com.jme.bounding.BoundingBox; +import com.jme.image.Texture; +import com.jme.math.FastMath; +import com.jme.math.Quaternion; +import com.jme.math.Vector3f; +import com.jme.scene.DistanceSwitchModel; +import com.jme.scene.lod.DiscreteLodNode; +import com.jme.scene.shape.Sphere; +import com.jme.scene.state.TextureState; +import com.jme.util.TextureManager; + +/** + * TestDiscreteLOD + * @author Mark Powell + * @version $Id: TestDiscreteLOD.java,v 1.15 2006/01/13 19:37:18 renanse Exp $ + */ +public class TestDiscreteLOD extends SimpleGame { + + private Quaternion rotQuat = new Quaternion(); + private float angle = 0; + private Vector3f axis = new Vector3f(1, 1, 0); + private DiscreteLodNode dlod; + + /** + * Entry point for the test, + * @param args + */ + public static void main(String[] args) { + TestDiscreteLOD app = new TestDiscreteLOD(); + app.setConfigShowMode(ConfigShowMode.AlwaysShow); + app.start(); + } + + protected void simpleUpdate() { + if (timer.getTimePerFrame() < 1) { + angle = angle + (timer.getTimePerFrame() * 10); + if (angle > 360) + angle = 0; + } + + rotQuat.fromAngleAxis(angle * FastMath.DEG_TO_RAD, axis); + + dlod.setLocalRotation(rotQuat); + } + + /** + * builds the trimesh. + * @see com.jme.app.SimpleGame#initGame() + */ + protected void simpleInitGame() { + display.setTitle("Discrete Level of Detail Test"); + cam.setLocation(new Vector3f(0, 0, 50)); + cam.update(); + + Sphere s1 = new Sphere("Sphere", 100, 100, 25); + s1.setModelBound(new BoundingBox()); + s1.updateModelBound(); + + Sphere s2 = new Sphere("Sphere", 50, 50, 25); + s2.setModelBound(new BoundingBox()); + s2.updateModelBound(); + + Sphere s3 = new Sphere("Sphere", 30, 20, 25); + s3.setModelBound(new BoundingBox()); + s3.updateModelBound(); + + Sphere s4 = new Sphere("Sphere", 10, 10, 25); + s4.setModelBound(new BoundingBox()); + s4.updateModelBound(); + + DistanceSwitchModel m = new DistanceSwitchModel(4); + m.setModelDistance(0, 0, 100); + m.setModelDistance(1, 100, 200); + m.setModelDistance(2, 200, 300); + m.setModelDistance(3, 300, 1000); + + dlod = new DiscreteLodNode("DLOD", m); + dlod.attachChild(s1); + dlod.attachChild(s2); + dlod.attachChild(s3); + dlod.attachChild(s4); + dlod.setActiveChild(0); + rootNode.attachChild(dlod); + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + ts.setTexture( + TextureManager.loadTexture( + TestBoxColor.class.getClassLoader().getResource( + "jmetest/data/images/Monkey.jpg"), + Texture.MinificationFilter.Trilinear, + Texture.MagnificationFilter.Bilinear)); + + rootNode.setRenderState(ts); + + } +} diff --git a/src/sg/test/TestJoystick.java b/src/sg/test/TestJoystick.java new file mode 100644 index 0000000..093088f --- /dev/null +++ b/src/sg/test/TestJoystick.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package sg.test; + +import java.io.IOException; +import java.util.logging.Logger; + +import com.jme.input.InputSystem; +import com.jme.input.joystick.Joystick; +import com.jme.input.joystick.JoystickInput; + +/** + * TestJoystick + */ +public class TestJoystick { + private static final Logger logger = Logger.getLogger(TestJoystick.class + .getName()); + + public static void main(String[] args) throws IOException, + InterruptedException { + JoystickInput.setProvider(InputSystem.INPUT_SYSTEM_LWJGL); + JoystickInput input = JoystickInput.get(); + logger.info("Number of joysticks: " + input.getJoystickCount()); + logger.info("Testing all joysticks."); + + boolean go = true; + while (go) { + input.update(); + for (int x = 0; x < input.getJoystickCount(); x++) { + Joystick test = input.getJoystick(x); + for (int i = 0; i < test.getAxisCount(); i++) { + float val = test.getAxisValue(i); + if (val != 0) + logger.info("joystick #"+x+" ('"+test.getName()+"') - axis '"+test.getAxisNames()[i]+"': " + + val); + } + for (int i = 0; i < test.getButtonCount(); i++) { + boolean pushed = test.isButtonPressed(i); + if (pushed) + logger.info("joystick #"+x+" ('"+test.getName()+"') - button #"+i+" pressed."); + } + } + Thread.sleep(10); + } + } +} diff --git a/src/sg/test/TestLensFlare.java b/src/sg/test/TestLensFlare.java new file mode 100644 index 0000000..843ed95 --- /dev/null +++ b/src/sg/test/TestLensFlare.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package sg.test; + +import com.jme.app.SimpleGame; +import com.jme.bounding.BoundingBox; +import com.jme.image.Image; +import com.jme.image.Texture; +import com.jme.light.LightNode; +import com.jme.light.PointLight; +import com.jme.math.Vector3f; +import com.jme.renderer.ColorRGBA; +import com.jme.scene.Spatial.LightCombineMode; +import com.jme.scene.shape.Box; +import com.jme.scene.state.TextureState; +import com.jme.util.TextureManager; +import com.jmex.effects.LensFlare; +import com.jmex.effects.LensFlareFactory; + +/** + * TestLensFlare Test of the lens flare effect in jME. Notice + * that currently it doesn't do occlusion culling. + * + * @author Joshua Slack + * @version $Id: TestLensFlare.java,v 1.17 2007/09/21 15:46:34 nca Exp $ + */ +public class TestLensFlare extends SimpleGame { + + private LightNode lightNode; + LensFlare flare; + + public static void main(String[] args) { + TestLensFlare app = new TestLensFlare(); + app.setConfigShowMode(ConfigShowMode.AlwaysShow); + app.start(); + } + + protected void simpleInitGame() { + + display.setTitle("Lens Flare!"); + cam.setLocation(new Vector3f(0.0f, 0.0f, 200.0f)); + cam.update(); + lightState.detachAll(); + + PointLight dr = new PointLight(); + dr.setEnabled(true); + dr.setDiffuse(ColorRGBA.white.clone()); + dr.setAmbient(ColorRGBA.gray.clone()); + dr.setLocation(new Vector3f(0f, 0f, 0f)); + + lightState.attach(dr); + lightState.setTwoSidedLighting(true); + + lightNode = new LightNode("light"); + lightNode.setLight(dr); + + Vector3f min2 = new Vector3f(-0.5f, -0.5f, -0.5f); + Vector3f max2 = new Vector3f(0.5f, 0.5f, 0.5f); + Box lightBox = new Box("box", min2, max2); + lightBox.setModelBound(new BoundingBox()); + lightBox.updateModelBound(); + lightNode.attachChild(lightBox); + lightNode.setLocalTranslation(new Vector3f(-14f, 14f, -14f)); + + Box box2 = new Box("blocker", new Vector3f(-5, -5, -5), new Vector3f(5, + 5, 5)); + box2.setModelBound(new BoundingBox()); + box2.updateModelBound(); + box2.setLocalTranslation(new Vector3f(100, 0, 0)); + rootNode.attachChild(box2); + + // clear the lights from this lightbox so the lightbox itself doesn't + // get affected by light: + lightBox.setLightCombineMode(LightCombineMode.Off); + + // Setup the lensflare textures. + TextureState[] tex = new TextureState[4]; + tex[0] = display.getRenderer().createTextureState(); + tex[0].setTexture(TextureManager.loadTexture(LensFlare.class + .getClassLoader() + .getResource("jmetest/data/texture/flare1.png"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear, Image.Format.RGBA8, + 0.0f, true)); + tex[0].setEnabled(true); + + tex[1] = display.getRenderer().createTextureState(); + tex[1].setTexture(TextureManager.loadTexture(LensFlare.class + .getClassLoader() + .getResource("jmetest/data/texture/flare2.png"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear)); + tex[1].setEnabled(true); + + tex[2] = display.getRenderer().createTextureState(); + tex[2].setTexture(TextureManager.loadTexture(LensFlare.class + .getClassLoader() + .getResource("jmetest/data/texture/flare3.png"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear)); + tex[2].setEnabled(true); + + tex[3] = display.getRenderer().createTextureState(); + tex[3].setTexture(TextureManager.loadTexture(LensFlare.class + .getClassLoader() + .getResource("jmetest/data/texture/flare4.png"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear)); + tex[3].setEnabled(true); + + flare = LensFlareFactory.createBasicLensFlare("flare", tex); + flare.setRootNode(rootNode); + //lightNode.attachChild(flare); + Box box = new Box("my box", new Vector3f(0, 0, 0), 10, 10, 10); + box.setModelBound(new BoundingBox()); + box.updateModelBound(); + rootNode.attachChild(box); + rootNode.attachChild(lightNode); + + // notice that it comes at the end + lightNode.attachChild(flare); + + } + +} diff --git a/src/sg/test/TestLoadingGameState.java b/src/sg/test/TestLoadingGameState.java new file mode 100644 index 0000000..ed89182 --- /dev/null +++ b/src/sg/test/TestLoadingGameState.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package sg.test; + +import java.util.concurrent.Callable; + +import com.jme.util.GameTaskQueueManager; +import com.jmex.game.StandardGame; +import com.jmex.game.state.DebugGameState; +import com.jmex.game.state.GameStateManager; +import com.jmex.game.state.load.LoadingGameState; + +/** + * @author Matthew D. Hicks + */ +public class TestLoadingGameState { + public static void main(String[] args) throws Exception { + StandardGame game = new StandardGame("Test LoadingGameState"); + game.getSettings().clear(); + game.start(); + + GameTaskQueueManager.getManager().update(new Callable(){ + + public Void call() throws Exception { + // Create LoadingGameState and enable + final LoadingGameState loading = new LoadingGameState(); + GameStateManager.getInstance().attachChild(loading); + loading.setActive(true); + + // Enable DebugGameState + DebugGameState debug = new DebugGameState(); + GameStateManager.getInstance().attachChild(debug); + debug.setActive(true); + + GameTaskQueueManager.getManager().update(new LoadingTask(loading, 0)); + + return null; + } + }); + } + + private static class LoadingTask implements Callable { + private final LoadingGameState loading; + private final int progress; + + public LoadingTask(LoadingGameState loading, int progress) { + super(); + this.loading = loading; + this.progress = progress; + } + + public Void call() throws Exception { + String status; + if (progress == 100) { + status = "I'm Finished!"; + } else if (progress > 80) { + status = "Almost There!"; + } else if (progress > 70) { + status = "Loading Something Extremely Useful"; + } else if (progress > 50) { + status = "More Than Half-Way There!"; + } else if (progress > 20) { + status = "Loading Something That You Probably Won't Care About"; + } else { + status = "Started Loading"; + } + + Thread.sleep(100); + loading.setProgress(progress / 100.0f, status); + + if (progress < 100) { + GameTaskQueueManager.getManager().update(new LoadingTask(loading, progress + 1)); + } + return null; + } + } +} diff --git a/src/sg/test/TestShaderTexturing.java b/src/sg/test/TestShaderTexturing.java new file mode 100644 index 0000000..7aabe8f --- /dev/null +++ b/src/sg/test/TestShaderTexturing.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package sg.test; + +import com.jme.app.SimpleGame; +import com.jme.image.Texture; +import com.jme.scene.shape.Quad; +import com.jme.scene.state.GLSLShaderObjectsState; +import com.jme.scene.state.TextureState; +import com.jme.util.TextureManager; + +public class TestShaderTexturing extends SimpleGame { + + public static void main(String[] args) { + TestShaderTexturing app = new TestShaderTexturing(); + app.setConfigShowMode(ConfigShowMode.AlwaysShow); + app.start(); + } + + @Override + protected void simpleInitGame() { + String shader = "uniform sampler2D tex0, tex1, tex2, tex3, tex4;" + + " void main(){" + + "vec2 tc0 = vec2(gl_TexCoord[1].x, gl_TexCoord[1].y);" + + "vec2 tc1 = vec2(gl_TexCoord[0].x, gl_TexCoord[0].y);" + + "vec4 result = texture2D(tex0,tc0);" + + "vec4 col0 = texture2D(tex1, tc0);" + + "vec4 alp0= texture2D(tex2, tc1);" + + "result = mix(result, col0, alp0.r);" + + "vec4 col1 = texture2D(tex3, tc0);" + + "vec4 alp1= texture2D(tex4, tc1);" + + "result = mix(result, col1, alp1.r);" + + "gl_FragColor = result * gl_Color;" + "}"; + + GLSLShaderObjectsState so = display.getRenderer() + .createGLSLShaderObjectsState(); + so.load(null, shader); + so.setUniform("tex0", 0); + so.setUniform("tex1", 1); + so.setUniform("tex2", 2); + so.setUniform("tex3", 3); + so.setUniform("tex4", 4); + so.setEnabled(true); + + Quad mesh = new Quad("mesh", 10, 10); + mesh.copyTextureCoordinates(0, 1, 1.0f); + mesh.setRenderState(so); + + TextureState ts = display.getRenderer().createTextureState(); + Texture t0 = TextureManager.loadTexture(ClassLoader + .getSystemResource("jmetest/data/texture/Decal.PNG"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.NearestNeighbor); + ts.setTexture(t0, 0); + Texture t1 = TextureManager.loadTexture(ClassLoader + .getSystemResource("jmetest/data/texture/highest.jpg"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear); + ts.setTexture(t1, 1); + Texture t2 = TextureManager.loadTexture(ClassLoader + .getSystemResource("jmetest/data/cursor/test.PNG"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.NearestNeighbor, 0, true); + t2.setWrap(Texture.WrapMode.EdgeClamp); + ts.setTexture(t2, 2); + Texture t3 = TextureManager.loadTexture(ClassLoader + .getSystemResource("jmetest/data/texture/highest.jpg"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear); + ts.setTexture(t3, 3); + Texture t4 = TextureManager.loadTexture(ClassLoader + .getSystemResource("jmetest/data/cursor/test.PNG"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.NearestNeighbor, 0, false); + t4.setWrap(Texture.WrapMode.EdgeClamp); + ts.setTexture(t4, 4); + + mesh.setRenderState(ts); + rootNode.attachChild(mesh); + + lightState.setEnabled(false); + } + +} diff --git a/src/sg/test/TestShadowPass.java b/src/sg/test/TestShadowPass.java new file mode 100644 index 0000000..55f7a49 --- /dev/null +++ b/src/sg/test/TestShadowPass.java @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package sg.test; + +import java.util.HashMap; + +import javax.swing.ImageIcon; + +import jmetest.renderer.ShadowTweaker; + +import com.jme.app.SimplePassGame; +import com.jme.bounding.BoundingBox; +import com.jme.image.Texture; +import com.jme.input.ChaseCamera; +import com.jme.input.KeyBindingManager; +import com.jme.input.KeyInput; +import com.jme.input.ThirdPersonHandler; +import com.jme.light.DirectionalLight; +import com.jme.light.PointLight; +import com.jme.math.FastMath; +import com.jme.math.Vector3f; +import com.jme.renderer.ColorRGBA; +import com.jme.renderer.Renderer; +import com.jme.renderer.pass.RenderPass; +import com.jme.renderer.pass.ShadowedRenderPass; +import com.jme.scene.Node; +import com.jme.scene.VBOInfo; +import com.jme.scene.shape.Box; +import com.jme.scene.shape.PQTorus; +import com.jme.scene.state.CullState; +import com.jme.scene.state.FogState; +import com.jme.scene.state.TextureState; +import com.jme.util.TextureManager; +import com.jmex.terrain.TerrainPage; +import com.jmex.terrain.util.FaultFractalHeightMap; +import com.jmex.terrain.util.ProceduralTextureGenerator; + +/** + * TestShadowPass + * + * @author Joshua Slack + * @version $Revision: 1.15 $ + */ +public class TestShadowPass extends SimplePassGame { + private Node m_character; + private Node occluders; + private ChaseCamera chaser; + private TerrainPage page; + private FogState fs; + private Vector3f normal = new Vector3f(); + private static ShadowedRenderPass sPass = new ShadowedRenderPass(); + private static boolean debug = true; + + /** + * Entry point for the test, + * + * @param args + */ + public static void main(String[] args) { + TestShadowPass app = new TestShadowPass(); + if (debug) new ShadowTweaker(sPass).setVisible(true); + + app.setConfigShowMode(ConfigShowMode.AlwaysShow); + app.start(); + } + + TestShadowPass() { + stencilBits = 4; // we need a minimum stencil buffer at least. + + } + + /** + * builds the scene. + * + * @see com.jme.app.BaseGame#initGame() + */ + protected void simpleInitGame() { + display.setTitle("jME - Shadow Volume Test : X - enable/disable shadows"); + display.getRenderer().setBackgroundColor(ColorRGBA.gray.clone()); + + setupCharacter(); + setupTerrain(); + setupChaseCamera(); + setupInput(); + setupOccluders(); + + rootNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE); + + /** Assign key X to action "toggle_shadows". */ + KeyBindingManager.getKeyBindingManager().set("toggle_shadows", + KeyInput.KEY_X); + + + sPass.add(rootNode); + sPass.addOccluder(m_character); + sPass.addOccluder(occluders); + sPass.setRenderShadows(true); + sPass.setLightingMethod(ShadowedRenderPass.LightingMethod.Additive); + pManager.add(sPass); + + RenderPass rPass = new RenderPass(); + rPass.add(statNode); + pManager.add(rPass); + } + + protected void simpleUpdate() { + chaser.update(tpf); + float characterMinHeight = page.getHeight(m_character + .getLocalTranslation())+((BoundingBox)m_character.getWorldBound()).yExtent; + if (!Float.isInfinite(characterMinHeight) && !Float.isNaN(characterMinHeight)) { + m_character.getLocalTranslation().y = characterMinHeight; + } + + float camMinHeight = characterMinHeight + 150f; + if (!Float.isInfinite(camMinHeight) && !Float.isNaN(camMinHeight) + && cam.getLocation().y <= camMinHeight) { + cam.getLocation().y = camMinHeight; + cam.update(); + } + + + if (KeyBindingManager.getKeyBindingManager().isValidCommand( + "toggle_shadows", false)) { + sPass.setRenderShadows(!sPass.getRenderShadows()); + } + } + + private void setupCharacter() { + PQTorus b = new PQTorus("torus - target", 2, 3, 2.0f, 1.0f, 64, 12); + b.setModelBound(new BoundingBox()); + b.updateModelBound(); + b.setVBOInfo(new VBOInfo(true)); + m_character = new Node("char node"); + rootNode.attachChild(m_character); + m_character.attachChild(b); + m_character.updateWorldBound(); // We do this to allow the camera setup access to the world bound in our setup code. + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + ts.setTexture( + TextureManager.loadTexture( + TestShadowPass.class.getClassLoader().getResource( + "jmetest/data/images/Monkey.jpg"), + Texture.MinificationFilter.BilinearNearestMipMap, + Texture.MagnificationFilter.Bilinear)); + m_character.setRenderState(ts); + } + + private void setupTerrain() { + + DirectionalLight dr = new DirectionalLight(); + dr.setEnabled(true); + dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); + dr.setAmbient(new ColorRGBA(.2f, .2f, .2f, .3f)); + dr.setDirection(new Vector3f(0.5f, -0.4f, 0).normalizeLocal()); + dr.setShadowCaster(true); + + PointLight pl = new PointLight(); + pl.setEnabled(true); + pl.setDiffuse(new ColorRGBA(.7f, .7f, .7f, 1.0f)); + pl.setAmbient(new ColorRGBA(.25f, .25f, .25f, .25f)); + pl.setLocation(new Vector3f(0,500,0)); + pl.setShadowCaster(true); + + DirectionalLight dr2 = new DirectionalLight(); + dr2.setEnabled(true); + dr2.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); + dr2.setAmbient(new ColorRGBA(.2f, .2f, .2f, .4f)); + dr2.setDirection(new Vector3f(-0.2f, -0.3f, .2f).normalizeLocal()); + dr2.setShadowCaster(true); + + CullState cs = display.getRenderer().createCullState(); + cs.setCullFace(CullState.Face.Back); + cs.setEnabled(true); + rootNode.setRenderState(cs); + + lightState.detachAll(); + lightState.attach(dr); + lightState.attach(dr2); + lightState.attach(pl); + lightState.setGlobalAmbient(new ColorRGBA(0.6f, 0.6f, 0.6f, 1.0f)); + + FaultFractalHeightMap heightMap = new FaultFractalHeightMap(257, 32, 0, + 255, 0.55f); + Vector3f terrainScale = new Vector3f(10, 1, 10); + heightMap.setHeightScale(0.001f); + page = new TerrainPage("Terrain", 33, heightMap.getSize(), + terrainScale, heightMap.getHeightMap()); + + page.setDetailTexture(1, 16); + rootNode.attachChild(page); + + ProceduralTextureGenerator pt = new ProceduralTextureGenerator( + heightMap); + pt.addTexture(new ImageIcon(TestShadowPass.class.getClassLoader() + .getResource("jmetest/data/texture/grassb.png")), -128, 0, 128); + pt.addTexture(new ImageIcon(TestShadowPass.class.getClassLoader() + .getResource("jmetest/data/texture/dirt.jpg")), 0, 128, 255); + pt.addTexture(new ImageIcon(TestShadowPass.class.getClassLoader() + .getResource("jmetest/data/texture/highest.jpg")), 128, 255, + 384); + + pt.createTexture(512); + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear, true); + ts.setTexture(t1, 0); + + Texture t2 = TextureManager.loadTexture(TestShadowPass.class + .getClassLoader() + .getResource("jmetest/data/texture/Detail.jpg"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear); + ts.setTexture(t2, 1); + t2.setWrap(Texture.WrapMode.Repeat); + + t1.setApply(Texture.ApplyMode.Combine); + t1.setCombineFuncRGB(Texture.CombinerFunctionRGB.Modulate); + t1.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture); + t1.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor); + t1.setCombineSrc1RGB(Texture.CombinerSource.PrimaryColor); + t1.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor); + + t2.setApply(Texture.ApplyMode.Combine); + t2.setCombineFuncRGB(Texture.CombinerFunctionRGB.AddSigned); + t2.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture); + t2.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor); + t2.setCombineSrc1RGB(Texture.CombinerSource.Previous); + t2.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor); + rootNode.setRenderState(ts); + + fs = display.getRenderer().createFogState(); + fs.setDensity(0.5f); + fs.setEnabled(true); + fs.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f)); + fs.setEnd(1000); + fs.setStart(500); + fs.setDensityFunction(FogState.DensityFunction.Linear); + fs.setQuality(FogState.Quality.PerVertex); + rootNode.setRenderState(fs); + } + + private void setupOccluders() { + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + ts.setTexture( + TextureManager.loadTexture( + TestShadowPass.class.getClassLoader().getResource( + "jmetest/data/texture/rust.jpg"), + Texture.MinificationFilter.Trilinear, + Texture.MagnificationFilter.Bilinear)); + + occluders = new Node("occs"); + occluders.setRenderState(ts); + rootNode.attachChild(occluders); + for (int i = 0; i < 50; i++) { + Box b = new Box("box", new Vector3f(), 8, 50, 8); + b.setModelBound(new BoundingBox()); + b.updateModelBound(); + float x = (float) Math.random() * 2000 - 1000; + float z = (float) Math.random() * 2000 - 1000; + b.setLocalTranslation(new Vector3f(x, page.getHeight(x, z)+50, z)); + page.getSurfaceNormal(b.getLocalTranslation(), normal ); + if (normal != null) + b.rotateUpTo(normal); + occluders.attachChild(b); + } + occluders.lock(); + } + + private void setupChaseCamera() { + Vector3f targetOffset = new Vector3f(); + targetOffset.y = ((BoundingBox) m_character.getWorldBound()).yExtent * 1.5f; + chaser = new ChaseCamera(cam, m_character); + chaser.setTargetOffset(targetOffset); + chaser.getMouseLook().setMinRollOut(150); + chaser.setMaxDistance(300); + } + + private void setupInput() { + HashMap handlerProps = new HashMap(); + handlerProps.put(ThirdPersonHandler.PROP_DOGRADUAL, "true"); + handlerProps.put(ThirdPersonHandler.PROP_TURNSPEED, ""+(.5f * FastMath.PI)); + handlerProps.put(ThirdPersonHandler.PROP_LOCKBACKWARDS, "true"); + handlerProps.put(ThirdPersonHandler.PROP_CAMERAALIGNEDMOVE, "true"); + handlerProps.put(ThirdPersonHandler.PROP_ROTATEONLY, "true"); + input = new ThirdPersonHandler(m_character, cam, handlerProps); + input.setActionSpeed(100f); + } +} diff --git a/src/sg/test/TestThirdPersonController.java b/src/sg/test/TestThirdPersonController.java new file mode 100644 index 0000000..afd8516 --- /dev/null +++ b/src/sg/test/TestThirdPersonController.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2003-2009 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package sg.test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.swing.ImageIcon; + +import jmetest.terrain.TestTerrain; + +import com.jme.app.SimpleGame; +import com.jme.bounding.BoundingBox; +import com.jme.image.Texture; +import com.jme.input.ChaseCamera; +import com.jme.input.InputSystem; +import com.jme.input.ThirdPersonHandler; +import com.jme.input.joystick.Joystick; +import com.jme.input.joystick.JoystickInput; +import com.jme.input.thirdperson.ThirdPersonJoystickPlugin; +import com.jme.light.DirectionalLight; +import com.jme.math.FastMath; +import com.jme.math.Vector3f; +import com.jme.renderer.ColorRGBA; +import com.jme.renderer.Renderer; +import com.jme.scene.Node; +import com.jme.scene.shape.Box; +import com.jme.scene.state.CullState; +import com.jme.scene.state.FogState; +import com.jme.scene.state.TextureState; +import com.jme.util.TextureManager; +import com.jmex.terrain.TerrainPage; +import com.jmex.terrain.util.FaultFractalHeightMap; +import com.jmex.terrain.util.ProceduralTextureGenerator; + +/** + * TestThirdPersonController + * + * @author Joshua Slack + * @version $Revision: 1.21 $ + */ +public class TestThirdPersonController extends SimpleGame { + private static final Logger logger = Logger + .getLogger(TestThirdPersonController.class.getName()); + + private Node m_character; + + private ChaseCamera chaser; + + private TerrainPage page; + + /** + * Entry point for the test, + * + * @param args + */ + public static void main(String[] args) { + try { + JoystickInput.setProvider(InputSystem.INPUT_SYSTEM_LWJGL); + } catch (Exception e) { + logger.logp(Level.SEVERE, TestThirdPersonController.class.toString(), + "main(args)", "Exception", e); + } + TestThirdPersonController app = new TestThirdPersonController(); + app.setConfigShowMode(ConfigShowMode.AlwaysShow); + app.start(); + } + + /** + * builds the scene. + * + * @see com.jme.app.SimpleGame#initGame() + */ + protected void simpleInitGame() { + display.setTitle("jME - 3rd person controller test"); + + setupCharacter(); + setupTerrain(); + setupChaseCamera(); + setupInput(); + setupJoystick(); + } + + protected void simpleUpdate() { + chaser.update(tpf); + float camMinHeight = page.getHeight(cam.getLocation()) + 2f; + if (!Float.isInfinite(camMinHeight) && !Float.isNaN(camMinHeight) + && cam.getLocation().y <= camMinHeight) { + cam.getLocation().y = camMinHeight; + cam.update(); + } + + float characterMinHeight = page.getHeight(m_character + .getLocalTranslation())+((BoundingBox)m_character.getWorldBound()).yExtent; + if (!Float.isInfinite(characterMinHeight) && !Float.isNaN(characterMinHeight)) { + m_character.getLocalTranslation().y = characterMinHeight; + } + } + + private void setupCharacter() { + Box b = new Box("box", new Vector3f(), 5,5,5); + b.setModelBound(new BoundingBox()); + b.updateModelBound(); + m_character = new Node("char node"); + rootNode.attachChild(m_character); + m_character.attachChild(b); + m_character.updateWorldBound(); // We do this to allow the camera setup access to the world bound in our setup code. + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + ts.setTexture( + TextureManager.loadTexture( + TestThirdPersonController.class.getClassLoader().getResource( + "jmetest/data/images/Monkey.jpg"), + Texture.MinificationFilter.BilinearNearestMipMap, + Texture.MagnificationFilter.Bilinear)); + m_character.setRenderState(ts); + } + + private void setupTerrain() { + rootNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE); + + display.getRenderer().setBackgroundColor( + new ColorRGBA(0.5f, 0.5f, 0.5f, 1)); + + DirectionalLight dr = new DirectionalLight(); + dr.setEnabled(true); + dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); + dr.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)); + dr.setDirection(new Vector3f(0.5f, -0.5f, 0)); + + CullState cs = display.getRenderer().createCullState(); + cs.setCullFace(CullState.Face.Back); + cs.setEnabled(true); + rootNode.setRenderState(cs); + + lightState.detachAll(); + lightState.attach(dr); + + FaultFractalHeightMap heightMap = new FaultFractalHeightMap(257, 32, 0, + 255, 0.75f); + Vector3f terrainScale = new Vector3f(10, 1, 10); + heightMap.setHeightScale(0.001f); + page = new TerrainPage("Terrain", 33, heightMap.getSize(), + terrainScale, heightMap.getHeightMap()); + + page.setDetailTexture(1, 16); + rootNode.attachChild(page); + + ProceduralTextureGenerator pt = new ProceduralTextureGenerator( + heightMap); + pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader() + .getResource("jmetest/data/texture/grassb.png")), -128, 0, 128); + pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader() + .getResource("jmetest/data/texture/dirt.jpg")), 0, 128, 255); + pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader() + .getResource("jmetest/data/texture/highest.jpg")), 128, 255, + 384); + + pt.createTexture(512); + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled(true); + Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear, true); + ts.setTexture(t1, 0); + + Texture t2 = TextureManager.loadTexture(TestThirdPersonController.class + .getClassLoader() + .getResource("jmetest/data/texture/Detail.jpg"), + Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear); + ts.setTexture(t2, 1); + t2.setWrap(Texture.WrapMode.Repeat); + + t1.setApply(Texture.ApplyMode.Combine); + t1.setCombineFuncRGB(Texture.CombinerFunctionRGB.Modulate); + t1.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture); + t1.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor); + t1.setCombineSrc1RGB(Texture.CombinerSource.PrimaryColor); + t1.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor); + + t2.setApply(Texture.ApplyMode.Combine); + t2.setCombineFuncRGB(Texture.CombinerFunctionRGB.AddSigned); + t2.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture); + t2.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor); + t2.setCombineSrc1RGB(Texture.CombinerSource.Previous); + t2.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor); + rootNode.setRenderState(ts); + + FogState fs = display.getRenderer().createFogState(); + fs.setDensity(0.5f); + fs.setEnabled(true); + fs.setColor(new ColorRGBA(0.5f, 0.5f, 0.5f, 0.5f)); + fs.setEnd(1000); + fs.setStart(500); + fs.setDensityFunction(FogState.DensityFunction.Linear); + fs.setQuality(FogState.Quality.PerVertex); + rootNode.setRenderState(fs); + } + + private void setupChaseCamera() { + Vector3f targetOffset = new Vector3f(); + targetOffset.y = ((BoundingBox) m_character.getWorldBound()).yExtent * 1.5f; + chaser = new ChaseCamera(cam, m_character); + chaser.setTargetOffset(targetOffset); + } + + private void setupInput() { + HashMap handlerProps = new HashMap(); + handlerProps.put(ThirdPersonHandler.PROP_DOGRADUAL, "true"); + handlerProps.put(ThirdPersonHandler.PROP_TURNSPEED, ""+(1.0f * FastMath.PI)); + handlerProps.put(ThirdPersonHandler.PROP_LOCKBACKWARDS, "false"); + handlerProps.put(ThirdPersonHandler.PROP_CAMERAALIGNEDMOVE, "true"); + input = new ThirdPersonHandler(m_character, cam, handlerProps); + input.setActionSpeed(100f); + } + + private void setupJoystick() { + ArrayList joys = JoystickInput.get().findJoysticksByAxis("X Axis", "Y Axis", "Z Axis", "Z Rotation"); + Joystick joy = joys.size() >= 1 ? joys.get(0) : null; + if (joy != null) { + ThirdPersonJoystickPlugin plugin = new ThirdPersonJoystickPlugin(joy, joy.findAxis("X Axis"), joy.findAxis("Y Axis"), joy.findAxis("Z Axis"), joy.findAxis("Z Rotation")); + ((ThirdPersonHandler)input).setJoystickPlugin(plugin); + chaser.getMouseLook().setJoystickPlugin(plugin); + } + } +}