Following the tutorial i reached the physics part. I tested the physics with a small object and all seems to work fine.
a) The problems are following, when i load two or more small objects they collide right after initialisation and fly trough the map.
b) When i load a bigger Object it sink’s half into the landscape and after some time it fly’s up and lands correctly on the ground.
Here is the code i wrote for loading the terrain and the objects and setting up the physics. (I can’t attache a screenshot because the objects are not visible on the pictures)
The GameUnit.java should load a model and attach it to the root node and BulletAppState.
[java]package mygame;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import java.util.ArrayList;
import java.util.Stack;
/**
*
-
@author zzuegg
/
public class GameUnit {
Node position;
Node rootNode;
Spatial mesh;
RigidBodyControl unit_physics;
//AssetManager
AssetManager assetManager;
//PHYSICS
BulletAppState bulletAppState;
BoxCollisionShape collisionShape;
CharacterControl playerControl;
int id;
public boolean isMovable;
public boolean isRotable;
Stack<Vector3f> waypoint;
ArrayList subUnits;
public GameUnit(Node rootNode,Vector3f position,AssetManager assetManager, BulletAppState bulletAppState, int id,String modelName) {
this.position=new Node();
this.position.setLocalTranslation(position);
this.bulletAppState = bulletAppState;
this.assetManager=assetManager;
this.id = id;
this.rootNode=rootNode;
this.load(modelName);
}
private void load(String modelName){
this.mesh=assetManager.loadModel(modelName);
this.mesh.setShadowMode(ShadowMode.CastAndReceive);
//Collision Model
this.collisionShape= new BoxCollisionShape(new Vector3f(1f,1f,1f));
this.playerControl=new CharacterControl(this.collisionShape,1);
//Physic Modlel
this.unit_physics = new RigidBodyControl(2f);
this.mesh.addControl(this.unit_physics);
//Attach mesh to node.
this.position.attachChild(this.mesh);
//Add object to physic system
this.playerControl.setPhysicsLocation(this.position.getWorldTranslation());
this.bulletAppState.getPhysicsSpace().add(this.playerControl);
this.bulletAppState.getPhysicsSpace().add(this.unit_physics);
waypoint=new Stack();
}
public Node getNode(){
return (this.position);
}
}[/java]
This is the MapLoader:
[java]
/
- To change this template, choose Tools | Templates
- and open the template in the editor.
*/
package mygame;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.light.DirectionalLight;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.shadow.PssmShadowRenderer;
import com.jme3.water.WaterFilter;
/**
*
-
@author zzuegg
*/
public class ManagerMapLoader {
Node loadNewMap(int id,Node rootNode,AssetManager assetManager,BulletAppState bulletAppState, ViewPort viewPort){
Node map=new Node();
//LOAD VARIABLES
Vector3f lightDirection=new Vector3f(-40.9f, -10.3f, 0.9f);
Spatial terrain=assetManager.loadModel("Scenes/Map_Demo1/Map_Demo1_scene.j3o");
float waterHeight=-1.5f;
//ADD LIGHT AND TERRAIN
DirectionalLight sun = new DirectionalLight();
sun.setDirection(lightDirection);
rootNode.addLight(sun);
map.attachChild(terrain);
//ADD SHADOW
PssmShadowRenderer pssmRenderer=new PssmShadowRenderer(assetManager,1024,4);
pssmRenderer.setFilterMode(PssmShadowRenderer.FilterMode.PCF8);
pssmRenderer.setDirection(new Vector3f(-1,-1,-1).normalizeLocal());
viewPort.addProcessor(pssmRenderer);
//REGISTER PHYSICS
CollisionShape sceneShape=CollisionShapeFactory.createMeshShape((Node) terrain);
RigidBodyControl landscape= new RigidBodyControl(sceneShape,0);
terrain.addControl(landscape);
bulletAppState.getPhysicsSpace().add(landscape);
//ADD WATEREFFECT
FilterPostProcessor ffp=new FilterPostProcessor(assetManager);
WaterFilter water=new WaterFilter(map,lightDirection);
water.setWaterHeight(waterHeight);
ffp.addFilter(water);
viewPort.addProcessor(ffp);
return map;
}
}
[/java]
And finaly the main:
[java]
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
/**
- test
-
@author normenhansen
*/
public class Main extends SimpleApplication {
ManagerMapLoader MapManager;
ManagerPlayerInputControl InputManager;
BulletAppState bulletAppState;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
this.flyCam.setEnabled(false);
settings.setRenderer(AppSettings.LWJGL_OPENGL3);
this.MapManager=new ManagerMapLoader();
this.InputManager=new ManagerPlayerInputControl();
this.InputManager.initPlayerControls(this.inputManager, this.cam);
this.bulletAppState=new BulletAppState();
this.bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
this.stateManager.attach(this.bulletAppState);
this.rootNode.attachChild(MapManager.loadNewMap(0,this.rootNode, assetManager, this.bulletAppState, viewPort));
GameUnit tmp=new GameUnit(this.rootNode,new Vector3f(1,1,1),this.assetManager,this.bulletAppState,0,"Models/Rebellion_Radar_test1.j3o");
this.rootNode.attachChild(tmp.getNode());
//GameUnit tmp=new GameUnit(this.rootNode,new Vector3f(3,10,3),this.assetManager,this.bulletAppState,0,"Models/Rebellion_Headquarter_test1.j3o");
//this.rootNode.attachChild(tmp.getNode());
tmp=new GameUnit(this.rootNode,new Vector3f(10,10,20),this.assetManager,this.bulletAppState,0,"Models/Electro_turret1.j3o");
this.rootNode.attachChild(tmp.getNode());
}
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
this.InputManager.updatePlayerControls(tpf, inputManager, settings.getHeight(), settings.getWidth());
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
[/java]