I'm using Newton quite for a while in my engine. In the past I used Newton2.x. I have the following destruction scenario:
I have some fragment bodies, that are connected together with hinge joints, forming the whole body (Container). As long as the force does not exceed the max. allowed breakforce the framents are tied together.
Now I'm throwing other objects at the container. Now with Newton2.x the container will break to peaces.
Since I'm using Newton3, the container will no more break.
I'm having custom force and torque callbacks, in which I add force etc. (NewtonBodySetForceAndTorqueCallback). Something is wrong with the forces. Has something significantly changed in Newton3? Do I miss a command? The forces I get for testing if its high enough to resolve the joints is never high enough and depending when I calculate the force, the acting force is even 0.
When I manually break the joints, the fragments have no gravity anymore, which is also strange, since each fragment has its own force and torque callback.
So there are several things strange.
Code:
- Code: Select all
void PhysicsActiveDestructableComponent::SplitPart::splitPartMoveCallback(OgreNewt::Body* body, Ogre::Real timeStep, int threadIndex)
{
this->splitPartBody->setCustomForceAndTorqueCallback<PhysicsActiveDestructableComponent::SplitPart>(&PhysicsActiveDestructableComponent::SplitPart::splitPartMoveCallback, this);
void PhysicsActiveDestructableComponent::SplitPart::splitPartMoveCallback(OgreNewt::Body* body, Ogre::Real timeStep, int threadIndex)
{
Ogre::Real breakForceLength = body->getForce().squaredLength();
Ogre::Real breakTorqueLength = body->getOmega().squaredLength();
PhysicsActiveDestructableComponent::SplitPart* part = OgreNewt::any_cast<PhysicsActiveDestructableComponent::SplitPart*>(body->getUserData());
// go through all joint handlers for a split part and if the acting force or torgue is stronger as the configured value,
for (auto& jointCompPtr : part->getJointComponents())
{
// check if the force acting on the body is higher as the specified force to break the joint
if (breakForceLength >= part->getBreakForce() /** part->getBreakForce()*/ || breakTorqueLength >= part->getBreakTorque() /** part->getBreakTorque()*/)
{
Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LML_CRITICAL, "[PhysicsActiveDestructableComponent::SplitPart] Force high enough!!!!");
// If at least one part is broken, hide the placeholder scene node and show all parts
if (false == this->physicsActiveDestructableComponent->firstTimeBroken && true == this->physicsActiveDestructableComponent->motionless->getBool())
{
this->physicsActiveDestructableComponent->gameObjectPtr->getSceneNode()->setVisible(false);
for (auto& it = this->physicsActiveDestructableComponent->parts.cbegin(); it != this->physicsActiveDestructableComponent->parts.cend(); it++)
{
it->second->sceneNode->setVisible(true);
}
this->physicsActiveDestructableComponent->firstTimeBroken = true;
}
// can be called by x-configured threads, therefore lock here the remove operation
mutex.lock();
if (jointCompPtr->getJoint())
{
part->setMotionLess(false);
this->physicsActiveDestructableComponent->motionless->setValue(false);
this->physicsActiveDestructableComponent->delayedDeleteJointComponentList.emplace(jointCompPtr);
}
// Also check all its predecessors and remove the joints if necessary
auto& predecessorJointComponent = NOWA::makeStrongPtr(GameObjectController::getInstance()->getJointComponent(jointCompPtr->getPredecessorId()));
if (predecessorJointComponent && predecessorJointComponent->getJoint())
{
this->physicsActiveDestructableComponent->delayedDeleteJointComponentList.emplace(predecessorJointComponent);
}
mutex.unlock();
}
}
// will not work here, because force is 0 above, why???
Ogre::Real mass;
Ogre::Vector3 inertia;
// calculate gravity
body->getMassMatrix(mass, inertia);
Ogre::Vector3 force = this->physicsActiveDestructableComponent->getGravity();
force *= mass;
// add the force that pushed towards earth
body->setForce(force);
}
}
Regards
Lax