Hi all,
I tried adding collision detection to flagrush tutorial lesson 5 - physics space, added staticPhysicsNode terrainNode for terrain and dynamicPhysicsNode for the box and when I load it causes jitters?? All I have done is added simple physics and for some reason it does not work. I am including the code, it compiles and runs - can someone tell me what is wrong here?
Lesson5.java
package lesson5;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import jmetest.renderer.TestSkybox;
import jmetest.terrain.TestTerrain;
import com.jme.app.BaseGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.ChaseCamera;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.thirdperson.ThirdPersonMouseLook;
import com.jme.light.DirectionalLight;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.shape.Box;
import com.jme.scene.state.CullState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.StaticPhysicsNode;
public class Lesson5 extends BaseGame {
private static final Logger logger = Logger.getLogger(Lesson5.class
.getName());
private TerrainBlock tb;
private ForceFieldFence fence;
private Skybox skybox;
private Node player;
protected InputHandler input;
protected Timer timer;
private Camera cam;
private ChaseCamera chaser;
private Node scene;
private int width, height, depth, freq;
private boolean fullscreen;
private PhysicsSpace physicsSpace;
private DynamicPhysicsNode playerNode;
private StaticPhysicsNode terrainNode;
public static void main(String[] args) {
Lesson5 app = new Lesson5();
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG, Lesson5.class
.getClassLoader().getResource(
"jmetest/data/images/FlagRush.png"));
app.start();
}
protected void update(float interpolation)
{
// update the time to get the framerate
timer.update();
interpolation = timer.getTimePerFrame();
getPhysicsSpace().update(interpolation);
//update the keyboard input (move the player around)
input.update(interpolation);
//update the chase camera to handle the player moving around.
chaser.update(interpolation);
fence.update(interpolation);
//we want to keep the skybox around our eyes, so move it with
//the camera
skybox.setLocalTranslation(cam.getLocation());
// if escape was pressed, we exit
if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit")) {
finished = true;
}
if(cam.getLocation().y < (tb.getHeight(cam.getLocation())+2)) {
cam.getLocation().y = tb.getHeight(cam.getLocation()) + 2;
cam.update();
}
float characterMinHeight = tb.getHeight(playerNode
.getLocalTranslation())+((BoundingBox)playerNode.getWorldBound()).yExtent;
if (!Float.isInfinite(characterMinHeight) && !Float.isNaN(characterMinHeight)) {
playerNode.getLocalTranslation().y = characterMinHeight;
}
scene.updateGeometricState(interpolation, true);
}
protected void render(float interpolation) {
// Clear the screen
display.getRenderer().clearBuffers();
display.getRenderer().draw(scene);
}
protected void initSystem() {
// store the properties information
width = properties.getWidth();
height = properties.getHeight();
depth = properties.getDepth();
freq = properties.getFreq();
fullscreen = properties.getFullscreen();
try {
display = DisplaySystem.getDisplaySystem(properties.getRenderer());
display.createWindow(width, height, depth, freq, fullscreen);
cam = display.getRenderer().createCamera(width, height);
} catch (JmeException e) {
logger.log(Level.SEVERE, "Could not create displaySystem", e);
System.exit(1);
}
display.getRenderer().setBackgroundColor(ColorRGBA.black.clone());
cam.setFrustumPerspective(45.0f, (float) width / (float) height, 1,
5000);
cam.update();
timer = Timer.getTimer();
display.getRenderer().setCamera(cam);
KeyBindingManager.getKeyBindingManager().set("exit",
KeyInput.KEY_ESCAPE);
}
protected void initGame()
{
display.setTitle("Flag Rush");
scene = new Node("Scene graph node");
physicsSpace = PhysicsSpace.create();
terrainNode = getPhysicsSpace().createStaticNode();
playerNode = getPhysicsSpace().createDynamicNode();
/** Create a ZBuffer to display pixels closest to the camera above farther ones. */
ZBufferState buf = display.getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.CF_LEQUAL);
scene.setRenderState(buf);
CullState cs = display.getRenderer().createCullState();
cs.setCullMode(CullState.CS_BACK);
scene.setRenderState(cs);
buildTerrain();
buildLighting();
buildEnvironment();
buildSkyBox();
buildPlayer();
buildChaseCamera();
buildInput();
scene.updateGeometricState(0.0f, true);
scene.updateRenderState();
}
private void buildPlayer()
{
Box b = new Box("box", new Vector3f(), 0.35f,0.25f,0.5f);
b.setModelBound(new BoundingBox());
b.updateModelBound();
playerNode.setLocalTranslation(new Vector3f(100,10, 100));
scene.attachChild(playerNode);
playerNode.attachChild(b);
playerNode.updateWorldBound();
playerNode.generatePhysicsGeometry();
//playerNode.computeMass();
//playerNode.setAffectedByGravity(false);
}
private void buildEnvironment()
{
fence = new ForceFieldFence("fence");
fence.setLocalScale(5);
fence.setLocalTranslation(new Vector3f(25, tb.getHeight(25,25)+10, 25));
scene.attachChild(fence);
}
private void buildLighting() {
DirectionalLight light = new DirectionalLight();
light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
light.setDirection(new Vector3f(1,-1,0));
light.setEnabled(true);
LightState lightState = display.getRenderer().createLightState();
lightState.setEnabled(true);
lightState.attach(light);
scene.setRenderState(lightState);
}
private void buildTerrain() {
MidPointHeightMap heightMap = new MidPointHeightMap(64, 1f);
Vector3f terrainScale = new Vector3f(4, 0.0575f, 4);
tb = new TerrainBlock("Terrain", heightMap.getSize(), terrainScale,
heightMap.getHeightMap(), new Vector3f(0, 0, 0), false);
tb.setModelBound(new BoundingBox());
tb.updateModelBound();
// generate a terrain texture with 2 textures
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(32);
// assign the texture to the terrain
TextureState ts = display.getRenderer().createTextureState();
Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR, true);
ts.setTexture(t1, 0);
tb.setRenderState(ts);
tb.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
terrainNode.attachChild(tb);
terrainNode.generatePhysicsGeometry();
scene.attachChild(tb);
}
private void buildSkyBox() {
skybox = new Skybox("skybox", 10, 10, 10);
Texture north = TextureManager.loadTexture(
TestSkybox.class.getClassLoader().getResource(
"jmetest/data/texture/north.jpg"),
Texture.MM_LINEAR,
Texture.FM_LINEAR);
Texture south = TextureManager.loadTexture(
TestSkybox.class.getClassLoader().getResource(
"jmetest/data/texture/south.jpg"),
Texture.MM_LINEAR,
Texture.FM_LINEAR);
Texture east = TextureManager.loadTexture(
TestSkybox.class.getClassLoader().getResource(
"jmetest/data/texture/east.jpg"),
Texture.MM_LINEAR,
Texture.FM_LINEAR);
Texture west = TextureManager.loadTexture(
TestSkybox.class.getClassLoader().getResource(
"jmetest/data/texture/west.jpg"),
Texture.MM_LINEAR,
Texture.FM_LINEAR);
Texture up = TextureManager.loadTexture(
TestSkybox.class.getClassLoader().getResource(
"jmetest/data/texture/top.jpg"),
Texture.MM_LINEAR,
Texture.FM_LINEAR);
Texture down = TextureManager.loadTexture(
TestSkybox.class.getClassLoader().getResource(
"jmetest/data/texture/bottom.jpg"),
Texture.MM_LINEAR,
Texture.FM_LINEAR);
skybox.setTexture(Skybox.NORTH, north);
skybox.setTexture(Skybox.WEST, west);
skybox.setTexture(Skybox.SOUTH, south);
skybox.setTexture(Skybox.EAST, east);
skybox.setTexture(Skybox.UP, up);
skybox.setTexture(Skybox.DOWN, down);
skybox.preloadTextures();
scene.attachChild(skybox);
}
private void buildChaseCamera() {
Vector3f targetOffset = new Vector3f();
targetOffset.y = ((BoundingBox) playerNode.getWorldBound()).yExtent * 1.5f;
HashMap<String, Object> props = new HashMap<String, Object>();
props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "6");
props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "3");
props.put(ThirdPersonMouseLook.PROP_MAXASCENT, ""+45 * FastMath.DEG_TO_RAD);
props.put(ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(5, 0, 30 * FastMath.DEG_TO_RAD));
props.put(ChaseCamera.PROP_TARGETOFFSET, targetOffset);
chaser = new ChaseCamera(cam, playerNode, props);
chaser.setMaxDistance(8);
chaser.setMinDistance(2);
}
private void buildInput() {
input = new FlagRushHandler(playerNode, properties.getRenderer());
}
protected void reinit() {
display.recreateWindow(width, height, depth, freq, fullscreen);
}
protected void setPhysicsSpace(PhysicsSpace physicsSpace)
{
if (physicsSpace != this.physicsSpace)
{
if ( this.physicsSpace != null )
{
this.physicsSpace.delete();
this.physicsSpace = physicsSpace;
}
}
}
public PhysicsSpace getPhysicsSpace()
{
return physicsSpace;
}
protected void quit() {
super.quit();
System.exit(0);
}
protected void cleanup() {
}
}
ForceFieldFence.java
package lesson5;
import jmetest.flagrushtut.Lesson2;
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.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.SharedMesh;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Cylinder;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
public class ForceFieldFence extends Node {
private static final long serialVersionUID = 1L;
private Texture t;
public ForceFieldFence(String name) {
super(name);
buildFence();
}
public void update(float interpolation) {
t.getTranslation().y += 0.3f * interpolation;
if(t.getTranslation().y > 1) {
t.getTranslation().y = 0;
}
}
private void buildFence() {
Cylinder postGeometry = new Cylinder("post", 10, 10, 1, 10);
Quaternion q = new Quaternion();
q.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
postGeometry.setLocalRotation(q);
postGeometry.setModelBound(new BoundingBox());
postGeometry.updateModelBound();
SharedMesh post1 = new SharedMesh("post1", postGeometry);
post1.setLocalTranslation(new Vector3f(0,0.5f,0));
SharedMesh post2 = new SharedMesh("post2", postGeometry);
post2.setLocalTranslation(new Vector3f(32,0.5f,0));
SharedMesh post3 = new SharedMesh("post3", postGeometry);
post3.setLocalTranslation(new Vector3f(0,0.5f,32));
SharedMesh post4 = new SharedMesh("post4", postGeometry);
post4.setLocalTranslation(new Vector3f(32,0.5f,32));
Cylinder strutGeometry = new Cylinder("strut", 10,10, 0.125f, 32);
strutGeometry.setModelBound(new BoundingBox());
strutGeometry.updateModelBound();
SharedMesh strut1 = new SharedMesh("strut1", strutGeometry);
Quaternion rotate90 = new Quaternion();
rotate90.fromAngleAxis(FastMath.PI/2, new Vector3f(0,1,0));
strut1.setLocalRotation(rotate90);
strut1.setLocalTranslation(new Vector3f(16,3f,0));
SharedMesh strut2 = new SharedMesh("strut2", strutGeometry);
strut2.setLocalTranslation(new Vector3f(0,3f,16));
SharedMesh strut3 = new SharedMesh("strut3", strutGeometry);
strut3.setLocalTranslation(new Vector3f(32,3f,16));
SharedMesh strut4 = new SharedMesh("strut4", strutGeometry);
strut4.setLocalRotation(rotate90);
strut4.setLocalTranslation(new Vector3f(16,3f,32));
Box forceFieldX = new Box("forceFieldX", new Vector3f(-16, -3f, -0.1f), new Vector3f(16f, 3f, 0.1f));
forceFieldX.setModelBound(new BoundingBox());
forceFieldX.updateModelBound();
SharedMesh forceFieldX1 = new SharedMesh("forceFieldX1",forceFieldX);
forceFieldX1.setLocalTranslation(new Vector3f(16,0,0));
SharedMesh forceFieldX2 = new SharedMesh("forceFieldX2",forceFieldX);
forceFieldX2.setLocalTranslation(new Vector3f(16,0,32));
Box forceFieldZ = new Box("forceFieldZ", new Vector3f(-0.1f, -3f, -16), new Vector3f(0.1f, 3f, 16));
forceFieldZ.setModelBound(new BoundingBox());
forceFieldZ.updateModelBound();
SharedMesh forceFieldZ1 = new SharedMesh("forceFieldZ1",forceFieldZ);
forceFieldZ1.setLocalTranslation(new Vector3f(0,0,16));
SharedMesh forceFieldZ2 = new SharedMesh("forceFieldZ2",forceFieldZ);
forceFieldZ2.setLocalTranslation(new Vector3f(32,0,16));
Node forceFieldNode = new Node("forceFieldNode");
forceFieldNode.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
forceFieldNode.attachChild(forceFieldX1);
forceFieldNode.attachChild(forceFieldX2);
forceFieldNode.attachChild(forceFieldZ1);
forceFieldNode.attachChild(forceFieldZ2);
AlphaState as1 = DisplaySystem.getDisplaySystem().getRenderer().createAlphaState();
as1.setBlendEnabled(true);
as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as1.setDstFunction(AlphaState.DB_ONE);
as1.setTestEnabled(true);
as1.setTestFunction(AlphaState.TF_GREATER);
as1.setEnabled(true);
forceFieldNode.setRenderState(as1);
TextureState ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
t = TextureManager.loadTexture(Lesson2.class.getClassLoader()
.getResource("jmetest/data/texture/reflector.jpg"),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
t.setWrap(Texture.WM_WRAP_S_WRAP_T);
t.setTranslation(new Vector3f());
ts.setTexture(t);
forceFieldNode.setRenderState(ts);
Node towerNode = new Node("tower");
towerNode.attachChild(post1);
towerNode.attachChild(post2);
towerNode.attachChild(post3);
towerNode.attachChild(post4);
towerNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
TextureState ts2 = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
Texture t2 = TextureManager.loadTexture(Lesson2.class.getClassLoader()
.getResource("jmetest/data/texture/post.jpg"),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
ts2.setTexture(t2);
towerNode.setRenderState(ts2);
Node strutNode = new Node("strutNode");
strutNode.attachChild(strut1);
strutNode.attachChild(strut2);
strutNode.attachChild(strut3);
strutNode.attachChild(strut4);
strutNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
TextureState ts3 = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
Texture t3 = TextureManager.loadTexture(Lesson2.class.getClassLoader()
.getResource("jmetest/data/texture/rust.jpg"),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
ts3.setTexture(t3);
strutNode.setRenderState(ts3);
this.attachChild(forceFieldNode);
this.attachChild(towerNode);
this.attachChild(strutNode);
}
}
FlagRushHandler code in the next post..
Dev