Bowl of Eggs Physics Demo

Hello, my buddy uses the UNITY game engine and I asked him to do a demo using a curved surface (bowl) holding some eggs to see the physics and collision detection ability.

Here is the UNITY sample’s link:
vids.myspace.com/index.cfm?fusea … 2016335848

Looks pretty cool in my opinion so he asked what Panda could do …any ideas how to do this in Panda? Would I be able to use the basic collision detection equations with specific functions or would I need something more like PyODE integration.
The problems I see are like the Ralph demo on uneven terrain: I guess a bowl would be like an uneven terrain, no?

Anyway, if anyone could give an idea of how to set this up. I plan to use the samples of the maze, ynjh_jo 's great samples, and Roaming Ralph to start.

Thanks!

guess you need PyODE for this. panda’s collision and physics are very basic.
there are a couple of posts here in the forum about how to use pyode. incudling a function to pass triangle-geometry. should work fine with it.

the samples use manually coded “physics”. its more or less python code to define the behaviour of ralph and the ball combined with basic collision detection. wouldnt work too well in your case since you have 2 meshes colliding with each other. panda is only good if you have one mesh (like a terrain) and a collison solid like a ray or a sphere.

Thanks for the reply…

To understand better, based on your answer… If there were only one egg in that bowl then Panda’s hard coded “physics” would work just fine to simulate that action?

hm… not exactly… if there would be oanly one egg which would be a perfect sphere it would be possible to code the behaviour quite easy.
but since egg’s are no perfect spheres and since you have more than one egg it would be very difficult without a real physic engine.

Hello,

do you mind providing a (temporary) download for the the egg and bowl meshes, in a format that is easy to convert, e.g. Wavefront OBJ or DirectX?

I’d like to give it a try using Newton convex hulls.

enn0x

Awesome! I hope you are able to do it. Here is a temporary download link for you…I made the meshes as OBJ file. Let me know if you need them as seprate files (they are seperate meshes though!) Thanks !
here is the link:

yousendit.com/download/M3Brc … bmcwTVE9PQ

PS is the Newton convex hulls part of Panda?

I took the dare and –[THIS]– is the result.
Use arrow keys to move the bowl, SPACE to lift it, and TAB to see the egg’s collision spheres. I use 3 spheres for 1 egg, which are arranged to fit the egg’s shape. I created those spheres since modeling phase, and then loaded and sent to ODE. Then they get connected by fixed joints to lock it’s position relative to each other. And since they overlap each other, I modify my OO classes a little to allow multiple collision geoms build a larger custom collision structure. It’s cheap, runs at 65+ fps for 15 eggs.
The result is interesting, when the egg is on the table and get hit by the bowl’s side, it spins while circling over it’s orbit. It could spin upright or at very shallow angle, just like motoGP racer circling the circuit :laughing: . It can be fun afterall.

This is super impressive. I just showed my buddy this and he couldnt beleive what you did with this scenario.
See UNITY has it all built in (the Agia Physx engine) and to get what you did requires no coding at all. So this is brilliant…he is really impressed with Panda and I told him that knowing how to code this type of stuff has its benefits in the long run.
I didnt get this far at all, I was still studying the OOriented PyODE sample that ynjh_jo made!

Speaking for the panda community…thanks for the contributions to Panda3D.

really nice example… had to change “from direct.ode import ode” to “import ode” but nice…
and now the 1mio dollar question… why is the empty bowl harder to lift than the full one? :smiley:

ynjh_jo,
Let me know if I am wrong in understanding this,…
but you modeled/created some spheres and then fit them into the egg model…then exported them to Panda? Are these spheres Panda primitives or new mesh models? How did you manage to fit the spheres so perfectly into the egg model? Thanks.

Ok, I moved ode.pyd to Panda install dir.

I’m not sure, but now I use stay-pressed key to lift it, so you don’t have to hit the SPACE like crazy. And that weird behaviour doesn’t show up again.

@ Liquid7800:
those spheres are just ordinary polygonal spheres, arranged by hands in modeling phase, to make them fit the egg skin perfectly. Then in ODEsphere, the sphere is passed in as collObj, which next queried for it’s radius by iterating through it’s vertices. For that, basically you only need 1 triangle for each sphere, but I’d like to see them, so I left them uncorrupted.
I just added new param to ODEsphere : isPerfectSphere. If it’s true, it would grab only the 1st vertex. If it’s false, it would iterate through all vertices, looking for the outermost vertex, to make sure the object is covered entirely, but not overcovered as if using the bounding volume. As you can see, no more lag during reset scene, right ?

that’s cool, so your buddy must use the eggs’ triangles to collide with the bowl. Unfortunately, my trimesh-trimesh collision using ODE is far from expectation. Maybe it’s due to old version, or I just haven’t figured out the best way to do collision response when both colliding objects are trimeshes.

update : ODE6-bowlEgg.py

Back with may own version off the eggs in a bowl. I use self-written bindings for Newton Game Dynamics. The bindings are not yet complete (e.g. rad dolls are missing) and there are still some issues (e.g. with scaling). As soon as I have enough webspace again I will release a first alpha. I already busted my html quota.

The eggs in my version have convex hull collisions created from the mesh vertices. So it is kinda trimesh-trimesh collision. Something Newton is rather good with.

But it comes at a price: for the bowl I had to use a tree collision. Tree collision is a polygon mesh that been designed and optimized for collision with (large) static scenes, like terrain and static objects. And this means I have to cheat when it comes to shaking the bowl. I have to move the gravity vector and rotate the camera while the bowl stays where it is :frowning:

Anyway, performance is about the same a ynjh_jo’s ODE demo, but with mesh-mesh collisions.

