[ODE] Bowling physics
Jon Watte (ODE)
hplus-ode at mindcontrol.org
Thu May 10 11:15:23 MST 2007
Note that, in simulation, you can get much more precise forces than in
real life. A sphere that falls STRAIGHT down onto a box, will just come
to rest on that box.
For bowling pins, I've preivously used a collection of three primitives:
1) a capsule for the main pin part
2) a sphere for the lower globe part
3) a small box positioned at the bottom, to make the pin stand up
Note that you can attach more than one geom to a body, and they can
intersect without problems.
Cheers,
/ h+
samira S. wrote:
> Hello
>
> I need to get some realistic Bowling-Physics by using ODE.
> Actually this should not be too hard, but I am new to physics engines and I
> have the following problems:
> I created two boxes which should approximate my BowlingPins. However when I
> tried to let a sphere push them over, they just slipped away on the ground
> (approximated by a plane)
> I tried to change several Parameters, like friction (surface.mu,
> surface.mu2), mass, the spheres velocity and initial force, but the boxes
> were never pushed over, they only slide away.
>
> Then I tried the following:
> Box1 is standing on the plane and Box2 is on top of it, but horizontal, in
> such a way that it should fall down (see picture). In addition I let a
> sphere fall on Box2 so that the Box should really fall down. However, this
> didn´t happen. The sphere just stayed on Box2.
>
> O Sphere
> ------------- Box2 is horizontal
> l
> l
> l
> l
> l Box1 is vertical
>
>
> Please, can anyone tell me what I am doing wrong in my implementation, or
> which parameter could be wrong or missing?
> I am using Visual Studio C# and the Tao-Framework-bindings for ODE. But
> anyone who knows ODE should understand my Code as well:
>
>
> private void main()
> {
> world = Ode.dWorldCreate();
>
> Ode.dWorldSetGravity(world, 0,0,-9.81f);
>
> space = Ode.dSimpleSpaceCreate(System.IntPtr.Zero);
> contactgroup = Ode.dJointGroupCreate(0);
>
> floorGeom = Ode.dCreatePlane(space,0,0,1.0f,0);
>
> sphere_body = Ode.dBodyCreate(world);
> sphere_geom = Ode.dCreateSphere(space,10);
>
> pin1_body = Ode.dBodyCreate(world);
> pin1_geom = Ode.dCreateBox(space,10,10,100);
>
> pin2_body = Ode.dBodyCreate(world);
> pin2_geom = Ode.dCreateBox(space,10,100,10);
>
> Ode.dGeomSetBody(sphere_geom,sphere_body);
> Ode.dGeomSetBody(pin1_geom,pin1_body);
> Ode.dGeomSetBody(pin2_geom,pin2_body);
>
> Ode.dMass sphere_mass = new Ode.dMass();
> Ode.dMassSetSphere(ref mass, 2500, 10);
>
> Ode.dMass pin1_mass = new Ode.dMass();
> Ode.dMassSetBox(ref pin1_mass,2500,10,10,100);
>
> Ode.dMass pin2_mass = new Ode.dMass();
> Ode.dMassSetBox(ref pin2_mass,2500,10,100,10);
>
> sphere_mass.mass = 100;
> pin1_mass.mass = 15;
> pin2_mass.mass = 15;
>
> Ode.dBodySetMass(sphere_body, ref sphere_mass);
> Ode.dBodySetMass(pin1_body,ref pin1_mass);
> Ode.dBodySetMass(pin2_body,ref pin2_mass);
>
> Ode.dBodySetPosition(sphere_body,0,10,190);
> Ode.dBodySetPosition(pin1_body,0,80,50);
> Ode.dBodySetPosition(pin2_body,0,50,105);
>
> Ode.dBodySetLinearVel(sphere_body,0,0,-2000);
>
> float time = 0;
>
> float deltaTime = 0.04f;
>
> while(time < 2)
> {
> //Get the bodies position
> Ode.dVector3 position = Ode.dBodyGetPosition(sphere_body);
> Ode.dVector3 pin1_position = Ode.dBodyGetPosition(pin1_body);
> Ode.dVector3 pin2_position = Ode.dBodyGetPosition(pin2_body);
>
> //Get the bodies velocity
> Ode.dVector3 velocity = Ode.dBodyGetLinearVel(sphere_body);
> Ode.dVector3 pin1_velocity = Ode.dBodyGetLinearVel(pin1_body);
> Ode.dVector3 pin2_velocity = Ode.dBodyGetLinearVel(pin2_body);
>
> //Get the bodies Rotation
> // convert the quaternion to an axis angle so we can put the rotation
> Ode.dQuaternion rotation = new Ode.dQuaternion();
> Ode.dGeomGetQuaternion(pin2_geom,ref rotation);
>
> float cos_a = rotation.W;
> float angle = (float)(Math.Acos(cos_a) * 2.0f);
> float sin_a = (float)(Math.Sqrt(1.0f - cos_a * cos_a));
> if (Math.Abs(sin_a) < 0.0005f)
> sin_a = 1.0f;
> sin_a = 1.0f / sin_a;
> float x_axis = rotation.X * sin_a;
> float y_axis = rotation.Y * sin_a;
> float z_axis = rotation.Z * sin_a;
>
>
> // Print out the 'time', the body's position, rotation and its velocity
> Console.WriteLine("{0} sec: rot_angel={1} rot_axis=({2}, {3}, {4}))",
> time,angle,x_axis,y_axis,z_axis);
> Console.WriteLine("{0:0.00} sec: pos=({1:0.00}, {2:0.00},
> {3:0.00}) vel=({4:0.00}, {5:0.00}, {6:0.00})",
> time, position[0], position[1], position[2], velocity[0],
> velocity[1], velocity[2]);
>
> Ode.dSpaceCollide(space,(IntPtr)1, new Ode.dNearCallback(cbTest));
>
> Ode.dWorldStep(world, deltaTime);
>
> Ode.dJointGroupEmpty(contactgroup);
>
> time += deltaTime;
> }
> }//end main
>
>
>
> // nearCallback:
> static void cbTest(IntPtr data, IntPtr o1, IntPtr o2)
> {
> IntPtr b1 = Ode.dGeomGetBody(o1);
> IntPtr b2 = Ode.dGeomGetBody(o2);
>
> int MAX_COLLISIONS = 128;
>
> Ode.dContactGeom[] contactGeoms = new
> Ode.dContactGeom[MAX_COLLISIONS];
>
> int numc = Ode.dCollide(o1,o2,MAX_COLLISIONS,contactGeoms,sizeOf());
>
> Ode.dContact[] contact = new Tao.Ode.Ode.dContact[numc];
>
> for(int i=0; i<numc; i++)
> {
> contact[i].surface.mode =
> (int)Ode.dContactFlags.dContactBounce |
> (int)Ode.dContactFlags.dContactSoftCFM;
>
> contact[i].surface.mu = 5;
> contact[i].surface.mu2 = 5;
> contact[i].surface.bounce = 0.1f;
> contact[i].surface.bounce_vel = 0.1f;
> contact[i].surface.soft_cfm = 0;
>
> contact[i].geom = contactGeoms[i];
>
> IntPtr joint =
> Ode.dJointCreateContact(world,contactgroup,ref contact[i]);
> Ode.dJointAttach(joint,b1,b2);
> }
> }
>
> Regards,
> Samira
>
> _________________________________________________________________
> Haben Spinnen Ohren? Finden Sie es heraus – mit dem MSN Suche Superquiz via
> http://www.msn-superquiz.de Jetzt mitmachen und gewinnen!
>
> _______________________________________________
> ODE mailing list
> ODE at ode.org
> http://ode.org/mailman/listinfo/ode
>
>
>
More information about the ODE
mailing list