activate object after size changes...

Post Reply
LastBlow
Posts: 14
Joined: Mon Jul 11, 2016 10:36 am
Location: SAN DIEGO

activate object after size changes...

Post by LastBlow » Thu Jan 31, 2019 4:12 pm

Hey, hey, hey, I change objects sizes and update their collision shapes, then call the method activateAllObjects() but the objects
remain hung in thin air, see pic and code here below...

The same method activateAllObjects() works fine elsewhere in the project. If I click on and off on the resized object, it remains
hung. rigidBody->activate(true) did not work either. The object starts falling down only if I pick it up and move it with the mouse.

So, please, how to activate resized objects, so they fall down by gravity once resized? :)))

hanging in thin air.jpg
Object hanging in thin air after resizing
hanging in thin air.jpg (140.53 KiB) Viewed 364 times

Code: Select all

switch (collisionShape->getShapeType()) {

		case BOX_SHAPE_PROXYTYPE:
			collisionShape->setLocalScaling(sizeObject);
			break;

		case SPHERE_SHAPE_PROXYTYPE:
			collisionShape->setLocalScaling(sizeObject);
			break;

		case CYLINDER_SHAPE_PROXYTYPE:
			collisionShape->setLocalScaling(sizeObject);
			break;

		case CONE_SHAPE_PROXYTYPE:
			collisionShape->setLocalScaling(sizeObject);
			break;

		case CONVEX_HULL_SHAPE_PROXYTYPE: {		// icosahedron, table, tree, flower, mushroom,...
			btConvexHullShape* convexHullShape = static_cast<btConvexHullShape*>(collisionShape);
			convexHullShape->setLocalScaling(sizeObject);
			convexHullShape->initializePolyhedralFeatures();
			break;
		}

		case GIMPACT_SHAPE_PROXYTYPE: {			// truck, bunny,...
			btGImpactMeshShape* impactMeshShape = static_cast<btGImpactMeshShape*>(collisionShape);
			impactMeshShape->updateBound();
			impactMeshShape->setLocalScaling(sizeObject);
			impactMeshShape->setMargin(0.04f);
			break;
		}

		default:
			logStderr("ERROR: Unrecognized collision shape...\n");
			break;
	}
	
	rigidBody->activate(true);
	m_dynamicsWorld->updateSingleAabb(rigidBody);

Code: Select all

void InceptionPhysics::activateAllObjects() {
	for (int i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) {
		btCollisionObject* collisionObject = m_dynamicsWorld->getCollisionObjectArray()[i];
		collisionObject->activate(true);
	}
}
Last edited by LastBlow on Sun Feb 03, 2019 8:55 am, edited 1 time in total.

User avatar
drleviathan
Posts: 486
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: activate object after size changes...

Post by drleviathan » Fri Feb 01, 2019 4:47 pm

Here is the relevant code from btCollisionWorld.cpp:

Code: Select all

void btCollisionObject::setActivationState(int newState) const
{ 
    if ( (m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION))
        m_activationState1 = newState;
}

void btCollisionObject::forceActivationState(int newState) const
{
    m_activationState1 = newState;
}

void btCollisionObject::activate(bool forceActivation) const
{
    if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT)))
    {
        setActivationState(ACTIVE_TAG);
        m_deactivationTime = btScalar(0.);
    }
}
The only way btCollisionObject::activate(true) can fail is if if m_activationState1 is either DISABLE_DEACTIVATION or DISABLE_SIMULATION. Are you setting m_activationState1 to either of those values?

LastBlow
Posts: 14
Joined: Mon Jul 11, 2016 10:36 am
Location: SAN DIEGO

Re: activate object after size changes...

Post by LastBlow » Sun Feb 03, 2019 8:42 am

Thank you very much for your reply!

No, I am not using DISABLE_DEACTIVATION or DISABLE_SIMULATION.

When resized, boxes, spheres, cylinders and cones behave normally by either working their way out of the terrain
if bigger (usually on top but falling through sometimes) or if smaller by falling on the terrain.

On the other hand, convex hulls and impact meshes tend to respond badly to size changes. Convex hulls update
their meshes and AABB boxes but remain hung in thin air. Impact meshes update their meshes but not their AABB
boxes making them sink in the terrain, given that impactMeshShape->updateBound(); seemingly has effect at
object creation but not at resizing.

Also, convexHullShape->recalcLocalAabb() method is public for a convex hull but private for an impact mesh and
can't be accessed directly. To finish, impactMeshShape->postUpdate() does not seem to be needed: the method
impactMeshShape->setMargin(0.05f) already sets the flag m_needs_update to true, needed for the method that
follows, namely impactMeshShape->updateBound().

The trees, including the resized tree, from the picture above are btConvexHullShape. I attach a second picture
with the Stanford bunny which is a btGImpactMeshShape.

Any further experience/examples of how to change sizes, please? ;-)))
Attachments
sinking bunny.jpg
Standford bunny sinking in terrain after resizing
sinking bunny.jpg (141.63 KiB) Viewed 263 times

