Jump to content

  • Log In with Google      Sign In   
  • Create Account

We need your feedback on a survey! Each completed response supports our community and gives you a chance to win a $25 Amazon gift card!

Dirk Gregorius

Member Since 24 Apr 2002
Offline Last Active Dec 22 2014 02:40 PM

#5199140 Polymorphic pairwise collision testing implementation

Posted by Dirk Gregorius on 19 December 2014 - 01:18 PM

I simply use an array of function pointers. Essentially something along these lines:

static void rnCollide( rnManifold& Manifold, const rnTransform& Transform1, const rnShape* Shape1, const rnTransform& Transform2, const rnShape* Shape2, rnContactCache& Cache )
	typedef void (*rnCollideFunc)( rnManifold&, const rnTransform&, const rnShape*, const rnTransform&, const rnShape* );
	static const rnCollideFunc CollisionMatrix[ RN_SHAPE_COUNT ][ RN_SHAPE_COUNT ] =
			{ rnCollideSpheres, rnCollideSphereCapsule,  rnCollideSphereHull,	NULL },
			{ NULL,             rnCollideCapsules,       rnCollideCapsuleHull,	NULL },
			{ NULL,             NULL,                    rnCollideHulls,		NULL },
			{ NULL,		    NULL,		     NULL,			NULL }

	RN_ASSERT( Shape1->GetType() <= Shape2->GetType() );
	rnCollideFunc Collide = CollisionMatrix[ Shape1->GetType() ][ Shape2->GetType() ];
	Collide( Manifold, Transform1, Shape1, Transform2, Shape2, Cache );

If you cannot guarantee the ordering (I do this when creating a contact) you must handle the lower collision matrix as well. Most often this simply involves reversing the normal direction. 


In general this a simple problem and I recommend using a simple solution for this problem. Until you don't add dispatchers dynamically I would go with this solution or use your switch-case approach which is totally fine. There is a lot of value to keep things simple and readable.

#5188352 Good books on mathematics

Posted by Dirk Gregorius on 21 October 2014 - 12:09 PM

I really like these:









#5182977 SAT response

Posted by Dirk Gregorius on 25 September 2014 - 02:50 PM

After the SAT you have a feature (either edges or face) which defines the axis of minimum penetration. 


If this feature is a face:

- The face defines the so called reference face

- Find the incident face on the other shape 

- This face defines the incident face

- Clip the incident face against the side planes of the reference face

- Keep all point below the reference face

- The distance of the clipped vertices to the reference face is your penetration


If the witness features are edge

- Compute the closest point between the edges

- The contact point is the average of the two points

- The penetration is the distance between the two witness points


I recommend to look into a bunch of example. E.g. in the ODE there is a function dBoxBox which shows how to build contacts for two OBBs. In Box2D you can find examples for building contacts between convex hull. In 3D you need to add the edge case.


Erin gave a bunch of presentation and one deals with contact creation. Have a look here: www.box2d.org  

I think Erwin gave a presentation on contact creation as well. Look at the Bullet website




#5182690 collision with frictions dealt using tangent impulses

Posted by Dirk Gregorius on 24 September 2014 - 11:33 AM

Probably a typo. The tangent impulses must be equal and opposite as well.

#5182504 Capsule Moment Of Inertia

Posted by Dirk Gregorius on 23 September 2014 - 03:33 PM

I agree with Eric. You find a bunch of scary solutions out there. So I quickly wrote my derivation up for you (if you don't have Eric's book handy) and also summarized some common gotchas to watch out for when using the parallel axis theorem. It is very short and on the point, but hopefully this helps:



#5179914 Capsule Moment Of Inertia

Posted by Dirk Gregorius on 12 September 2014 - 10:55 AM

Look at the Parallel Axis Theorem. E.g. here: http://en.wikipedia.org/wiki/Parallel_axis_theorem

#5161516 Explosive tangent impulses causes extreme rotation

Posted by Dirk Gregorius on 19 June 2014 - 10:30 AM

I recommend starting from Box2D *Lite*. Then you can start playing around from a working solution. Regarding the changes you made to Box2D I wonder what problem you try to solve and where you think your solution is better. I personally would only make such changes if it solves a particular problem while not breaking anything else.

#5160144 Spline Ik and Fullbody Ik

Posted by Dirk Gregorius on 12 June 2014 - 03:52 PM

I am looking for some references on Spline Ik and Fullbody Ik. I found tons of good material on basic Ik solvers like Jacobian methods, CCD, analytical and particle methods, but I failed to find anything about these two topics. I must assume I lost my Google Fu :)


For Spline Ik my understanding is that your are given a bunch of joint pivots and find a curve through all these points. Then while moving the spline control points you reconstruct the bone chain. There are some tricky details for the twist.


