Page 1 of 1

activate object after size changes...

Posted: Thu Jan 31, 2019 4:12 pm
by LastBlow
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? :)))

Object hanging in thin air after resizing
Object hanging in thin air after resizing
hanging in thin air.jpg (140.53 KiB) Viewed 6898 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);
	}
}

Re: activate object after size changes...

Posted: Fri Feb 01, 2019 4:47 pm
by drleviathan
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?

Re: activate object after size changes...

Posted: Sun Feb 03, 2019 8:42 am
by LastBlow
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? ;-)))

Re: activate object after size changes...

Posted: Sun Feb 03, 2019 5:29 pm
by LastBlow
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

Re: activate object after size changes...

Posted: Mon Feb 04, 2019 6:39 pm
by LastBlow
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);
}

{...}

Re: activate object after size changes...

Posted: Sat Feb 09, 2019 9:15 am
by LastBlow
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);
}

{...}

Re: activate object after size changes...

Posted: Fri Oct 18, 2019 8:00 am
by jiaxin
change size or radius etc, it be same as scaling, so I solve this problem by updating the local scaling of the shape