LastBlow
Posts: 14
Joined: Mon Jul 11, 2016 10:36 am
Location: SAN DIEGO

Re: activate object after size changes...

Post by LastBlow » Sun Feb 03, 2019 5:29 pm

The mystery thickens, a short video to illustrate the size changes of an impact mesh shape...
which seems to scale AABB just fine down from the initial size but not up.

https://youtu.be/7kAmT3m1Ixc

LastBlow
Posts: 14
Joined: Mon Jul 11, 2016 10:36 am
Location: SAN DIEGO

Re: activate object after size changes...

Post by LastBlow » Mon Feb 04, 2019 6:39 pm

Alright, removing the rigid body and adding it back seems to solve the problem for btConvexHullShape
which does not get hung in thin air anymore! Thank you for the quick response, Erwin.

Curiously, no change thought for btGImpactMeshShape which would still resize their AABB down but not up...

Code: Select all

{...}

	float sizeX, sizeY, sizeZ;

	btVector3 distanceFigers = ((startPosition2 - startPosition1) / 2.0f).absolute();
	// logStderr("Distance fingers...\n"); printVector3(distanceFigers);

	(distanceFigers.x() < 1.0f) ? sizeX = 2.0f : sizeX = distanceFigers.x();
	(distanceFigers.y() < 1.0f) ? sizeY = 2.0f : sizeY = distanceFigers.y();
	(distanceFigers.z() < 1.0f) ? sizeZ = 2.0f : sizeZ = distanceFigers.z();

	btVector3 size = btVector3(sizeX, sizeY, sizeZ);
	logStderr("size object...\n"); printVector3(size);

	m_dynamicsWorld->removeRigidBody(rigidBody);

	switch (collisionShape->getShapeType()) {

		case BOX_SHAPE_PROXYTYPE: {
			btBoxShape* boxShape = static_cast<btBoxShape*>(collisionShape);
			boxShape->setLocalScaling(size);
			break;
		}

		case SPHERE_SHAPE_PROXYTYPE: {
			btSphereShape* sphereShape = static_cast<btSphereShape*>(collisionShape);
			sphereShape->setLocalScaling(btVector3(sizeX, sizeX, sizeX));
			break;
		}	

		case CYLINDER_SHAPE_PROXYTYPE: {
			btCylinderShape* cylinderShape = static_cast<btCylinderShape*>(collisionShape);
			cylinderShape->setLocalScaling(btVector3(sizeX, sizeY, sizeX));
			break;
		}

		case CONE_SHAPE_PROXYTYPE: {
			btConeShape* coneShape = static_cast<btConeShape*>(collisionShape);
			coneShape->setLocalScaling(btVector3(sizeX, 2.0f * sizeY, sizeX));
			break;
		}

		case COMPOUND_SHAPE_PROXYTYPE: {		// snowman,...
			std::shared_ptr<CompoundObject> compoundObject = std::dynamic_pointer_cast<CompoundObject>(node);
			btCompoundShape* compoundShape = static_cast<btCompoundShape*>(collisionShape);

			btVector3 initialSize = compoundShape->getLocalScaling();
			float factor = distanceFigers.length() / initialSize.length();

			if (factor > 1.5) factor = 1.5f;
			if (factor < 0.25) factor = 0.25f;

			compoundShape->setLocalScaling(btVector3(factor, factor, factor));
			logStderr("Scale object... %5.2f\n", factor);

			break;
		}

		case CONVEX_HULL_SHAPE_PROXYTYPE: {		// icosahedron, table, tree, flower, mushroom,...
			btConvexHullShape* convexHullShape = static_cast<btConvexHullShape*>(collisionShape);

			btVector3 initialSize = convexHullShape->getLocalScaling();
			float factor = sizeX / initialSize.x();

			convexHullShape->setLocalScaling(factor * initialSize);
			convexHullShape->initializePolyhedralFeatures();

			break;
		}

		case GIMPACT_SHAPE_PROXYTYPE: {			// truck, bunny,...
			std::shared_ptr<ImpactMesh> impactMesh = std::dynamic_pointer_cast<ImpactMesh>(node);
			btGImpactMeshShape* impactMeshShape = static_cast<btGImpactMeshShape*>(collisionShape);

			btVector3 initialSize = impactMeshShape->getLocalScaling();
			float factor = distanceFigers.length();

			if (factor > 2.5) factor = 2.5f;
			if (factor < 0.5) factor = 0.5f;

			logStderr("Scale object... %5.2f\n", factor);
			impactMeshShape->setLocalScaling(btVector3(factor, factor, factor) / 3.0f);

			btVector3 localInertia;
			float mass = impactMesh->getMass();
			impactMeshShape->calculateLocalInertia(mass, localInertia);

			rigidBody->setMassProps(mass, localInertia);
			rigidBody->updateInertiaTensor();

			impactMeshShape->postUpdate();
			impactMeshShape->setMargin(0.04f);
			impactMeshShape->updateBound();

			break;
		}

		default:
			logStderr("ERROR: Unrecognized collision shape...\n");
			break;
	}

	m_dynamicsWorld->addRigidBody(rigidBody);
	m_dynamicsWorld->updateSingleAabb(rigidBody);

	rigidBody->activate(true);
}

