[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