Creating rigid object directly in C++ with JNI

Heya all!

For development reasons, I want to understand the method that JME uses to put objects into the C++ Bullet engine.

I’ve written my own JNI function that I call from JME after the physics is instantiated and after I’ve added a few other capsule objects.

This function puts a large sphere into the simulation, that I would like to make collide with the existing capsule objects (I’ve set the CollisionFlags of both types of objects to 0xFFFF and a tried a few other values)

The problem I’m having is that I can place the sphere into the simulation- and it seems to obey the physics of the simulation, but it does not cause collisions with the capsule objects.

What am I missing in the instantiation of a rigid body, such that it will cause collisions inside the Bullet engine?

[java]
/*
* TEMPORARY TESTING FUNCTION
*
* Class: com_jme3_bullet_PhysicsSpace
* Method: addRigidBodyTEST
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_addRigidBodyTEST
(JNIEnv * env, jobject object, jlong spaceId) {

    jmeClasses::initJavaClasses(env);
    jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId);
    
    //Would have representation on the Java side
    jmeMotionState* motionState = new jmeMotionState();
    btSphereShape* shape = new btSphereShape(300);

    //Create rigid body
    btVector3 localInertia = btVector3(0,0,0);
    shape->calculateLocalInertia(10000, localInertia);
    btRigidBody* body = new btRigidBody(10000, motionState, shape, localInertia);

    
    //Set collision flags to collide with all
    body->setCollisionFlags(0xFFFF);
    printf("JNI flag: %d\n",body->getCollisionFlags());
    fflush(stdout);
    
    //Add to physics space
    body->setUserPointer(space);
    space->getDynamicsWorld()->addRigidBody(body);
    
}

[/java]

Thankyou in advance

Anthony.

I’ve written a testing function which is called at each physics tick, which prints the AABB’s for each object. The objects have their AABB’s overlap, but no collisions occur.
The objects are in the same dynamicsWorld, I believe that they have everything that would enable a collision enabled, they react to gravity perfectly fine, but collisions do not occur between them.

[java]
/*
* TEMPORARY TESTING FUNCTION
*
* Class: com_jme3_bullet_PhysicsSpace
* Method: rigidTestUpdate
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_rigidTestUpdate
(JNIEnv * env, jobject object, jlong spaceId) {

    jmeClasses::initJavaClasses(env);
    jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*>(spaceId);      
    
    int nObjects = space->getDynamicsWorld()->getNumCollisionObjects();
    int i;
    
    for(i=0; i<nObjects; i++){
        btCollisionObject* obj = space->getDynamicsWorld()->getCollisionObjectArray().at(i);
        btVector3 location1 = (btVector3)obj->getBroadphaseHandle()->m_aabbMin;
        btVector3 location2 = (btVector3)obj->getBroadphaseHandle()->m_aabbMax;
        printf("Location: %f, %f, %f -> %f, %f, %f\n\n",location1.x(),location1.y(),location1.z(),location2.x(),location2.y(),location2.z());
        fflush(stdout);
    }
}

[/java]

Figured it out!
Just in case anyone has the same issue:

I was assuming that JME simply instantiated objects inside the bullet engine and let them play- using the motionStates to extract the movements the objects made.
Hence I thought you’d just need to instantiate the object inside the engine in a manner exactly the same as how objects are instantiated within Bullet.

This is mostly true- but objects instantiated in ways other than through Java do not collide with other objects.

I tracked the problem back to callbacks instantiated within JME’s initialisation of the bullet engine.
These callbacks use the 'userPointer’s stored in the bullet engine to extract information from the Java side of JME to tell bullet whether two objects should collide or not. If they aren’t set, then the logic that will allow collisions will not ever be true and your objects will never collide.

To fix this- you can follow the standard process for instantiating bullet objects, but then also use the following code in addition;

[java]

<given a btRigidBody* body>

jmeUserPointer userPointer = (jmeUserPointer)body->getUserPointer();

    userPointer = new jmeUserPointer(); 
    userPointer -&gt; javaCollisionObject = env-&gt;NewWeakGlobalRef(object);     //the env variable is the JNIEnv * variable within the JNI layer.
    userPointer -&gt; group = 1;               //Set this to the collision group flag you desire
    userPointer -&gt; groups = 1;             //As with this
    userPointer -&gt; space = NULL;
    body -&gt; setUserPointer(userPointer);  

[/java]

Hope this helps someone!