Native Bullet - SoftBody

Hi,

Is anyone in the process of writing, or planning to write, the JNI bridging code for the Bullet SoftBody classes?

This is on my road map for a research project, but I don’t want to waste time if it is already under development.



Thanks

Gideon

3 Likes

Somebody sometime ago said he would but no, I am not aware of that. It would certainly be a welcome contribution :slight_smile:

Hi,



We are now working on writing JNI bridging code for SoftBody.

We hope to have some basic functionality implemented shortly. We’ll keep you updated.

6 Likes

Wow, cool. I gather theres a lot of data transfer going on to get the vectors updated?

@normen
Hello Normen!
I’ve been working on writing a JNI wrapper for the SoftBody code and I had a few initial questions that would greatly assist me.

Firstly, my conceptual understanding of what needs to be done is essentially:

  1. Write wrappers for the C++ functions that insert SoftBody objects and allow for interactions with them
  2. Write a Java class that stores and updates the location and other information about each node of a SoftBody
  3. Integrate these node locations into a mesh data structure, which can be used and drawn by JME3

Does that sound correct?

Secondly,

In my initial foray into the problem I added code to jmePhysicsSpace.cpp at the very end of createPhysicsSpace(…) (ln:207); in order to test the interactions of the JME instantiated objects and C++ instantiated SoftBodies. The soft bodies I generated did not collide with any planes, other soft bodies or what-have-you; which led me to do my best to emulate the functions used by JME3’s native bullet physics object creation process.
(I also initially tried with the standard C++ Bullet method of adding objects to the physics engine)

printf("Native Bullet C++: Making plane\n"); fflush(stdout); //Set shape and origin of plane btBoxShape* plane = new btBoxShape(btVector3(btScalar(50.),btScalar(1.),btScalar(50.))); btTransform* transPlane = new btTransform(); transPlane->getOrigin().setX(0.); transPlane->getOrigin().setY(0.); transPlane->getOrigin().setZ(0.); //Generate a motionState btDefaultMotionState* myPlaneMotionState = new btDefaultMotionState(*transPlane); //Construct the plane object btRigidBody::btRigidBodyConstructionInfo planeInfo(0,myPlaneMotionState,plane,transPlane->getOrigin()); btRigidBody* rigid_plane = new btRigidBody(planeInfo); //Set the location of the plane rigid_plane->getMotionState()->setWorldTransform(*transPlane); rigid_plane->setCenterOfMassTransform(*transPlane); //Add the plane to the world world->addRigidBody(rigid_plane);
printf("Native Bullet C++: Making sphere\n");
fflush(stdout);
   //Set shape and origin of sphere
btSphereShape* sphere = new btSphereShape(1.);
btTransform* transSphere = new btTransform();
transSphere->getOrigin().setX(0.);
transSphere->getOrigin().setY(10.);
transSphere->getOrigin().setZ(0.);
//Generate a motionState
btDefaultMotionState* mySphereMotionState = new btDefaultMotionState(*transSphere);
//Construct the sphere object
btRigidBody::btRigidBodyConstructionInfo sphereInfo(10,mySphereMotionState,sphere,transSphere->getOrigin());
btRigidBody* rigid_sphere = new btRigidBody(sphereInfo);
//Set the location of the sphere
rigid_sphere->getMotionState()->setWorldTransform(*transSphere);
rigid_sphere->setCenterOfMassTransform(*transSphere);
//Add the sphere to the world
world->addRigidBody(rigid_sphere);

This code created a sphere that dropped onto a plane in a C++ instantiated bullet physics world.
However, when run in jmePhysicsSpace.cpp- outputs of the locations of the falling sphere show that it is responding to gravity within the simulation, but is not interacting with the plane and simply falling through.

/*Within jmePhysicsSpace::preTickCallback(..)*/ printf("Native Bullet C++: "); for(int i=dynamicsWorld->dynamicsWorld->getNumCollisionObjects()-1;i>=0;i--) { btCollisionObject* obj=dynamicsWorld->dynamicsWorld->getCollisionObjectArray()[i]; printf("%f, ",obj->getWorldTransform().getOrigin().getY()); } printf("\n"); fflush(stdout);

