Non Physic Collision Detection

Well whenever the Parent is moved, the client changes it's position as well (obiviously)

When it sets the new position/rotation it seems to set some of the jme or physics dirty flags,

wich then in someway prevents the collisiontests.



When i only move it like above in every second update, then it works.

1 Update rotate parent,

2 Update do nothing but get collisione event.



So I only get collision events when the Parent fo the ghost node is not changing rotation/position.

However when I move the GhostNode directly it works even in the same update.



What is causing this directly I don't know , but I gues it is somthing in the parentingupdate code i the jme core.

Here is a more detailed testcase:



package de.empirephoenix;

import com.bulletphysics.collision.shapes.BoxShape;
import com.jme3.app.PhysicsApplication;
import com.jme3.app.SimplePhysicsApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.collision.CollisionEvent;
import com.jme3.bullet.collision.CollisionListener;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.MeshCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.nodes.PhysicsGhostNode;
import com.jme3.bullet.nodes.PhysicsNode;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.material.Material;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Transform;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;



public class SolarSystem extends SimplePhysicsApplication {

   public static void main(String[] args){
      SolarSystem lol = new SolarSystem();
      lol.setMultithreaded(false);
      lol.start();
   }

   private PhysicsGhostNode box;
   private Node tester;
   private boolean tick;

   @Override
   public void simpleInitApp() {
      this.flyCam.setMoveSpeed(50);
      
      Box boxmesh = new Box(Vector3f.ZERO,100,10f,100);
      Geometry boxgeom = new Geometry("Box",boxmesh);
      
      Material mat = new Material(manager, "plain_texture.j3md");
        TextureKey key = new TextureKey("Monkey.jpg", true);
        key.setGenerateMips(true);
        Texture tex = manager.loadTexture(key);
        tex.setMinFilter(Texture.MinFilter.Trilinear);
        mat.setTexture("m_ColorMap", tex);
        boxgeom.setMaterial(mat);
      
      PhysicsNode ground = new PhysicsNode(boxgeom,new BoxCollisionShape(new Vector3f(100,10,100)),0);
      ground.setLocalTranslation(0,-30,0);
      ground.updateModelBound();

      this.rootNode.attachChild(ground);
      getPhysicsSpace().addQueued(ground);

      
      Box boxmesh2 = new Box(Vector3f.ZERO,1,1,1);
      BoxCollisionShape boxshape = new BoxCollisionShape(new Vector3f(1,1,1));

      tester = new Node();
      
      tester.setLocalTranslation(0,0,0);
      
      Geometry boxgeom2 = new Geometry("Box2",boxmesh2);
      box = new PhysicsGhostNode(boxgeom2,boxshape);
      box.setLocalTranslation(0,30,0);
      box.setMaterial(mat);
      this.tester.attachChild(box);
      this.rootNode.attachChild(tester);
      getPhysicsSpace().addCollisionListener(new CollisionListener(){
         @Override
         public void collision(CollisionEvent event) {
            System.out.println("Event");
         }
         
      });
      getPhysicsSpace().addQueued(box);
      
      
      
      Geometry box2 = new Geometry("Lol",boxmesh2);
      box2.setLocalTranslation(0,32,0);
      box2.setMaterial(mat);
      this.tester.attachChild(box2);
      this.rootNode.attachChild(tester);
   }
   
   @Override
   public void update(){
      super.update();
      
   
      if(tick){
         Quaternion bla = tester.getLocalRotation();
         float[] storage = new float[3];
         bla.toAngles(storage);
         storage[0]+=0.00001f;
         bla.fromAngles(storage);
         tester.setLocalRotation(bla);
         tick = false;
      }else{
         tick = true;
      }
   
   }
 
}



It clearly seems that the Ghostnode is nt updated right with this test. If you remove the tick stuff in the update, then it is moving correctly, but not reciving any further collision events. O.o Already looked at the Code, but I have not really any idea, why this is happening.

Ok, it could be that the GhostNode does not report collisions in the tick its being moved, maybe its just supposed to be static and throw collision events if something bumps into it, gotta check that. If it is so, you'll have to wait until I add the kinematic flag to normal PhysicsNodes and then try to use those for this purpose.

Cheers,

Normen

Found a hacky fix, but it works as intendend:



package de.empirephoenix;


import javax.vecmath.Quat4f;

import com.bulletphysics.collision.dispatch.CollisionFlags;
import com.bulletphysics.collision.dispatch.GhostObject;
import com.bulletphysics.collision.dispatch.PairCachingGhostObject;
import com.bulletphysics.linearmath.Transform;
import com.jme3.bullet.collision.CollisionObject;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.nodes.PhysicsGhostNode;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;

/**
 * <i>From Bullet manual:</i><br>
 * GhostObject can keep track of all objects that are overlapping.
 * By default, this overlap is based on the AABB.
 * This is useful for creating a character controller,
 * collision sensors/triggers, explosions etc.<br>
 * @author normenhansen
 */
public class PGhostNode extends PhysicsGhostNode{

   private boolean tick;
   private Spatial child;
   private Transform jmetrans = new Transform();
   private Quat4f bulletrot = new Quat4f();

    public PGhostNode(Spatial child, CollisionShape shape){
        super(child,shape);
        this.child = child;
    }
   
   
   @Override
   public synchronized void updateGeometricState(){
      
      super.updateGeometricState();
      Vector3f pos = this.child.getWorldTranslation();
      jmetrans .origin.x = pos.x;
      jmetrans.origin.y = pos.y;
      jmetrans.origin.z = pos.z;
      
      Quaternion rot = child.getWorldRotation();
      bulletrot.w = rot.getW();
      bulletrot.x = rot.getX();
      bulletrot.y = rot.getY();
      bulletrot.z = rot.getZ();
      jmetrans.setRotation(bulletrot);
      gObject.setWorldTransform(jmetrans);
   
   }
   

}




So the problem is not the Ghost node, but the way it is updated.

Ok, there was a bug in PhysicsGhostNode that would set the local transform of the node as world transform in the physics, it uses the world translation now. Can you try the latest svn and see if that solves your problem?

Yes, perfect all workinga s intended now :slight_smile:

ehm, I might have lost some pieces, but reading the requirements, why don’t use simply add a continuous force to entities inside a ship with artificial gravitational field on? just an idea…

Well it did not work well, either you can’t really move or you get thrown around when the pilot flies curves.

hey, your image is not visible for me ?

Same here.