Right Now I am using BitMapText for my HUD to tell me when a collision occurs. I have been to the website pages http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:collision_and_intersection and http://wiki.jmonkeyengine.org/doku.php/jme3:beginner:hello_picking but its been difficult and its not displaying back to me the collisions in my main class with for the simpleUpdate() .
public class Main extends SimpleApplication {
protected BulletAppState bulletAppState;
private Vector3f normalGravity = new Vector3f(0, -9.81f, 0);
RigidBodyControl terrainRBC;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
/**
* Load a model. Uses model and texture from jme3-test-data library!
*/
Spatial scene = assetManager.loadModel("Scenes/Week2Scene.j3o");
rootNode.attachChild(scene);
bulletAppState = new BulletAppState(); //Allows for the use of Physics simulation
stateManager.attach(bulletAppState);
//stateManager.detach(stateManager.getState(FlyCamAppState.class));
Spatial terrain = assetManager.loadModel("Scenes/Week2Scene.j3o");
CollisionShape cs = CollisionShapeFactory.createMeshShape(terrain);
terrainRBC = new RigidBodyControl(cs, 0);
bulletAppState.getPhysicsSpace().add(terrainRBC);
rootNode.attachChild(terrain);
//Create the Physics World based on the Helper class
PhysicsTestHelper.createPhysicsTestWorldSoccer(rootNode, assetManager, bulletAppState.getPhysicsSpace());
//Add the Player to the world and use the customer character and input control classes
Node playerNode = (Node) assetManager.loadModel("Models/Pumpkin/Pumpkin.j3o");
MyGameCharacterControl charControl = new MyGameCharacterControl(0.5f, 2.5f, 8f);
charControl.setCamera(cam);
playerNode.addControl(charControl);
charControl.setGravity(normalGravity);
bulletAppState.getPhysicsSpace().add(charControl);
InputAppState appState = new InputAppState();
appState.setCharacter(charControl);
stateManager.attach(appState);
rootNode.attachChild(playerNode);
//Add the "bullets" to the scene to allow the player to shoot the balls
PhysicsTestHelper.createBallShooter(this, rootNode, bulletAppState.getPhysicsSpace());
//Add a custom font and text to the scene
BitmapFont myFont = assetManager.loadFont("Interface/Fonts/BasicFont.fnt");
BitmapText hudText = new BitmapText(myFont, true);
hudText.setText("Patrick McCully, Game Testing");
hudText.setColor(ColorRGBA.Red);
hudText.setSize(guiFont.getCharSet().getRenderedSize());
//Set the text in the middle of the screen
hudText.setLocalTranslation(settings.getWidth() / 2, settings.getHeight() / 2 + hudText.getLineHeight(), 0f); //Positions text to middle of screen
guiNode.attachChild(hudText);
}
@Override
public void simpleUpdate(float tpf) {
BitmapText hudText = new BitmapText(guiFont, false);
hudText.setSize(guiFont.getCharSet().getRenderedSize()); // font size
hudText.setColor(ColorRGBA.Blue); // font color
hudText.setText("You can write any string here"); // the text
hudText.setLocalTranslation(600, hudText.getLineHeight(), 0); // position
guiNode.attachChild(hudText);
//Problem here
CollisionResults results = new CollisionResults();
a.collideWith(b, results);
hudText.setText("Number of Collisions between"
+ a.getName() + " and " + b.getName() + ": " + results.size());
// Use the results
if (results.size() > 0) {
// how to react when a collision was detected
CollisionResult closest = results.getClosestCollision();
hudText.setText("What was hit? " + closest.getGeometry().getName());
hudText.setText("Where was it hit? " + closest.getContactPoint());
hudText.setText("Distance? " + closest.getDistance());
}
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
public class InputAppState extends AbstractAppState implements AnalogListener, ActionListener {
private Application app;
private InputManager inputManager;
private MyGameCharacterControl character; //The Custom Character Control
private float sensitivity = 5000;
List<Geometry> targets = new ArrayList<Geometry>();
public enum InputMapping{
LeanLeft,
LeanRight,
LeanFree,
RotateLeft,
RotateRight,
LookUp,
LookDown,
StrafeLeft,
StrafeRight,
MoveForward,
MoveBackward,
Fire;
}
private String[] mappingNames = new String[]{InputMapping.LeanFree.name(), InputMapping.LeanLeft.name(), InputMapping.LeanRight.name(), InputMapping.RotateLeft.name(), InputMapping.RotateRight.name(), InputMapping.LookUp.name(), InputMapping.LookDown.name(), InputMapping.StrafeLeft.name(), InputMapping.StrafeRight.name(), InputMapping.MoveForward.name(), InputMapping.MoveBackward.name()};
@Override
public void initialize(AppStateManager stateManager, Application app) {
super.initialize(stateManager, app);
this.app = app;
this.inputManager = app.getInputManager();
addInputMappings();
assignJoysticks();
}
private void addInputMappings(){
inputManager.addMapping(InputMapping.LeanFree.name(), new KeyTrigger(KeyInput.KEY_V));
inputManager.addMapping(InputMapping.LeanLeft.name(), new KeyTrigger(KeyInput.KEY_Q));
inputManager.addMapping(InputMapping.LeanRight.name(), new KeyTrigger(KeyInput.KEY_E));
inputManager.addMapping(InputMapping.RotateLeft.name(), new MouseAxisTrigger(MouseInput.AXIS_X, true));
inputManager.addMapping(InputMapping.RotateRight.name(), new MouseAxisTrigger(MouseInput.AXIS_X, false));
inputManager.addMapping(InputMapping.LookUp.name(), new MouseAxisTrigger(MouseInput.AXIS_Y, false));
inputManager.addMapping(InputMapping.LookDown.name(), new MouseAxisTrigger(MouseInput.AXIS_Y, true));
inputManager.addMapping(InputMapping.StrafeLeft.name(), new KeyTrigger(KeyInput.KEY_H), new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping(InputMapping.StrafeRight.name(), new KeyTrigger(KeyInput.KEY_K), new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping(InputMapping.MoveForward.name(), new KeyTrigger(KeyInput.KEY_U), new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping(InputMapping.MoveBackward.name(), new KeyTrigger(KeyInput.KEY_J), new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addListener(this, mappingNames);
inputManager.addMapping(InputMapping.Fire.name(), new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
}
/**
*
*/
private void assignJoysticks(){
Joystick[] joysticks = inputManager.getJoysticks();
if (joysticks != null){
for( Joystick j : joysticks ) {
for(JoystickAxis axis : j.getAxes()){
if(axis == j.getXAxis()){
axis.assignAxis(InputMapping.StrafeRight.name(), InputMapping.StrafeLeft.name());
} else if ( axis == j.getYAxis()){
axis.assignAxis(InputMapping.MoveBackward.name(), InputMapping.MoveForward.name());
} else if (axis.getLogicalId().equals("ry")){
axis.assignAxis(InputMapping.LookDown.name(), InputMapping.LookUp.name());
} else if(axis.getLogicalId().equals("rx")){
axis.assignAxis(InputMapping.RotateRight.name(), InputMapping.RotateLeft.name());
}
}
for(JoystickButton button : j.getButtons()){
button.assignButton("Fire");
}
}
}
}
/**
*
*/
@Override
public void cleanup() {
super.cleanup();
for (InputMapping i : InputMapping.values()) {
if (inputManager.hasMapping(i.name())) {
inputManager.deleteMapping(i.name());
}
}
inputManager.removeListener(this);
}
public void onAnalog(String action, float value, float tpf) {
if(character != null){
character.onAnalog(action, value * sensitivity, tpf);
}
}
public void onAction(String name, boolean isPressed, float tpf) {
if(character != null){
if (name.equals("Fire")) {
if (isPressed && character.getCooldown() == 0f){
fire();
}
} else {
character.onAction(name, isPressed, tpf);
}
}
}
public void setCharacter(MyGameCharacterControl character){
this.character = character;
}
public void setTargets(List<Geometry> targets){
this.targets = targets;
}
public void fire(){
if(character != null){
Ray r = new Ray(app.getCamera().getLocation(), app.getCamera().getDirection());
CollisionResults collRes = new CollisionResults();
for(Geometry g: targets){
g.collideWith(r, collRes);
}
if(collRes.size() > 0){
System.out.println("hit");
}
character.onFire();
}
}
}
public class PhysicsTestHelper {
/**
* creates a simple physics test world with a floor, an obstacle and some test boxes
* @param rootNode
* @param assetManager
* @param space
*/
public static void createPhysicsTestWorld(Node rootNode, AssetManager assetManager, PhysicsSpace space) {
AmbientLight light = new AmbientLight();
light.setColor(ColorRGBA.LightGray);
rootNode.addLight(light);
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
Box floorBox = new Box(140, 0.25f, 140);
Geometry floorGeometry = new Geometry("Floor", floorBox);
floorGeometry.setMaterial(material);
floorGeometry.setLocalTranslation(0, -5, 0);
// Plane plane = new Plane();
// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y);
// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0));
floorGeometry.addControl(new RigidBodyControl(0));
rootNode.attachChild(floorGeometry);
space.add(floorGeometry);
//movable boxes
for (int i = 0; i < 12; i++) {
Box box = new Box(0.25f, 0.25f, 0.25f);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material);
boxGeometry.setLocalTranslation(i, 5, -3);
//RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
boxGeometry.addControl(new RigidBodyControl(2));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
//immovable sphere with mesh collision shape
Sphere sphere = new Sphere(8, 8, 1);
Geometry sphereGeometry = new Geometry("Sphere", sphere);
sphereGeometry.setMaterial(material);
sphereGeometry.setLocalTranslation(4, -4, 2);
sphereGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0));
rootNode.attachChild(sphereGeometry);
space.add(sphereGeometry);
}
public static void createPhysicsTestWorldSoccer(Node rootNode, AssetManager assetManager, PhysicsSpace space) {
AmbientLight light = new AmbientLight();
light.setColor(ColorRGBA.LightGray);
rootNode.addLight(light);
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Textures/BumpMapTest/Tangent.png"));
Material material2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material2.setTexture("ColorMap", assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));
//movable spheres
for (int i = 0; i < 10; i++) {
Sphere sphere = new Sphere(16, 16, .5f);
Geometry ballGeometry = new Geometry("Soccer ball", sphere);
ballGeometry.setMaterial(material);
ballGeometry.setLocalTranslation(i, 2, -3);
//RigidBodyControl automatically uses Sphere collision shapes when attached to single geometry with sphere mesh
ballGeometry.addControl(new RigidBodyControl(.001f));
ballGeometry.getControl(RigidBodyControl.class).setRestitution(1);
rootNode.attachChild(ballGeometry);
space.add(ballGeometry);
}
{
//immovable Box with mesh collision shape
Box box = new Box(1, 1, 1);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material2);
boxGeometry.setLocalTranslation(4, 1, 2);
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
{
//immovable Box with mesh collision shape
Box box = new Box(1, 1, 1);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material2);
boxGeometry.setLocalTranslation(4, 3, 4);
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
{
//immovable Box with mesh collision shape
Box box = new Box(1, 1, 1);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material2);
boxGeometry.setLocalTranslation(4, 5, 6);
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
{
//immovable Box with mesh collision shape
Box box = new Box(1, 1, 1);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material2);
boxGeometry.setLocalTranslation(3, 7, 8);
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
{
//immovable Box with mesh collision shape
Box box = new Box(1, 1, 1);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material2);
boxGeometry.setLocalTranslation(5, 8, 9);
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0));
rootNode.attachChild(boxGeometry);
space.add(boxGeometry);
}
}
/**
* creates a box geometry with a RigidBodyControl
* @param assetManager
* @return
*/
public static Geometry createPhysicsTestBox(AssetManager assetManager) {
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
Box box = new Box(0.25f, 0.25f, 0.25f);
Geometry boxGeometry = new Geometry("Box", box);
boxGeometry.setMaterial(material);
//RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh
boxGeometry.addControl(new RigidBodyControl(2));
return boxGeometry;
}
/**
* creates a sphere geometry with a RigidBodyControl
* @param assetManager
* @return
*/
public static Geometry createPhysicsTestSphere(AssetManager assetManager) {
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
Sphere sphere = new Sphere(8, 8, 0.25f);
Geometry boxGeometry = new Geometry("Sphere", sphere);
boxGeometry.setMaterial(material);
//RigidBodyControl automatically uses sphere collision shapes when attached to single geometry with sphere mesh
boxGeometry.addControl(new RigidBodyControl(2));
return boxGeometry;
}
/**
* creates an empty node with a RigidBodyControl
* @param manager
* @param shape
* @param mass
* @return
*/
public static Node createPhysicsTestNode(AssetManager manager, CollisionShape shape, float mass) {
Node node = new Node("PhysicsNode");
RigidBodyControl control = new RigidBodyControl(shape, mass);
node.addControl(control);
return node;
}
/**
* creates the necessary inputlistener and action to shoot balls from teh camera
* @param app
* @param rootNode
* @param space
*/
public static void createBallShooter(final Application app, final Node rootNode, final PhysicsSpace space) {
ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
Sphere bullet = new Sphere(22, 22, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
Material mat2 = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
key2.setGenerateMips(true);
Texture tex2 = app.getAssetManager().loadTexture(key2);
mat2.setTexture("ColorMap", tex2);
if (name.equals("shoot") && !keyPressed) {
Geometry bulletg = new Geometry("bullet", bullet);
bulletg.setMaterial(mat2);
bulletg.setShadowMode(ShadowMode.CastAndReceive);
bulletg.setLocalTranslation(app.getCamera().getLocation());
RigidBodyControl bulletControl = new RigidBodyControl(10);
bulletg.addControl(bulletControl);
bulletControl.setLinearVelocity(app.getCamera().getDirection().mult(25));
bulletg.addControl(bulletControl);
rootNode.attachChild(bulletg);
space.add(bulletControl);
}
}
};
app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
app.getInputManager().addListener(actionListener, "shoot");
}
}
public class MyGameCharacterControl extends BetterCharacterControl
implements ActionListener, AnalogListener {
boolean forward = false, backward = false, leftRotate = false, rightRotate = false, leftStrafe = false, rightStrafe = false;
protected Node head = new Node("Head");
private float yaw = 0;
protected float moveSpeed = 3;
private float cooldownTime = 1f;
private float cooldown = 0f;
public MyGameCharacterControl(float radius, float height, float mass) {
super(radius, height, mass);
head.setLocalTranslation(0, 1.8f, 0);
}
public void onAction(String action, boolean isPressed, float tpf) {
if (action.equals("StrafeLeft")) {
leftStrafe = isPressed;
} else if (action.equals("StrafeRight")) {
rightStrafe = isPressed;
} else if (action.equals("MoveForward")) {
forward = isPressed;
} else if (action.equals("MoveBackward")) {
backward = isPressed;
} else if (action.equals("Jump")) {
jump();
} else if (action.equals("Duck")) {
setDucked(isPressed);
}
}
public void onAnalog(String name, float value, float tpf) {
if (name.equals("RotateLeft")) {
rotate(tpf * value);
} else if (name.equals("RotateRight")) {
rotate(-tpf * value);
} else if (name.equals("LookUp")) {
lookUpDown(value * tpf);
} else if (name.equals("LookDown")) {
lookUpDown(-value * tpf);
} /**
*
*/
else if (name.equals("MoveForward") || name.equals("MoveBackward") || name.equals("StrafeLeft") || name.equals("StrafeRight")) {
moveSpeed = value * 1;
}
/**
*
*/
}
public void update(float tpf) {
super.update(tpf);
Vector3f modelForwardDir = spatial.getWorldRotation().mult(Vector3f.UNIT_Z);
Vector3f modelLeftDir = spatial.getWorldRotation().mult(Vector3f.UNIT_X);
walkDirection.set(0, 0, 0);
if (cooldown > 0) {
cooldown -= tpf;
cooldown = Math.max(cooldown, 0);
}
if (forward) {
walkDirection.addLocal(modelForwardDir.mult(moveSpeed));
} else if (backward) {
walkDirection.addLocal(modelForwardDir.negate().multLocal(moveSpeed));
}
if (leftStrafe) {
walkDirection.addLocal(modelLeftDir.mult(moveSpeed));
} else if (rightStrafe) {
walkDirection.addLocal(modelLeftDir.negate().multLocal(moveSpeed));
}
setWalkDirection(walkDirection);
}
public void setCamera(Camera cam) {
CameraNode camNode = new CameraNode("CamNode", cam);
camNode.setControlDir(CameraControl.ControlDirection.SpatialToCamera);
head.attachChild(camNode);
camNode.setLocalTranslation(new Vector3f(0, 5, -5));
camNode.lookAt(head.getLocalTranslation(), Vector3f.UNIT_Y);
}
protected void rotate(float value) {
Quaternion rotate = new Quaternion().fromAngleAxis(FastMath.PI * value, Vector3f.UNIT_Y);
rotate.multLocal(viewDirection);
setViewDirection(viewDirection);
}
protected void lookUpDown(float value) {
yaw += value;
yaw = FastMath.clamp(yaw, -FastMath.HALF_PI, FastMath.HALF_PI);
head.setLocalRotation(new Quaternion().fromAngles(yaw, 0, 0));
}
public float getCooldown() {
return cooldown;
}
public void onFire() {
cooldown = cooldownTime;
}
}