setLocalScaling for Cylinders for non-uniform scaling

metaganic
Posts: 1
Joined: Mon Dec 07, 2009 5:01 pm

setLocalScaling for Cylinders for non-uniform scaling

Post by metaganic »

I'm very new to Bullet and just finishing up a proof-of-concept demo using a few of the basic built-in prmitives. Our issue was we needed to support user-scaling of the objects, and specifically for Cylinders. (Cones would be nice, but we can do without.)

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;

}
2) Although this updates the halfExtents dimension settings, they aren't used individually in the internal Cylinder collision calcs, so we also modified the CylinderLocalSupportY. I was aiming for "minimum" changes here rather than "good"... The four commented out lines are the original code, and the additional lines are (possible) changes to compensate for the local scaling. (If you need X and Z cylinders, the same changes would be applied to the respective internal functions.)

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;
}
3) Finally, we also had to modify the base class btConvexShape::localGetSupportVertexWithoutMarginNonVirtual(...) function, since it's non-virtual, and also appears to be the narrow-phase collision calculation? The exact same changes as in (2) above were added to the Cylinder case section, so no need to repeat.

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.)
livio
Posts: 1
Joined: Sun Jun 13, 2010 8:20 am

Re: setLocalScaling for Cylinders for non-uniform scaling

Post by livio »

I have succesfully applied modifications to Bullet-2.76,
and now cylinders are scalable and working 100% OK

I hope that this will be included in the future Bullet versions.

bye
Livio
arabesc
Posts: 1
Joined: Mon Jan 31, 2011 12:25 am

Re: setLocalScaling for Cylinders for non-uniform scaling

Post by arabesc »

It's sad that this feature still not included to the engine. The nonuniform scaling of some primitives is an important thing.
And there is something wrong with scaling and collision margins... when the dimension of the object becomes less than the defined margin.