Skip to content

Commit

Permalink
UPBGE: Fix capsule shape issues.
Browse files Browse the repository at this point in the history
Two issues from bullet were noticed:
- The scaling of capsule failed
- An high margin wasn't handled properly for the cylinder
part.

These two issues were fixed by cleaning the way bullet manages
the cone dimensions. First the attribute m_implicitShapeDimensions
store the complete half height including the radius of the hemisphere
but without the margin.
In consideration a function getExtent is implemented to return the
height without the radius as the previous getHalfHeight.
Secondly setLocalScaling scale the whole height and radius including
margin and remove the margin after scale.

About margin, the margin isn't anymore removed from height or radius
in btConvexShape::localGetSupportVertexWithoutMarginNonVirtual and
btCapsuleShape::localGetSupportingVertexWithoutMargin.
  • Loading branch information
panzergame committed Aug 31, 2017
1 parent 525ca90 commit 0ba9897
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1303,10 +1303,10 @@ void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const
const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);

btScalar radius = capsuleShape->getRadius();
btScalar halfHeight = capsuleShape->getHalfHeight();
btScalar extend = capsuleShape->getExtend();

int upAxis = capsuleShape->getUpAxis();
getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
getDebugDrawer()->drawCapsule(radius, extend, upAxis, worldTransform, color);
break;
}
case CONE_SHAPE_PROXYTYPE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter
m_shapeType = CAPSULE_SHAPE_PROXYTYPE;
m_upAxis = 1;
m_implicitShapeDimensions.setValue(radius,0.5f*height,radius);
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions -= margin;
}


Expand Down Expand Up @@ -53,9 +55,9 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter

{
btVector3 pos(0,0,0);
pos[getUpAxis()] = getHalfHeight();
pos[getUpAxis()] = getExtend();

vtx = pos +vec*(radius) - vec * getMargin();
vtx = pos +vec*(radius);
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
Expand All @@ -65,9 +67,9 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter
}
{
btVector3 pos(0,0,0);
pos[getUpAxis()] = -getHalfHeight();
pos[getUpAxis()] = -getExtend();

vtx = pos +vec*(radius) - vec * getMargin();
vtx = pos +vec*(radius);
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
Expand Down Expand Up @@ -95,8 +97,8 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter
btScalar newDot;
{
btVector3 pos(0,0,0);
pos[getUpAxis()] = getHalfHeight();
vtx = pos +vec*(radius) - vec * getMargin();
pos[getUpAxis()] = getExtend();
vtx = pos +vec*(radius);
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
Expand All @@ -106,8 +108,8 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter
}
{
btVector3 pos(0,0,0);
pos[getUpAxis()] = -getHalfHeight();
vtx = pos +vec*(radius) - vec * getMargin();
pos[getUpAxis()] = -getExtend();
vtx = pos +vec*(radius);
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
Expand All @@ -131,9 +133,9 @@ void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) con
btScalar radius = getRadius();

btVector3 halfExtents(radius,radius,radius);
halfExtents[getUpAxis()]+=getHalfHeight();
halfExtents[getUpAxis()]+=getExtend();

btScalar margin = CONVEX_DISTANCE_MARGIN;
btScalar margin = getMargin();

btScalar lx=btScalar(2.)*(halfExtents[0]+margin);
btScalar ly=btScalar(2.)*(halfExtents[1]+margin);
Expand All @@ -153,6 +155,8 @@ btCapsuleShapeX::btCapsuleShapeX(btScalar radius,btScalar height)
{
m_upAxis = 0;
m_implicitShapeDimensions.setValue(0.5f*height, radius,radius);
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions -= margin;
}


Expand All @@ -164,6 +168,8 @@ btCapsuleShapeZ::btCapsuleShapeZ(btScalar radius,btScalar height)
{
m_upAxis = 2;
m_implicitShapeDimensions.setValue(radius,radius,0.5f*height);
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions -= margin;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,12 @@ ATTRIBUTE_ALIGNED16(class) btCapsuleShape : public btConvexInternalShape
btConvexInternalShape::setMargin(collisionMargin);
btVector3 newMargin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;

}

virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
{
btVector3 halfExtents(getRadius(),getRadius(),getRadius());
halfExtents[m_upAxis] = getRadius() + getHalfHeight();
halfExtents[m_upAxis] += getExtend();
halfExtents += btVector3(getMargin(),getMargin(),getMargin());
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
Expand Down Expand Up @@ -92,16 +91,27 @@ ATTRIBUTE_ALIGNED16(class) btCapsuleShape : public btConvexInternalShape
return m_implicitShapeDimensions[m_upAxis];
}

btScalar getExtend() const
{
return getHalfHeight() - getRadius();
}

virtual void setLocalScaling(const btVector3& scaling)
{
btVector3 oldMargin(getMargin(),getMargin(),getMargin());
btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
const unsigned short r1 = (m_upAxis + 1) % 3;
const unsigned short r2 = (m_upAxis + 2) % 3;

btConvexInternalShape::setLocalScaling(scaling);
const float margin = getMargin();
const float halfHeight = m_implicitShapeDimensions[m_upAxis];
float radius = m_implicitShapeDimensions[r2];
float radiusWithMargin = radius + margin;
const float halfHeightWithMargin = halfHeight + margin;

m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
const btVector3 scaleRatio = scaling / m_localScaling;
m_implicitShapeDimensions[r2] = radiusWithMargin * (scaleRatio[r1] + scaleRatio[r2]) / 2.0f - margin;

m_implicitShapeDimensions[m_upAxis] = halfHeightWithMargin * scaleRatio[m_upAxis] - margin;
btConvexInternalShape::setLocalScaling(scaling);
}

virtual btVector3 getAnisotropicRollingFrictionDirection() const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,4 @@ void btConeShape::setLocalScaling(const btVector3& scaling)
m_radius *= (scaling[r1] / m_localScaling[r1] + scaling[r2] / m_localScaling[r2]) / 2;
m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height));
btConvexInternalShape::setLocalScaling(scaling);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btV
btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());

btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
btScalar halfHeight = capsuleShape->getHalfHeight();
btScalar extend = capsuleShape->getExtend();
int capsuleUpAxis = capsuleShape->getUpAxis();

btScalar radius = capsuleShape->getRadius();
Expand All @@ -249,10 +249,9 @@ btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btV
btScalar newDot;
{
btVector3 pos(0,0,0);
pos[capsuleUpAxis] = halfHeight;
pos[capsuleUpAxis] = extend;

//vtx = pos +vec*(radius);
vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV();
vtx = pos +vec*(radius);
newDot = vec.dot(vtx);


Expand All @@ -264,10 +263,9 @@ btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btV
}
{
btVector3 pos(0,0,0);
pos[capsuleUpAxis] = -halfHeight;
pos[capsuleUpAxis] = -extend;

//vtx = pos +vec*(radius);
vtx = pos +vec*(radius) - vec * capsuleShape->getMarginNV();
vtx = pos +vec*(radius);
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
Expand Down Expand Up @@ -426,7 +424,7 @@ void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin,
btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius());
int m_upAxis = capsuleShape->getUpAxis();
halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight();
halfExtents[m_upAxis] += capsuleShape->getExtend();
halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2897,7 +2897,7 @@ void CcdPhysicsEnvironment::ConvertObject(BL_BlenderSceneConverter& converter, K
case OB_BOUND_CAPSULE:
{
shapeInfo->m_radius = MT_max(bounds_extends[0], bounds_extends[1]);
shapeInfo->m_height = 2.0f * (bounds_extends[2] - shapeInfo->m_radius);
shapeInfo->m_height = 2.0f * bounds_extends[2];
if (shapeInfo->m_height < 0.0f)
shapeInfo->m_height = 0.0f;
shapeInfo->m_shapeType = PHY_SHAPE_CAPSULE;
Expand Down

0 comments on commit 0ba9897

Please sign in to comment.