Fullbody Ik seems to combine different kinds of Ik solvers (e.g. spline solver for the spine, and maybe analytical methods for arms, etc) and then solve those in some hierarchical way with constraints between the Ik handles.


Any information is welcome! Thanks!

#5155675 Sequential Impulse Solver and Sliding Contacts

Posted by Dirk Gregorius on 24 May 2014 - 10:50 AM

There are two things with position solvers. 


1) Friction and motors are usually modeled as velocity constraints. It is tricky to do this on the position level

2) If you solve on the position level you need to solve a non-linear system. Solving on the velocity level is a linear problem. Also constraint equations and Jacobians are functions of the positions and orientations. So you need to re-evaluate them while you iterate over them. This is *pretty* costly. On the velocity level they remain constant and can be pre-computed. For particle systems it is a great choice though. Check all the Position-Based-Dynamics (PBD) work by Mueller and the original presentation by Jacobsen using Verlet integration.


If you really want to understand what is going on, here are a couple of links:






Everything from Erin Catto here:



These are good as well:




Finally you can read also everything from David Baraff and Brian Mirtich. Just google for those names


If you want to write your own physics engine I recommend starting from Box2D Lite and then port it slowly over to 3D. Once you have the basic understanding you can improve broadphase, collision detection, contact persistence, etc. based on you personal preferences. You can use the real Box2D as guidance then


Edit: Here are links to the Mueller and Jacobsen papers




For a formal background look into technical mechanics books or online lectures.


Happy studying! :)

#5155466 Sequential Impulse Solver and Sliding Contacts

Posted by Dirk Gregorius on 23 May 2014 - 09:41 AM

Yes! You first solve the velocities. The projection steo give you the 'best' velocities to advance to the positions. Then you correct positions. I would not re-run the collision detection though, but keep contact points local and measure the penetration along the normal. 


Again, I recommend having look at Box2D and Box2D Lite.

#5155141 Sequential Impulse Solver and Sliding Contacts

Posted by Dirk Gregorius on 21 May 2014 - 05:19 PM

First I would make sure that your tangent doesn't go to zero when the relative velocity vanishes. What is the impulseMag? Is this the incremental or the accumulated impulse? You need to clamp against the accumulated impulse.


I would clamp the friction impulse like this (assuming impulseMag > 0) :

frictionImpulse = clamp( frictionImpulse, -curContact->friction * impulseMag, curContact->friction * impulseMag );

#5143727 Support Vector

Posted by Dirk Gregorius on 01 April 2014 - 10:26 AM

The support point is the furthest (extreme) point in a given direction:

int Support( const std::vector< vector2 >& vertices, const vector2& vDirection )
  float flBestDistance = -FLT_MAX;
  int nBestVertex = -1;

  for ( int nVertex = 0; nVertex < nVertexCount; ++nVertex )
    float flDistance = DotProduct( vertices[ nVertex ], vDirection );
    if ( flDistance > flBestDistance )
      flBestDistance = flDistance;
      nBestVertex = nVertex;

  return nBestVertex;

#5128780 Unity-like transform component

Posted by Dirk Gregorius on 04 February 2014 - 12:37 PM

I like how joints in Maya handle scale. Essentially the scale doesn't propagate down to the children. I recently needed to work with Maya and while their SDK is definitely ugly, you will find a lot of interesting things.


Here are some references:




#5128638 Unity-like transform component

Posted by Dirk Gregorius on 03 February 2014 - 11:37 PM

I wonder how Unity does this. If they support non-uniform scaling they cannot decompose necessarily only into TRS. They might be also a shear component like in Maya.

#5126846 Naming conventions for math statements

Posted by Dirk Gregorius on 27 January 2014 - 07:04 PM

I like to distinguish between game code and low level code. In game code I also use longer names like e.g. a descriptive player_position over just 'p'. For my low level collision or physics routines I prefer short names as I derived them on paper. I usually check in theses paper with the code and add a reference in the code. Then those can be used for debugging. E.g. a function to compute the intersection between a ray and a triangle would look like this:


float IntersectRayTriangle( Vector A, Vector B, Vector C, Vector P, Vector Q ). 


If you need functions that take a triangle or ray structure you just overload the function and delegate to the leaf code function. Personally I found this very convenient to work, but YMMV.


As the point came up here I personally recommend against using a special point class. I have to use this lately a lot inside the Maya SDK and find this more confusing than helpful. E.g. you get the translation from a transformation matrix as vector and pass this as position (a point) for e.g. a manipulator you have to convert between types for this. Also the overloading of a multiplication operator between vectors and points which ignores the translation in the first place is very error prone. In this case I prefer explicit functions of the form TransformVector( Matrix m, Vector v ) and TransformPoint( Matrix m, Vector p ). This is my personal preference and it worked well for me, but again YMMV.


In general I find most most libraries that are available as open source these days way over-engineered for such a simple problem like a math library. E.g. using templates and extra point classes and what not else.