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);
+ }
+ }
+}