The following is the SDK changes made to support this, but mostly asking the experts if this is going to create problems down the road. We do need to add jointing and constraint support, and don't want to break future code just for a concept demo.
1) The first item we ran into was that the docs show btCylinderShape as being inherited from btBoxShape, but in fact it inherits from btConvexInternalShape. This means that the implementation of setLocalScaling() is the generic version, which only sets the m_localScaling variable, but does no calcs or changes to the m_implicitShapeDimensions values.
The first step then was to add a setLocalScaling(...) function to the Cylinder class, for which we just used a direct copy/paste of the code from the btBoxShape.
Code: Select all
virtual void setLocalScaling(const btVector3& scaling)
{
btVector3 oldMargin(getMargin(),getMargin(),getMargin());
btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
btConvexInternalShape::setLocalScaling(scaling);
m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
}
Code: Select all
inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v)
{
const int cylinderUpAxis = 1;
const int XX = 0;
const int YY = 1;
const int ZZ = 2;
//btScalar radius = halfExtents[XX];
//btScalar halfHeight = halfExtents[cylinderUpAxis];
btScalar radius = 1.0;
btScalar halfHeight = 1;
btVector3 tmp;
btScalar d ;
btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
if (s != btScalar(0.0))
{
d = radius / s;
tmp[XX] = v[XX] * d;
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
tmp[ZZ] = v[ZZ] * d;
//return tmp;
}
else
{
tmp[XX] = radius;
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
tmp[ZZ] = btScalar(0.0);
//return tmp;
}
tmp[XX] *= halfExtents[XX];
tmp[YY] *= halfExtents[YY];
tmp[ZZ] *= halfExtents[ZZ];
return tmp;
}
This did work for our limited use, but I am far from knowledeable enough about Bullet to suggest it is the proper approach. Would even be very surprised if it was, and am worried about what possible side effects this could cause for constraints and such? One known side-effect is that the cylinders really get to "rocking"! So some additional inertia handling is definately needed, but I'm more concerned about implications for constraint handling.
It does remain a fact that non-uniform scaling for cylinders (and cones,) is not supported in the current release, although it does appear to be an oversight more than anything.
(this is using 2.75-1776 as the source. Also is perhaps relevent to the http://code.google.com/p/bullet/issues/detail?id=178 report.)