From: Simon H. <twi...@ob...> - 2007-04-23 00:15:52
|
Firstly, I'd like to second Martijn's sentiment - ODE (and PyODE) are very nice to work with. :) Secondly - I have a problem that I hope someone has already solved, and that they can point me in the right direction... I'm working on a physics-enabled boardgame environment ( http://groups.google.com/group/pyglet-users/web/geoffrey-a-board-game-environment ) and I'm using PyODE for selection and collision detection/physics. The selection code works perfectly (using glUnProject to position a GeomRay in the scene, then test for contacts with pieces) but I'm slightly stuck on *moving* the selected piece to keep it under the mouse pointer each frame. First I tried setting it's position every frame, but that doesn't seem like the right way to do it, as collisions become unreliable. I tried setting it's linear velocity so that it would move to the target position each frame, but I couldn't get that working nicely either. I've experimented with attaching the object to *another* object, and setting *it's* position, but that didn't seem like the right solution - and applying a force (as per the 'thrust control logic' article in the wiki) didn't seem like it would solve my problem either. Am I going about this the wrong way? I *do* seem to be fighting ODE for control of the object - is it back-to-front to think I can control an ODE object's exact position, while still having it collide with other objects? Any suggestions welcome. :) Sincerely, Simon Hildebrandt. |
From: Chris B. <chr...@gm...> - 2007-04-23 09:00:59
|
On 23/04/07, Simon Hildebrandt <twi...@ob...> wrote: > Firstly, I'd like to second Martijn's sentiment - ODE (and PyODE) are very nice to work with. :) > > Secondly - I have a problem that I hope someone has already solved, and that they can point me in the right direction... > Am I going about this the wrong way? I *do* seem to be fighting ODE for control of the object - is it back-to-front to think I can control an ODE object's exact position, while still having it collide with other objects? The problem is that you're simulating a body with ODE. The body has mass, velocity, momentum etc. which I'm assuming you don't want - you want to click and drag the object instead. So you can either: a) not use an ODE body for your object - use a Geom, do the collision detection, then in your collide handler create an ode.ContactJoint, and instead of attaching it to the body of the draggable Geom attach it to the static environment (ode.environment). That should give ODE a contact on the object you hit, but not on the one you're dragging. b) envisage the mouse location as somewhere you'd like the object to be, rather than actually is. Use something like a proportional derivative or LQR controller to add forces to the dragged object in order to reposition it. This way you're treating the object as a proper body, so there will be some delay before it reaches your desired position. |
From: Chris B. <chr...@gm...> - 2007-04-24 08:42:10
|
On 24/04/07, Simon Hildebrandt <twi...@ob...> wrote: > Chris Bainbridge wrote: > > a) not use an ODE body for your object - use a Geom, do the collision > > detection, then in your collide handler create an ode.ContactJoint, > > and instead of attaching it to the body of the draggable Geom attach > > it to the static environment (ode.environment). That should give ODE a > > contact on the object you hit, but not on the one you're dragging. > > > *nod* Yeah - from reading the wiki, that seemed to be the best technique > to isolate the selected object. > > Particularly, I'm wondering what would be the best way to get the > selected object in motion? Setting the position seems to interfere with > the collision detection, and I don't think I could get the positioning > accurately by adding forces... Setting velocity, then? You set velocity, add forces etc. to ODE bodies. Those are the things with mass. Geoms are just shapes - you can translate them and rotate them, but they have no properties like velocity. So if you only have a Geom, you have to set its position. Now the collision detection normally generates a ContactJoint constraint from the two Geoms and then applies it to the actual ODE bodies in order to push them apart. In your code this looks something like: j = ode.ContactJoint(self.world, self.contactGroup, c) j.attach(geom1.getBody(), geom2.getBody()) c is the contact - you can get its parameters with c.getContactGeomParams(), which returns the depth, normal, and two intersecting Geoms. As this code shows, the actual collision detection is completely separate from the ODE body simulation. So setting a position directly is only going to be a problem if you have an ODE body attached to the Geom. You can play around with it by calling ode.collide(geom1,geom2) and examining the list of contacts it returns. It's completely up to you how this list gets applied in the ODE simulator; it's just a list of Geoms, intersection normals, penetration depths, and friction coefficients. |