Marvin Fröhlich
|
 |
«
Posted
2007-11-19 20:27:21 » |
|
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
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #1 - Posted
2007-11-19 21:14:14 » |
|
When I try to run an XPAL example I get this: 1 2 3 4 5 6 7 8 9
| 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
|
|
|
|
|
lhkbob
|
 |
«
Reply #2 - Posted
2007-11-20 00:32:38 » |
|
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.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Marvin Fröhlich
|
 |
«
Reply #3 - Posted
2007-11-20 01:58:53 » |
|
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
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #4 - Posted
2007-11-20 03:06:05 » |
|
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
|
|
|
|
|
lhkbob
|
 |
«
Reply #5 - Posted
2007-11-20 03:24:03 » |
|
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.
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #6 - Posted
2007-11-20 03:31:58 » |
|
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
|
|
|
|
|
lhkbob
|
 |
«
Reply #7 - Posted
2007-11-20 03:47:12 » |
|
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).
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #8 - Posted
2007-11-20 04:26:10 » |
|
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
|
|
|
|
|
lhkbob
|
 |
«
Reply #9 - Posted
2007-11-20 04:34:09 » |
|
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).
|
|
|
|
Games published by our own members! Check 'em out!
|
|
irrisor
|
 |
«
Reply #10 - Posted
2007-11-20 09:46:38 » |
|
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). Because odejava is so far behind ode
It's not. odejava-jni uses the most recent ODE release and can even use the trunk.
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #11 - Posted
2007-11-20 12:28:15 » |
|
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).
collide2() takes two ints. What should I pass there? Marvin
|
|
|
|
|
irrisor
|
 |
«
Reply #12 - Posted
2007-11-20 14:47:06 » |
|
as I wrote: (space, space), (geom, space) or (geom, geom) - their ids (addresses) of course - see ODE doc
|
|
|
|
|
lhkbob
|
 |
«
Reply #13 - Posted
2007-11-20 16:45:07 » |
|
It's not. odejava-jni uses the most recent ODE release and can even use the trunk.
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?
|
|
|
|
irrisor
|
 |
«
Reply #14 - Posted
2007-11-20 17:01:07 » |
|
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  ).
|
|
|
|
|
lhkbob
|
 |
«
Reply #15 - Posted
2007-11-20 18:28:05 » |
|
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. 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  ). 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.
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #16 - Posted
2007-11-20 20:01:45 » |
|
as I wrote: (space, space), (geom, space) or (geom, geom) - their ids (addresses) of course - see ODE doc
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
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #17 - Posted
2007-11-20 21:37:58 » |
|
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
|
|
|
|
|
irrisor
|
 |
«
Reply #18 - Posted
2007-11-20 22:32:27 » |
|
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.
Yep. Great you already figured it out.
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #19 - Posted
2007-11-20 23:19:57 » |
|
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
|
|
|
|
|
irrisor
|
 |
«
Reply #20 - Posted
2007-11-21 09:34:40 » |
|
What about the nativeAddress thing in Space? Is that correctly implemented?
If you can execute a call to collide2 it is  ... looking at it, now... ...there are copy paste bugs in the javadoc of getSpaceFromNativeAddr... ...you implemented nativeAddr correctly - but that cannot be used for collide2, as that expects the ID  . The ID is an address, but not the native address - the ID points to the native address. This confusing pointer stuff is caused by bad use of SWIG - all of this getNativeAdress and getCPtr stuff should be removed, but I didn't take the time for it. 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
looks ok - only that you must not use the nativeAddress but the CPtr
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #21 - Posted
2007-11-21 20:28:15 » |
|
Ah, Thanks. I've changed that to use getCPtr() instead of getNativeAddress(). No crashes anymore  . But I also don't receive any collisions. Do I have to do anything more than just collide2() and then iterate over collision.getContactCount()? Marvin
|
|
|
|
|
irrisor
|
 |
«
Reply #22 - Posted
2007-11-21 21:23:16 » |
|
You need to apply them to get contact joints. Or do you mean that there are no collisions reported to iterate over?
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #23 - Posted
2007-11-21 22:09:50 » |
|
You need to apply them to get contact joints. Or do you mean that there are no collisions reported to iterate over?
Yes. This is the code: 1 2 3 4 5 6 7 8 9 10 11
| JavaCollision collision = new JavaCollision(world); Contact contact = new Contact(collision.getContactIntBuffer(), collision.getContactFloatBuffer());
collision.collide2(c1, c2);
for (int i = 0; i < collision.getContactCount(); i++) { } |
The world passed to the JavaCollision constructor is a new World instance, that has nothing to do with the rest of the scene. Could this be a problem? The collision.getContactCount() call always returns 0, no matter if I execute collision.applyContacts() before. Marvin
|
|
|
|
|
irrisor
|
 |
