btGImpactMeshShape scaling bug ?

Post Reply
bmeijering
Posts: 3
Joined: Thu Mar 25, 2010 2:50 pm
Location: The Netherlands

btGImpactMeshShape scaling bug ?

Post by bmeijering »

Hi everyone,

I ran into a problem and was wondering if anyone could help me out.
My problem concerns the scaling of a btGImpactMeshShape.
The bullet version I am using is 2.73.

What I am doing is the following:

Code: Select all

btGImpactMeshShape *shape = getShape();  // created with scale 1.0, 1.0, 1.0
shape->setLocalScaling(getScale());   // scale = 2.0, 2.0, 2.0
shape->updateBound();
updateBound invokes calcLocalAABB which in turn invokes the updateBound functions of all it's btGImpactMeshShapePart instances.
The updateBound function of btGImpactMeshShapePart calls it's own calcLocalAABB function which in turn calls the update function of it's btGImpactQuantizedBvh instance.
The update function of btGImpactQuantizedBvh calls it's refit function.

The refit function updates the bounds of the nodes using the setNodeBound function of it's btQuantizedBvhTree instance.
The node bounds are quantized, but the problem is that the quantization bounds (m_global_bound) have not been updated, so all values are being clamped.

Can anyone tell me if this is a bug ? Or am I just using it incorrectly ?

Regards,

Ben Meijering
jhurliman
Posts: 5
Joined: Thu Mar 25, 2010 8:03 am

Re: btGImpactMeshShape scaling bug ?

Post by jhurliman »

I don't know if it's the same issue, but I've been having trouble getting the AABBs for btGImpactMeshShapes to update after calling setLocalScaling(). For example:

Code: Select all

btGImpactMeshShape* mesh = createMeshShape(); // created with scale 1.0, 1.0, 1.0
mesh->updateBound(); // works as expected, creates the AABB assuming a scale of <1,1,1>
mesh->setLocalScaling(scale); // scale = 2.0, 2.0, 2.0
mesh->updateBound(); // does nothing? still has the old AABB although the mesh is the correct new size
If I remove the first call to updateBound() it works as expected, but does this mean I need to recreate the mesh shape whenever I want to change the scale?
bmeijering
Posts: 3
Joined: Thu Mar 25, 2010 2:50 pm
Location: The Netherlands

Re: btGImpactMeshShape scaling bug ?

Post by bmeijering »

That's the same problem, I fixed the problem by adding the following functions:

Code: Select all

SIMD_FORCE_INLINE void setQuantizationBounds(const btAABB &a_Bounds, btScalar a_BoundMargin = btScalar(1.0))
{
	bt_calc_quantization_parameters(
		m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization,a_Bounds.m_min,a_Bounds.m_max, a_BoundMargin);
}
to btQuantizedBvhTree.

Code: Select all

SIMD_FORCE_INLINE void updateAfterScaling(const btVector3& a_RelativeScaling)
{
	btAABB aabb = getGlobalBox();
	aabb.m_min *= a_RelativeScaling;
	aabb.m_max *= a_RelativeScaling;
	m_box_tree.setQuantizationBounds(aabb);
	refit();
}
to btGImpactQuantizedBvh

Code: Select all

virtual void calcLocalAABBAfterScaling()
{
	lockChildShapes();
	if(m_box_set.getNodeCount() == 0)
	{
		m_box_set.buildSet();
	}
	else
	{
		btVector3 localScaling = getLocalScaling();
		btVector3 relativeScaling = localScaling / m_BoxSetScaling;
		m_box_set.updateAfterScaling(relativeScaling);
	}
	unlockChildShapes();

	m_BoxSetScaling = getLocalScaling();
	m_localAABB = m_box_set.getGlobalBox();
}

SIMD_FORCE_INLINE void updateBoundAfterScaling()
{
	if(!m_needs_update) return;
	calcLocalAABBAfterScaling();
	m_needs_update  = false;
}
to btGImpactShapeInterface

Code: Select all

virtual void calcLocalAABBAfterScaling()
{
	m_localAABB.invalidate();
	int i = m_mesh_parts.size();
	while(i--)
	{
		m_mesh_parts[i]->updateBoundAfterScaling();
		m_localAABB.merge(m_mesh_parts[i]->getLocalBox());
	}
}
to btGImpactMeshShape

After invoking setLocalScaling you can just invoke updateBoundAfterScaling.
When you're just scaling the shape this could probably be done more efficiently, by adjusting the node bounds directly.
But I didn't have the time to look into that.

Hope this helps.

Regards,

Ben Meijering
User avatar
dotsquid
Posts: 22
Joined: Fri Jan 14, 2011 7:10 pm
Location: Ukraine
Contact:

Re: btGImpactMeshShape scaling bug ?

Post by dotsquid »

I have tried this workaround but no luck.
Before patching I have had a perfectly working btGImpactMeshShape. The problem occured only if I tried to scale it - the body became unstable, bouncing on the surface or falling through it.
After patching the body became zero sized (debug renderer shows no triangle normals which were seen before patching). Furthermore the application crashes with memory access violation message when the btGImpactMeshShape collides with another body.
At first I thought this is happening because of my custom collision dispatcher (for collision filtering). But when I switched to the native collision dispatcher the problem stayed.

Can anyone help? I'm using the latest revision of Bullet.
Whooom
Posts: 2
Joined: Wed May 27, 2015 4:20 pm

Re: btGImpactMeshShape scaling bug ?

Post by Whooom »

I recently encountered the same issue in bullet 2.83, and jhurliman's solution worked very well for me with a few tiny additions:

All this code goes in btGImpactShapeInterface

Declare the m_BoxSetScaling variable in the class member variables

Code: Select all

        btVector3  m_BoxSetScaling;
Initialize it to have unit scaling in the constructor:

Code: Select all

        btGImpactShapeInterface()
	{
		m_shapeType=GIMPACT_SHAPE_PROXYTYPE;
		m_localAABB.invalidate();
		m_needs_update = true;
		localScaling.setValue(1.f,1.f,1.f);

                //new code here
		m_BoxSetScaling.setValue(1, 1, 1);
	}
Post Reply