http://www.dachau.net/users/pfrogner/10-Egg-Bowl.zip (including win32 binary for PandaNewton)

enn0x

It’s great, all sim (detection->response) is done entirely at low level.

  1. I don’t know anything about Newton. So Newton doesn’t seem to know about joint/constraint (nail, hinge, spring, etc.) to connect bodies. Then how do you build a complex system ? Is it true, or it’s just because you haven’t binded that yet ?
  2. I found something wrong in your code, as you said : scaling, both in makeCollisionHull and makeCollisionTree.
    You want the relative pos of each vtx at the top root’s coordinate space, right ? But why did you bring it to the object’s CS ? It should be the top parent.
  3. in makeEgg, only position and rotation from the matrix is used. How about the scale, ignored ? but the convex hull is already scaled. Or is this scaling what you meant ?
  4. How does Newton deal with friction ? Which friction coef would be used when 2 meshes collide, the small one or the average, or what ?
    My bottleneck is Python…

Thank you, ynjh_jo. But it is not as shiny as it might look at first. ODE and Newton are very similar in what they can do or how fast they are. I think it is down to personal preferences.

for 1: Newton has joints too, and they are wrapped already, except for user defined joints (6DOF). Basic joints like ball, hinge, slider are almost the same in both engines. Newton has an UpVector joint for keeping actor upright even on slopes. And ODE hinge2joint is JointVehicle, only that you have to create one joint per vehicle and add tires to it.

for 2: The scaling is defaulted to (1,1,1) if I remember right. This is a code fragment remaining from some of my experiments with NodePath scaling. I have an unsolved issue when using setScale( ) on a node path, both from C++ and from Python. Panda3D crashes and complains about transform states having no previous state, weired). For now I use no scaling with Newton, until I found the reason for these crashes.

Hmm… about the coordinate system transformation. I thought I had it transformed from the geom nodes CS to the top NodePaths CS, but I might be wrong. I believe you are right, and will look at the code this evening.

for 3: The C++ transform callback ignores scale and shear for now. This is what I meant about scale. Perhaps I will change the API sometime to set position, orientation and scale of a Body, once it has become stable.

for 4: Friction is supported (of course :-), by employing a material system. Each body can have a material, and properties like static/kinetic friction, elasticity, softness can be set for a material pair. e.g. for vehicle tire on wet stone.

Newton offers a lot of callbacks to the user, for example if the simulations is advanced by a timestep dt then newton does update the position and orientation of a body. But the graphical representation is still where it is. So Newton offers a “transform callback” that gets called every time a bodies transform is changed by Newton. One useful thing to do in such a callback is updating the graphical object (NodePath). When wrapping Newton I decided to offer two choices. Either implementing a python method to do the updating of a NodePath (and whatever a user would want to do), or using a “default” callback implemented in C++. For most cases the default callbacks will be sufficient, and a little bit faster than Python callbacks.

A real advantage of Newton is the collision tree which can handle static geometry of 50000 and more polygons at reasonable speed, but raytaller has some very interesting Panda3D work here too. The big disadvantage: Newton is free but closed source :frowning:

Please give me a few days. Even if there are still a lot of issues I will try to come up with a first release (including source and basic demos) next weekend.
enn0x

@ enn0x Looks great! By employing a physics engine you really have shown some neat things Panda is capable of. Did you write your own Python “wrapper” for the newton system into Panda or is there one out there?

@ ynjh_jo I think your example is on par with the Unity demo. I am slowly getting familiar with the way ODE works, saying that, would it have been possible just to use the Egg model (not the spheres) as the colObj interacting with the bowl? Or does ODE not support asymetrical objects (like an egg vs a sphere?)

I guess to state this better is: why did you need to use spheres to get ODE to detect the collision. Thanks!

@ enn0x
I checked your code again. Sorry, there is nothing wrong in makeCollisionHull and makeCollisionTree. The problem is you didn’t pass the object’s scale to them.

@ Liquid7800
if you’d like to see trimesh-trimesh collision, use ODEtrimesh instead of ODEsphere.

I just found something about ODE :

in here :
ode.org/ode-latest-userguide.html

That explains why trimesh-trimesh collision is so horrible !

That sure does explain it. Thanks for the link.

I was playing around with your example, ynjh_jo, and I was trying to incorporate tilting the bowl on its orgin (like the maze example) with the mouse to roll the egg with the bowl (in addition to your arrow controls).

I added this function in the code and called it in the gLoop function

    def tiltTask(self):
    #Read the mouse position and tilt the maze accordingly
       if base.mouseWatcherNode.hasMouse():
          mpos = base.mouseWatcherNode.getMouse() #get the mouse position
          self.bowl.setP(mpos.getY() * -10)
          self.bowl.setR(mpos.getX() * 10)

The bowl tilts, but the tilting doesnt affect the egg at all. I assume it is because it is the (ODE) collObj that needs to tilt as well but I am unclear on how to do that.
Does anyone have any suggestions, thanks

If you want to affect the physics system, you should apply the changes to the body (for forces, position, rotation), or geom (for position & rotation).
Add this line to rotate the bowl’s body :

          self.SIM_bowl.body.setRotation(self.geomRotMat(self.bowl.getHpr()))

Thanks for the idea!

You worded it correctly. I wanted to affect the physics system…

It is very frustrating to be so new to this, but I am trying to begin the simulation with the bowl levitating at a height of say 2. The tilting is proving to be a little unstable.
I looked at your “lifting” code and the ODE API about position and orientation but I cannot figure out how to begin and have the bowl lifted consistently at a determined height.
Any guidance is appreciated