Edited output:
-----------------------| JME plane |-| JMEsphere |-| C++Sphere |-|C++Plane
Native Bullet C++: -10.000000, 6.000000, 10.000000, 0.000000,
Native Bullet C++: -10.000000, 5.997275, 9.997275, 0.000000,
Native Bullet C++: -10.000000, 5.991825, 9.991825, 0.000000,



Native Bullet C++: -10.000000, -8.000014, -15.386088, 0.000000,
Native Bullet C++: -10.000000, -8.000011, -15.759413, 0.000000,
Native Bullet C++: -10.000000, -8.000010, -16.135462, 0.000000,
Native Bullet C++: -10.000000, -8.000008, -16.514236, 0.000000,

Planes and spheres instantiated by the normal Java-based process of JME3 are drawn and interact as normal, but also do not interact with the created sphere or plane.

I was wondering whether these problems were being experienced because I have instantiated the objects I’ve placed into the physics engine incorrectly (most likely), or because there is a requirement within JME3 for objects to be associated with a Spatial and attached to the rootNode in order to interact and collide properly.

Any guidance you could give me on this problem would be greatly appreciated.

Sincere regards,

Anthony.

2 Likes

i was wondering what are practical game(not scientific) applications of soft bodies are, the only one i can think of is bouncy boobies.

1 Like

@anthonyevans2000 Hey, thanks for coming back to this.
For 1-3 thats basically correct, for the “moving of the nodes” you should be able to copy the RigidBodyControl and the base PhysicsRigidBody concept. The PhysicsRigidBody is system-agnostic and just wraps the bullet object with jME math objects. The RigidBodyControl takes over the part of applying the data to the actual scene objects, this principle should be kept. This is mainly to allow people to decouple the physics from the main update loop. So you’d basically put the update code in the PhysicsSoftBody object and make the Control assign the mesh and call the update method, then the user can do that however he wishes and in jME it can automatically be multithreaded in the “parallel way” (executing of physics step in parallel to rendering, applying of mesh data on update call)

@nick.meister37 said: i was wondering what are practical game(not scientific) applications of soft bodies are, the only one i can think of is bouncy boobies.

Ball game simulations, eg slowmotion shoots in football(the real one),
Spectacular car crashes in vehicle games (make the car a bit soft, so it gets compacted on the crash, freeze softbody logic after that, so it stays deformed)

[video]http://www.youtube.com/watch?v=KppTmsNFneg[/video]

@nick.meister37 said: i was wondering what are practical game(not scientific) applications of soft bodies are, the only one i can think of is bouncy boobies.
Well that alone makes it worth the work :D

Cloth simulation are coming to my mind, It can ease the artist’s work on animations for example.

@nehon said: Well that alone makes it worth the work :D

Cloth simulation are coming to my mind, It can ease the artist’s work on animations for example.


Foliage, particles etc. too.

Water simulation maybe…
Not as fancy as bouncing boobies I admit, but still.

Boobs is the uber application, idk how any1 needs any more reason :wink:

Big cars and boobs and beer, (screw water, beer simulation ftw) nuff said.

Whilst I have a firm idea of how to proceed with wrapping the C++ code into JME3 in the abstract, I’m having a problem in getting positive results from a test that I believe should be quite basic.
This tells me I might be missing something with the instantiation of objects and regulation of collisions in JME3.

I can create objects that fall within the simulation, but do not interact with other objects by piggybacking onto the end of jmePhysicsSpace::createPhysicsSpace with the following instantiation;

//Creation of a ground plane (rectangular prism)
btBoxShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(1.),btScalar(50.)));

//Setting physical parameters of plane
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,2,0));
btVector3 localInertia(0,0,0);
int mass = 0;
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);

//Adding plane to simulation
btRigidBody::btRigidBodyConstructionInfo planeInfo(mass,myMotionState,groundShape,localInertia);
btRigidBody* planeBody = new btRigidBody(planeInfo);
world->addRigidBody(planeBody);


