GJK and rotations

Started by
6 comments, last by dorcsyful 1 year, 8 months ago

So I have pretty much everything implemented for a good collision detection system. There is only one thing, I do not understand: what about when the objects are rotating. I have gone through several articles and github repositories, however I could not find anything related to this. How do I handle rotated objects? Do I multiply the direction vector before passing it to the support function? Or do I rotate the result? Or not rotate at all?

I am so confused. Any help is appreciated.

Advertisement

dorcsyful said:
Do I multiply the direction vector before passing it to the support function?

Yes.

Like this?

A = a_Object1->GetCollisionShape()->Support(a_Object1->GetTransform().getBasis() * direction) + a_Object1->GetTransform().getOrigin();
B = a_Object2->GetCollisionShape()->Support(a_Object2->GetTransform().getBasis() * (direction * -1)) + a_Object2->GetTransform().getOrigin();
support = A - B;

@dorcsyful
It looks like you rotate in the wrong direction (i.e. from local to world rather than world to local). The right way is to rotate by inverse rotation into local space, compute support points, then apply a regular local to world transform.

/// Return a minkowski vertex for the support point on each of the two specified shapes in the given direction.
MinkowskiVertex getSupportPoint( const ShapeTransform1* shape1, const ShapeTransform2* shape2, const SIMDFloat4& direction )
{
	// Transform the support direction into the local space of each shape.
	const SIMDFloat4 localDirection1 = math::normalize( shape1->transform.rotateToLocal( direction ) );
	const SIMDFloat4 localDirection2 = math::normalize( shape2->transform.rotateToLocal( -direction ) );
	
	// Get the support point on each shape.
	const SIMDFloat4 localPoint1 = getSupportPoint1( shape1->shape, localDirection1 );
	const SIMDFloat4 localPoint2 = getSupportPoint2( shape2->shape, localDirection2 );
	
	// Transform the local points on each shape into world space and return the minkowski vertex.
	return MinkowskiVertex( shape1->transform.transformToWorld( localPoint1 ), shape2->transform.transformToWorld( localPoint2 ) );
}

So then this is the correct one I guess?

direction.Normalize();
CVector3 local = CVector3::Normalize(a_Object1->GetTransform().getBasis().GetInverse() * direction);
A = a_Object1->GetTransform().getBasis() * a_Object1->GetCollisionShape()->Support(local) + a_Object1->GetTransform().getOrigin();
CVector3 local = CVector3::Normalize(a_Object2->GetTransform().getBasis().GetInverse() * (direction * -1));
B = a_Object2->GetTransform().getBasis() * a_Object2->GetCollisionShape()->Support(local) + a_Object2->GetTransform().getOrigin();
support = A - B;

On another note, since these are rotation matrices, I can work with their transpose as opposed to normally calculating the inverse?

dorcsyful said:
since these are rotation matrices, I can work with their transpose as opposed to normally calculating the inverse?

Yes if they are orthonormal matrices.

Thank you!

This topic is closed to new replies.

Advertisement