<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mobile Perspectives &#187; Collision Handling</title>
	<atom:link href="http://www.BluMtnWerx.com/blog/tag/collision-handling/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.BluMtnWerx.com/blog</link>
	<description>Computing at the Edge!</description>
	<lastBuildDate>Fri, 19 Aug 2011 00:29:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Oolong/Bullet Collision Detection</title>
		<link>http://www.BluMtnWerx.com/blog/2009/04/oolongbullet-collision-detection/</link>
		<comments>http://www.BluMtnWerx.com/blog/2009/04/oolongbullet-collision-detection/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 04:03:19 +0000</pubDate>
		<dc:creator>paul</dc:creator>
				<category><![CDATA[Resources]]></category>
		<category><![CDATA[Bullet]]></category>
		<category><![CDATA[Collision Handling]]></category>
		<category><![CDATA[Oolong]]></category>

		<guid isPermaLink="false">http://www.BluMtnWerx.com/blog/?p=80</guid>
		<description><![CDATA[Collision handling in Oolong/Bullet was not obvious.  Here is a rundown on what I learned along with some sample code from my solution.]]></description>
			<content:encoded><![CDATA[<p>One of the things that I found incredibly attractive about Oolong and the Bullet physics package (which is embedded in Oolong) was that one could get a fantastic simulation of objects bouncing around and interacting with each other and fixed objects with very little code.  The &quot;Falling Boxes&quot; example in Oolong is really cool, even though the code is simple.  However, it&#8217;s pretty important to be able to &quot;react&quot; to these collisions, and it took me a bit to figure out the best way to accomplish that.</p>
<p>What I was hoping for was a way to register a call-back with a rigid body such that my function or method would get called whenever the body collided with something.  Further, after working with the ray testing functionality, I was hoping for the same kind of filtering capabilities that the ray testing interface provides. Unfortunately, that functionality doesn&#8217;t quite exist, so you have to &quot;roll your own&quot; from what is provided.</p>
<p>The best reference on collision detection in Bullet is, I believe, <a title="Link to bullet collision detection documentation." href="http://www.bulletphysics.com/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers" target="_blank" title="Link to bullet collision detection documentation.">this one</a> .  After reading through this carefully and considering the options, I decided to use the first strategy, which is to simply loop through the manifolds at the end of each simulation cycle.  I quickly discovered that there were several issues I needed to deal with:</p>
<ul>
<li>A manifold will appear in the list and contain objects when there are no points of collision (getNumContacts() == 0) between the objects.  This surprised me!  Therefore, even though I didn&#8217;t care about the actual points of contact in my application, I needed to check the number of points and only register a collision if there were one or more.</li>
<li>Objects may remain in contact for a number of cycles.  The behavior I wanted was to be notified when objects came into contact and again when they separated.  In order to achieve this, I had to implement some state in my objects that indicated what other objects they were in contact with.  I used STL sets for this purpose, as shown below&#8230;  <em>(4/24/2009 &#8212; I have noticed that the B-Tree implementation underlying the STL set is showing up in profiling with lots of calls for allocation.  While this is not hurting the performance of my app yet, I expect that it will at some point.  I will probably end up optimizing the set implementation, probably through the use of a custom allocator.)</em></li>
</ul>
<p>Here is the code for the collision detection method, which is called after each simulation cycle:</p>
<pre>void BMWWorld::_detectCollisions() {
  // For information on collision detection using Bullet, see:
  // http://www.bulletphysics.com/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers
  //
  // Detect collisions and notify the objects involved.
  int numManifolds = this-&gt;numManifolds();
  BMWObjectSet *pNewNotifications = NULL;
  for (int i=0; i &lt; numManifolds; i++) {
    btPersistentManifold* contactManifold = this-&gt;contactManifold(i);
    int numContacts = contactManifold-&gt;getNumContacts();
    if (numContacts &gt; 0) {
      // We only notify the collision if there is a point of contact.  I suppose it's possible
      // to have really rapid, transient collisions that occurred during the simulation but
      // are still not in contact when the simulation step comes to an end.  I think our system
      // is slow enough that we can ignore these safely, but might want to keep an eye on this
      // as a future enhancement.
      // Call collision handlers for each object.
      btCollisionObject* obA = static_cast&lt;btCollisionObject*&gt;(contactManifold-&gt;getBody0());
      BMWObject* pObA = static_cast&lt;BMWObject*&gt;(obA-&gt;getUserPointer());
      btCollisionObject* obB = static_cast&lt;btCollisionObject*&gt;(contactManifold-&gt;getBody1());
      BMWObject* pObB = static_cast&lt;BMWObject*&gt;(obB-&gt;getUserPointer());
      pObA-&gt;_notifyCollision(pObB);
      pObB-&gt;_notifyCollision(pObA);
      if (pNewNotifications == NULL)
        pNewNotifications = new BMWObjectSet;
      pNewNotifications-&gt;insert(pObA);
      pNewNotifications-&gt;insert(pObB);
    }

    // The following code allows you to find out where the objects are in contact
    // with other.
//    	for (int j=0; j &lt; numContacts; j++) {
//    		btManifoldPoint&amp; pt = contactManifold-&gt;getContactPoint(j);
//
//    		btVector3 ptA = pt.getPositionWorldOnA();
//    		btVector3 ptB = pt.getPositionWorldOnB();
//    	}
//
//	// Clear all contact points out of the manifold cache
//    	contactManifold-&gt;clearManifold();
  }

  // All collisions reported.  Notify all objects in the previous notification set that we're done with
  // collision processing.  That way they can notify any handlers that collisions are complete.
  if (_pLastNotifySet != NULL) {
    BMWObjectSet::iterator itr;
    for (itr=_pLastNotifySet-&gt;begin(); itr != _pLastNotifySet-&gt;end(); itr++)
      (*itr)-&gt;_collisionDetectionComplete();
    delete _pLastNotifySet;
  }

  // Replace the notification set with the new notification set.
  _pLastNotifySet = pNewNotifications;
} // _detectCollisions()</pre>
<p>I then simply created a pure virtual collision handler interface and implemented it for objects for which I need to be notified about collisions.  Here it is:</p>
<pre>// Objects that need to handle collisions should derive from this and set
// the handler in the BMWObject.
class BMWCollision {
public:
  BMWCollision() {};
  virtual ~BMWCollision() {};

  // pObj is the object with which the collision has occurred.  This is called when
  // contact is first detected with the other object.
  virtual void handleCollision(BMWObject* pOther) = 0;

  // Called with the set of objects that we were in contact with that we're no longer
  // in contact with.  May be null or empty!
  virtual void collisionComplete(BMWObjectSet* pCollSet) = 0;
}; // class BMWCollision</pre>
<p>This interface is used by the objects when they determine that a collision has occurred or been completed, as shown here:</p>
<pre>void BMWObject::_notifyCollision(BMWObject* pObj) {
  if (_pCollHandler == NULL)
    return;

  // No collision processing if there is not a handler defined.
  // Do screening of collision notifications.  The handler is
  // only called if the &quot;other&quot; object is not in the LastCollSet.
  // The &quot;other&quot; object is always added to the NewCollSet.  When
  // all notifications are complete (the collisionDetectionComplete()
  // method is called), the objects that are in the LastCollSet but
  // not in the NewCollSet are sent to the handler.  This way the
  // handler can be appropriately called for both the detection of a
  // collision and also when the collision is complete.
  if (_pNewCollSet == NULL)
    _pNewCollSet = new BMWObjectSet;
  _pNewCollSet-&gt;insert(pObj);

  if ((_pLastCollSet == NULL) || (_pLastCollSet-&gt;count(pObj) == 0))
    _pCollHandler-&gt;handleCollision(pObj);
} // notifyCollision()

void BMWObject::_collisionDetectionComplete() {
  if (_pCollHandler == NULL)
    return;

  // Remove objects in the new collision set from the last collision set
  BMWObjectSet::iterator itr;
  if ((_pNewCollSet != NULL) &amp;&amp; (_pLastCollSet != NULL)) {
    for (itr=_pNewCollSet-&gt;begin(); itr != _pNewCollSet-&gt;end(); itr++)
        _pLastCollSet-&gt;erase(*itr);
  }

  // Notify collision handler about objects we're no longer colliding with
  // (those remaining in the last set.)
  _pCollHandler-&gt;collisionComplete(_pLastCollSet);

  // Delete the old set and swap in the new set.
  delete _pLastCollSet;
  _pLastCollSet = _pNewCollSet;
  _pNewCollSet = NULL;
} // collisionDetectionComplete()</pre>
<p>Again, if you see problems or improvements, please share with the rest of us!  This is definitely a learning process on my part!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.BluMtnWerx.com/blog/2009/04/oolongbullet-collision-detection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