{...}

LastBlow
Posts: 14
Joined: Mon Jul 11, 2016 10:36 am
Location: SAN DIEGO

Re: activate object after size changes...

Post by LastBlow » Sat Feb 09, 2019 9:15 am

LastBlow wrote:
Mon Feb 04, 2019 6:39 pm
Alright, removing the rigid body and adding it back seems to solve the problem for btConvexHullShape
which does not get hung in thin air anymore! Thank you for the quick response, Erwin.

Curiously, no change thought for btGImpactMeshShape which would still resize their AABB down but not up.

Latest code below...

Code: Select all

{...}

	float sizeX, sizeY, sizeZ;

	btVector3 distanceFigers = ((startPosition2 - startPosition1) / 2.0f).absolute();
	// logStderr("Distance fingers...\n"); printVector3(distanceFigers);

	(distanceFigers.x() < 1.0f) ? sizeX = 2.0f : sizeX = distanceFigers.x();
	(distanceFigers.y() < 1.0f) ? sizeY = 2.0f : sizeY = distanceFigers.y();
	(distanceFigers.z() < 1.0f) ? sizeZ = 2.0f : sizeZ = distanceFigers.z();

	btVector3 size = btVector3(sizeX, sizeY, sizeZ);
	logStderr("size object...\n"); printVector3(size);

	m_dynamicsWorld->removeRigidBody(rigidBody);

	switch (collisionShape->getShapeType()) {

		case BOX_SHAPE_PROXYTYPE: {
			btBoxShape* boxShape = static_cast<btBoxShape*>(collisionShape);
			boxShape->setLocalScaling(size);
			break;
		}

		case SPHERE_SHAPE_PROXYTYPE: {
			btSphereShape* sphereShape = static_cast<btSphereShape*>(collisionShape);
			sphereShape->setLocalScaling(btVector3(sizeX, sizeX, sizeX));
			break;
		}	

		case CYLINDER_SHAPE_PROXYTYPE: {
			btCylinderShape* cylinderShape = static_cast<btCylinderShape*>(collisionShape);
			cylinderShape->setLocalScaling(btVector3(sizeX, sizeY, sizeX));
			break;
		}

		case CONE_SHAPE_PROXYTYPE: {
			btConeShape* coneShape = static_cast<btConeShape*>(collisionShape);
			coneShape->setLocalScaling(btVector3(sizeX, 2.0f * sizeY, sizeX));
			break;
		}

		case COMPOUND_SHAPE_PROXYTYPE: {		// snowman,...
			std::shared_ptr<CompoundObject> compoundObject = std::dynamic_pointer_cast<CompoundObject>(node);
			btCompoundShape* compoundShape = static_cast<btCompoundShape*>(collisionShape);

			btVector3 initialSize = compoundShape->getLocalScaling();
			float factor = distanceFigers.length() / initialSize.length();

			if (factor > 1.5) factor = 1.5f;
			if (factor < 0.25) factor = 0.25f;

			compoundShape->setLocalScaling(btVector3(factor, factor, factor));
			logStderr("Scale object... %5.2f\n", factor);

			break;
		}

		case CONVEX_HULL_SHAPE_PROXYTYPE: {		// icosahedron, table, tree, flower, mushroom,...
			btConvexHullShape* convexHullShape = static_cast<btConvexHullShape*>(collisionShape);

			btVector3 initialSize = convexHullShape->getLocalScaling();
			float factor = sizeX / initialSize.x();

			convexHullShape->setLocalScaling(factor * initialSize);
			convexHullShape->initializePolyhedralFeatures();

			break;
		}

		case GIMPACT_SHAPE_PROXYTYPE: {			// truck, bunny,...
			std::shared_ptr<ImpactMesh> impactMesh = std::dynamic_pointer_cast<ImpactMesh>(node);
			btGImpactMeshShape* impactMeshShape = static_cast<btGImpactMeshShape*>(collisionShape);

			btVector3 initialSize = impactMeshShape->getLocalScaling();
			float factor = distanceFigers.length();

			if (factor > 2.5) factor = 2.5f;
			if (factor < 0.5) factor = 0.5f;

			logStderr("Scale object... %5.2f\n", factor);
			impactMeshShape->setLocalScaling(btVector3(factor, factor, factor) / 3.0f);

			btVector3 localInertia;
			float mass = impactMesh->getMass();
			impactMeshShape->calculateLocalInertia(mass, localInertia);

			rigidBody->setMassProps(mass, localInertia);
			rigidBody->updateInertiaTensor();

			impactMeshShape->postUpdate();
			impactMeshShape->setMargin(0.04f);
			impactMeshShape->updateBound();

			break;
		}

		default:
			logStderr("ERROR: Unrecognized collision shape...\n");
			break;
	}

	m_dynamicsWorld->addRigidBody(rigidBody);
	m_dynamicsWorld->updateSingleAabb(rigidBody);

	rigidBody->activate(true);
}

{...}

Post Reply