Need Help. XPAL implementation for Odejava

hi

I have ported the JOODE XPAL (Xith3D Physics Abstraction Layer) implementation to Odejava. But there are many things, that I simply don’t know, how to do in Odejava. So I need help. Would be very cool, if there was somebody, who can have a look at the code (to be found in the “xith-odejava-jni” branch in the xith3d folder of the Odejava CVS) and tell me, how to do everything marked with a TODO. Thanks in advance.

Marvin

When I try to run an XPAL example I get this:


Exception in thread "main" java.lang.UnsatisfiedLinkError: dWorldCreate
	at org.odejava.ode.OdeJNI.dWorldCreate(Native Method)
	at org.odejava.ode.Ode.dWorldCreate(Ode.java:620)
	at org.odejava.World.<init>(World.java:111)
	at org.xith3d.physics.collision.odejava.OdejavaCollisionEngine.<init>(OdejavaCollisionEngine.java:79)
	at org.xith3d.physics.OdejavaPhysicsEngine.<init>(OdejavaPhysicsEngine.java:10)
	at org.odejava.xith3d.test.xpal.PhysicRotationTest.setupPhysicsAndScene(PhysicRotationTest.java:125)
	at org.odejava.xith3d.test.xpal.PhysicRotationTest.<init>(PhysicRotationTest.java:215)
	at org.odejava.xith3d.test.xpal.PhysicRotationTest.main(PhysicRotationTest.java:234)

Is there anything I need to call to initialize ODE?

Marvin

I’m pretty sure there is an Odejava.init() call you have to make statically, not sure though since it’s been a while since I played with joode. If this init() method exists, it might call dInitODE() and if it doesn’t, you need to make sure this gets called.

Thanks. Odejava.init() did the trick. And yes, it calls dInitODE().

Marvin

How can I check for collisions between

  • Two Geoms
  • A Geom and all the Geoms of a Space
  • All the Geoms of a Space A and all the Geoms of a Space B

?

And what’s the difference between NativeCollision, JavaCollision and PureJavaCollision? I mean, what should I use in what situation?

And: Can I do a collision check without a World object? It seems, that I always need a World to instantiate a Collision instance. But what if I don’t need the simulation part?

Marvin

According to odejava’s javadocs, you’re supposed to use JavaCollision. I believe the difference is that NativeCollision is all native, PureJavaCollision is all java, and JavaCollision is a hybrid that uses NIO buffers. I’ve used the JavaCollision and I’ve found it fairly easy to use. Just look at the source code for the various tests included with odejava and it should be obvious (if you haven’t already figured out how to use them).

I think you would use PureJavaCollision if you want java implemented callbacks. JavaCollision only lets you iterate through the contacts and set the parameters I believe. However according to the docs, PureJavaCollision isn’t fully implemented or tested.
NativeCollision performs the collision detections fully on the native side without providing any information back to java and the contacts are unmodifiable.

I’ve only ever used JavaCollision, but when you use JavaCollision.collide(Space space), it collides all of the geometries within that space, I’m not sure how to explicitly collide just 2 geoms or between spaces (I’ve tried using the low-level methods and it didn’t end well since the SWIG objects are hard to manipulate and use).

You have to pass in a world object (I think the swig stuff requires an id handle from it), but you don’t need to do the simulation. Just don’t call a stepper function and only call Collision.collide(…).

Hope that answers your questions.

Thanks for the detailed info. Well, checking for collisions between space-space or geom-space should be a very rare situation. I currently need Geom-Space only anyway. But I do need Geom-space, but not Body-space. I will see, if I can create some kind of dummy Body to do this. Or do you think, there’s a better way?

Marvin

I’m not sure what you mean by Body-Space collisions. It was my impression that Body’s had nothing to do with collision detection in odejava. You would link a body and a geom together so they would share the same transformation but the Body would be stepped and the Geom would be collided. The collisions in odejava will work correctly if the Geom doesn’t have an attached Body (it treats those Geom’s as static objects).

Oh. My bad. What am I talking about? Well, the JavaCollision.collide(Space) does an nxn collision check between all contained geoms, doesn’t it? If that’s true, there must be a better way of checking collisions. Otherwise I would have to check for all collisions in a space and ignore the ones, I’m not interested in. And I would have to add my single Geom to the Space where it shouldn’t be in. That’s really odd.

Marvin

I might be mistaken but you can add Spaces to spaces to create a tree structure. If you call collide() on the parent space it will collide the spaces (and any Geoms therein as well) with each other and then the geometries appropriately. This is my guess because that’s the way ODE is supposed to work but the only available way in odejava is using a jni call. I haven’t looked at the source, but I wouldn’t be surprised if JavaCollisions native side did this for us.

The complexity of the collision detection depends on the type of space that you use. A SimpleSpace should be nxn. In ODE there are many types of spaces, many of which aren’t available in odejava.

To get things to ignore collisions you’re not interested in you can set the collide bits.

Because odejava is so far behind ode and the original developers have left us with a lot of loose ends and things that don’t always work, I wonder if it would be better to start over from scratch? Then we might not have to define the cumbersome interface file for swig, especially if we’re able to use gluegen (not exactly sure what it can do, but I think it is similar to swig, but I don’t know if it’s limited to jogl only).

Simply use a single space (I recommend a HashSpace). If you need all collisions and only ignore a few ones, let ODE compute them with collide(space) - that’s much cheaper (not n^2 btw). If you are interested in a few collision checks, only, use collide2 - you can pass in (space, geom) or even (geom, geom).

It’s not. odejava-jni uses the most recent ODE release and can even use the trunk.

collide2() takes two ints. What should I pass there?

Marvin

as I wrote: (space, space), (geom, space) or (geom, geom) - their ids (addresses) of course - see ODE doc

Sorry, but just to make sure then, the jni libraries in odejava-jni/lib will then work with ode-0.9? And the generated files will work as well?

yes, they include ODE 0.9. The only problem currently is the ppc support - we have no universal binaries for the head (but intel mac only). But that’s a matter of solving the build problems (and I don’t have a mac :-).

My mistake, the odeJNI didn’t contain a few calls to some new features for ODE, namely the one I noticed was that there was no interface for dCreateHeightfield() and the other functions part of the Heightfield Geom class. Anyway, it’s trivial to add them to odejava.i, so when I have more time, I’ll just do that.

I only have an intel mac, so I might be able to get it to build with -arch=ppc, but I wouldn’t be able to test if it works on a ppc mac.

Stupid me. Should have read the docs :). Well, why are the adresses (returned by getNativeAddress()) long while the collide2() method takes two ints? Is it a problem to just cast them to int? Or am I using the wrong method to retrieve the address? A Space doesn’t even have a getNativeAddress() method, nor any other one, that could be, what I need. So where can I get the (relevant) IDs from (especially for spaces)? Since the collide2() method is used nowhere in any example, I cannot just have a look at an example.

Marvin

OK, I have added a getNativeAddress() method to Space (and implemented all the necessary stuff). I have also set the nativeAddress back to zero in the delete method (of Space and Geom). I guess, this is correct. I will commit my changes in a few hours so that you can review them.

And I have changed the method signator of JavaCollision.collide2() to take two longs, since the Odejava.spaceCollide2() also takes two longs. So this should be correct.

Marvin

Yep. Great you already figured it out.

What about the nativeAddress thing in Space? Is that correctly implemented?

Could you maybe have a look at org.xith3d.physics.collision.odejava.OdejavaCollisionEngine.java (in the Odejava source)? I tried to implement collisions there, but it leads to a JVM crash. Did I do anything wrong? Thanks

Marvin