«
Reply #24 - Posted
2007-11-22 09:53:56 » |
|
The world passed to the JavaCollision constructor is a new World instance, that has nothing to do with the rest of the scene. Could this be a problem?
 of course! The geoms need to be in the same world and the JavaCollision needs to know that world. You should not create more than one JavaCollision per world, btw - it uses many resources (esp. native contact buffer) and I'm not sure they are freed correctly (e.g. with garbage collection of the Java object). And: you not invoke apply contacts before iterating through them but after you iterated through them and values were customized. Have a look at the demos - contacts are working fine in the old xith demos. Note (maybe I did not express that string enough before) : by using collide2(geom,geom) for all the geoms you kind of 'misuse' the collision detection - you don't use spaces, and spaces are the important stuff to make collision detection fast. So if you plan to do simulation where most things can collide with each other, use spaces and collide them!
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #25 - Posted
2007-11-22 12:04:28 » |
|
 of course! The geoms need to be in the same world and the JavaCollision needs to know that world. What if the Geoms are NOT in any World? Do I have to put them into a World just to do collision detection even if I don't need the simulation part? You should not create more than one JavaCollision per world, btw - it uses many resources (esp. native contact buffer) and I'm not sure they are freed correctly (e.g. with garbage collection of the Java object).
Well, I only created one JavaCollision per check for testing reasons. I wanted to make it a singleton. So don't worry  . And: you not invoke apply contacts before iterating through them but after you iterated through them and values were customized. Have a look at the demos - contacts are working fine in the old xith demos.
Well, as I said. It's not working with or without the applyContacts() call. Btw. What do I have to call to remove the joint contacts again (if there's anything). And none of these demos uses collide2(). They all use collide(). Note (maybe I did not express that string enough before) : by using collide2(geom,geom) for all the geoms you kind of 'misuse' the collision detection - you don't use spaces, and spaces are the important stuff to make collision detection fast. So if you plan to do simulation where most things can collide with each other, use spaces and collide them!
Well, everything should be possible. The very most used case is geom-space, which is where I need collide2(), too. But It should use the space for optimization, shouldn't it? If ONLY one geom is to be tested against one geom, it is certainly faster to just test that geom, but not all the others in the same space, too, right? Marvin Marvin
|
|
|
|
|
irrisor
|
 |
«
Reply #26 - Posted
2007-11-22 12:40:45 » |
|
What if the Geoms are NOT in any World? Do I have to put them into a World just to do collision detection even if I don't need the simulation part?
Ah, ok, that should be fine. Then you don't need to apply contacts (which is the only thing that uses the world) either. The very most used case is geom-space, which is where I need collide2(), too. But It should use the space for optimization, shouldn't it? sure And none of these demos uses collide2(). They all use collide(). Uh, true. But it's used in jME Physics 2... Probably the geoms' positions are wrong? Or you passed the geom and not the geomTranform?
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #27 - Posted
2007-11-22 20:16:23 » |
|
Ah, ok, that should be fine. Then you don't need to apply contacts (which is the only thing that uses the world) either.
ok. Just to make sure: The collide2() call will traverse through all the whole space (if a space is passed), and maybe subspaces, but not just check the space itself, right? Probably the geoms' positions are wrong? Or you passed the geom and not the geomTranform?
This is a good point. I just use pass the geom's/space'es IDs to the collide2() method like this: collision.collide2( geom1.getID(), space2.getID() ); // getID() returns the result of getCPtr(). Where do I get the GeomTransform from? Marvin
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #28 - Posted
2007-11-22 21:11:32 » |
|
I have embedded the actual Geom within a GeomTransform and am using it for positioning and collision detection. But I still don't get any collisions  . Any hints? Could you maybe setup a small example using collide2()? Marvin
|
|
|
|
|
Marvin Fröhlich
|
 |
«
Reply #29 - Posted
2007-11-22 21:51:35 » |
|
OK, I found one bug. The internal call to spaceCollide2() returns the contact count as well as the spaceCollide() method does. But the value was not stored to the contactCount variable. Now I am getting contact counts.
Marvin
|
|
|
|
|
|