<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://ode.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Simple_Bouncing_Sphere</id>
	<title>Simple Bouncing Sphere - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://ode.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Simple_Bouncing_Sphere"/>
	<link rel="alternate" type="text/html" href="https://ode.org/wiki/index.php?title=Simple_Bouncing_Sphere&amp;action=history"/>
	<updated>2026-04-08T20:37:55Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://ode.org/wiki/index.php?title=Simple_Bouncing_Sphere&amp;diff=102&amp;oldid=prev</id>
		<title>imported&gt;Richb3: /* Sample Code */</title>
		<link rel="alternate" type="text/html" href="https://ode.org/wiki/index.php?title=Simple_Bouncing_Sphere&amp;diff=102&amp;oldid=prev"/>
		<updated>2019-03-21T19:35:19Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Sample Code&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 12:35, 21 March 2019&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l48&quot;&gt;Line 48:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 48:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  static void start()&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  static void start()&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;static &lt;/del&gt;float xyz[3] = {2.0f,-2.0f,1.7600f};&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     float xyz[3] = {2.0f,-2.0f,1.7600f};&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;static &lt;/del&gt;float hpr[3] = {140.000f,-17.0000f,0.0000f};&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     float hpr[3] = {140.000f,-17.0000f,0.0000f};&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     dsSetViewpoint (xyz,hpr);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     dsSetViewpoint (xyz,hpr);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>imported&gt;Richb3</name></author>
	</entry>
	<entry>
		<id>https://ode.org/wiki/index.php?title=Simple_Bouncing_Sphere&amp;diff=101&amp;oldid=prev</id>
		<title>imported&gt;Russ: Created page with &quot;== Introduction ==  This article describes how to make a sphere that falls onto a plane and bounces. This is about as simple as it gets, but it shows the general structure of...&quot;</title>
		<link rel="alternate" type="text/html" href="https://ode.org/wiki/index.php?title=Simple_Bouncing_Sphere&amp;diff=101&amp;oldid=prev"/>
		<updated>2019-01-07T04:36:41Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;== Introduction ==  This article describes how to make a sphere that falls onto a plane and bounces. This is about as simple as it gets, but it shows the general structure of...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This article describes how to make a sphere that falls onto a plane and bounces. This is about as simple as it gets, but it shows the general structure of a dynamic simulation using ODE.&lt;br /&gt;
&lt;br /&gt;
== Sample Code ==&lt;br /&gt;
&lt;br /&gt;
This code is written in the style of the ODE demos, and uses drawstuff to show the simulation.&lt;br /&gt;
&lt;br /&gt;
First the objects for the simulation must be declared. You must have a world, a space to put everything in, a body with associated geometry and mass, and a joint group to store the contact joints that are created during a collision.&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;ode/ode.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;drawstuff/drawstuff.h&amp;gt;&lt;br /&gt;
 // dynamics and collision objects&lt;br /&gt;
 static dWorldID world;&lt;br /&gt;
 static dSpaceID space;&lt;br /&gt;
 static dBodyID body;	&lt;br /&gt;
 static dGeomID geom;	&lt;br /&gt;
 static dMass m;&lt;br /&gt;
 static dJointGroupID contactgroup;&lt;br /&gt;