//Creation of a rigid sphere
btSphereShape* ballShape = new btSphereShape(btScalar(1.));

//Setting physical parameters of sphere
btTransform ballTransform;
ballTransform.setIdentity();
ballTransform.setOrigin(btVector3(0,12,0));
int ballMass = 10;
btDefaultMotionState* myBallMotionState = new btDefaultMotionState(ballTransform);

//Adding rigid sphere to simulation
btRigidBody::btRigidBodyConstructionInfo sphereInfo(ballMass,myBallMotionState,ballShape,localInertia);
btRigidBody* sphereBody = new btRigidBody(sphereInfo);
world->addRigidBody(sphereBody); 

These added objects do not interact with each other or objects instantiated from the JME3 java side, through the JNI interface.

My thinking is that the C++ functions called by the JNI interface are different to those that I’m calling, but I cannot for the life of me figure out what aspect of the instantiation I’m missing.

Do you guys have any ideas?

any updates ? or other solution to do softbody with jme3 ?

Thx

Hello, i browsed a few JNI/JNA tutorials/howto’s lately and i found jnaerator (https://code.google.com/p/jnaerator/) and birdj (https://code.google.com/p/bridj/)

The question is, would it be an option, (or even possible) to create all needed bindings? After all the doc says that you can subclass c++ classes in java, which would make the integration quite easy i think…

I would spend some time on such a project, if someone with some deeper knowledge would support the project.

After all, if the jnareator/birdj workflow works nicely lots of native projects could be included

Well c++ bndings itself are not that difficult (after initial learning of course)

Even without all helping stuff, and doing it by hand.
Only thing to keep in mind:
-> JNI is C, not C+

So basically for each call just submit the object to the antive side you mean.
You can just store a 64 bit pointer to them on the java side, and thats it.

Then create a nice wrapper class taht mimics the native one around it that hides all the uglys and done.

Take a look at the bullet integration in the source code, if youa re interested in doing so.

I might say that for phsics ina game you likly need performance, so jna is a bit worse choice for call heavy parts. (eg update mesh logic)

Yeah, best use normal JNI and no “binding creation tool”, gives the most portable code, with these tools you never know what issues you get later on (avian for iOS, android etc etc).

In the case of softbodies the problem is a bit more complicated than straight bullet rigidbodies as we would probably have to use a separate type of mesh so that bullet can modify the native buffers and doesn’t have to go native->java->native to transfer the mesh data from the softbody to the actual geometry. This would also rule out the use of threading for this though.

@zzuegg from my experience javacpp is better than jna/bridj (see discussion at http://hub.jmonkeyengine.org/forum/topic/recast-ai-devlog-2/#post-288375)

@zzuegg said: Hello, i browsed a few JNI/JNA tutorials/howto's lately and i found jnaerator (https://code.google.com/p/jnaerator/) and birdj (https://code.google.com/p/bridj/)

The question is, would it be an option, (or even possible) to create all needed bindings? After all the doc says that you can subclass c++ classes in java, which would make the integration quite easy i think…

I would spend some time on such a project, if someone with some deeper knowledge would support the project.

After all, if the jnareator/birdj workflow works nicely lots of native projects could be included

From my experience javacpp is better than jna/bridj/swig. You can see discussion at http://hub.jmonkeyengine.org/forum/topic/recast-ai-devlog-2/#post-288375 , I provided some code fragment.

@normen, so integrating bullet’softbody is not made and not a easy task to complete.

Are you aware of an alternative softbody (or spring-mass) solution for jme3 ?

Ok, i see the point of using no binding creation tool.

Regarding the native->java->native transfer, bridJ supports pointerTo(NIO buffer) so it might be able to write directly to the buffers if the threading issue can be solved.

The point i am trying to make is that when using direct bindings with JNA instead of JNI we should no be required to write/compile any native code. As the doc say everything can be done on java side.

Additionlly, i it is possible to create a full wrapper over bullet not only jme might benefit.

Regarding performance, i assume that the drawing takes about 99% of the time, if the JNA bullet binding (on another thread) is slower then JNI, there is probably no noticable frametime difference