&lt;br /&gt;
When the collision system detects that two objects are colliding, it calls this routine which determines the points of contact and creates temporary joints. The surface parameters of the joint (friction, bounce velocity, CFM, etc) are also set here.&lt;br /&gt;
&lt;br /&gt;
 // this is called by dSpaceCollide when two objects in space are&lt;br /&gt;
 // potentially colliding.&lt;br /&gt;
 static void nearCallback (void *data, dGeomID o1, dGeomID o2)&lt;br /&gt;
 {&lt;br /&gt;
    dBodyID b1 = dGeomGetBody(o1);&lt;br /&gt;
    dBodyID b2 = dGeomGetBody(o2);&lt;br /&gt;
    dContact contact;  &lt;br /&gt;
    contact.surface.mode = dContactBounce | dContactSoftCFM;&lt;br /&gt;
    // friction parameter&lt;br /&gt;
    contact.surface.mu = dInfinity;&lt;br /&gt;
    // bounce is the amount of &amp;quot;bouncyness&amp;quot;.&lt;br /&gt;
    contact.surface.bounce = 0.9;&lt;br /&gt;
    // bounce_vel is the minimum incoming velocity to cause a bounce&lt;br /&gt;
    contact.surface.bounce_vel = 0.1;&lt;br /&gt;
    // constraint force mixing parameter&lt;br /&gt;
    contact.surface.soft_cfm = 0.001;  &lt;br /&gt;
    if (int numc = dCollide (o1,o2,1,&amp;amp;contact.geom,sizeof(dContact))) {&lt;br /&gt;
        dJointID c = dJointCreateContact (world,contactgroup,&amp;amp;contact);&lt;br /&gt;
        dJointAttach (c,b1,b2);&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is called at the start of the simulation to set up the point of view of the camera.&lt;br /&gt;
&lt;br /&gt;
 // start simulation - set viewpoint&lt;br /&gt;
 static void start()&lt;br /&gt;
 {&lt;br /&gt;
    static float xyz[3] = {2.0f,-2.0f,1.7600f};&lt;br /&gt;
    static float hpr[3] = {140.000f,-17.0000f,0.0000f};&lt;br /&gt;
    dsSetViewpoint (xyz,hpr);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This is the main simulation loop that calls the collision detection function, steps the simulation, resets the temporary contact joint group, and redraws the objects at their new position.&lt;br /&gt;
&lt;br /&gt;
 // simulation loop&lt;br /&gt;
 static void simLoop (int pause)&lt;br /&gt;
 {&lt;br /&gt;
    const dReal *pos;&lt;br /&gt;
    const dReal *R;&lt;br /&gt;
    // find collisions and add contact joints&lt;br /&gt;
    dSpaceCollide (space,0,&amp;amp;nearCallback);&lt;br /&gt;
    // step the simulation&lt;br /&gt;
    dWorldQuickStep (world,0.01);  &lt;br /&gt;
    // remove all contact joints&lt;br /&gt;
    dJointGroupEmpty (contactgroup);&lt;br /&gt;
    // redraw sphere at new location&lt;br /&gt;
    pos = dGeomGetPosition (geom);&lt;br /&gt;
    R = dGeomGetRotation (geom);&lt;br /&gt;
    dsDrawSphere (pos,R,dGeomSphereGetRadius (geom));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the program starts, the callbacks are set up, everything is initialized, and then the simulation is started.&lt;br /&gt;
&lt;br /&gt;
 int main (int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
    // setup pointers to drawstuff callback functions&lt;br /&gt;
    dsFunctions fn;&lt;br /&gt;
    fn.version = DS_VERSION;&lt;br /&gt;
    fn.start = &amp;amp;start;&lt;br /&gt;
    fn.step = &amp;amp;simLoop;&lt;br /&gt;
    fn.stop = 0;&lt;br /&gt;
    fn.command = 0;&lt;br /&gt;
    fn.path_to_textures = &amp;quot;../../drawstuff/textures&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
    dInitODE ();&lt;br /&gt;
    // create world&lt;br /&gt;
    world = dWorldCreate ();&lt;br /&gt;
    space = dHashSpaceCreate (0);&lt;br /&gt;
    dWorldSetGravity (world,0,0,-0.2);&lt;br /&gt;
    dWorldSetCFM (world,1e-5);&lt;br /&gt;
    dCreatePlane (space,0,0,1,0);&lt;br /&gt;
    contactgroup = dJointGroupCreate (0);&lt;br /&gt;
    // create object&lt;br /&gt;
    body = dBodyCreate (world);&lt;br /&gt;
    geom = dCreateSphere (space,0.5);&lt;br /&gt;
    dMassSetSphere (&amp;amp;m,1,0.5);&lt;br /&gt;
    dBodySetMass (body,&amp;amp;m);&lt;br /&gt;
    dGeomSetBody (geom,body);&lt;br /&gt;
    // set initial position&lt;br /&gt;
    dBodySetPosition (body,0,0,3);&lt;br /&gt;
    // run simulation&lt;br /&gt;
    dsSimulationLoop (argc,argv,352,288,&amp;amp;fn);&lt;br /&gt;
    // clean up&lt;br /&gt;
    dJointGroupDestroy (contactgroup);&lt;br /&gt;
    dSpaceDestroy (space);&lt;br /&gt;
    dWorldDestroy (world);&lt;br /&gt;
    dCloseODE();&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>imported&gt;Russ</name></author>
	</entry>
</feed>