diff --git a/include/irrDynamics.h b/include/irrDynamics.h index cb42d22..8a556c3 100644 --- a/include/irrDynamics.h +++ b/include/irrDynamics.h @@ -66,6 +66,14 @@ class irrDynamics * \param pivotInB A position relative to nodeB where the hinge relation will be placed. * \return True, when both nodes were found in the physics representation and the relation was created.*/ static bool createPoint2PointConstraint(irr::scene::ISceneNode* nodeA, irr::scene::ISceneNode* nodeB, const irr::core::vector3df& pivotInA, const irr::core::vector3df& pivotInB); + //! Create a slider relation between two objects + /** The slider constraint allows a rigid body to rotate around and translate along an axis. This + * method uses to the two nodes' current rotation to compute this axis. + * \note Both scene nodes have to be already added to the sim. + * \param nodeA The "parent" node the constraint is computed from. + * \param nodeB The child element that will be animated by that relation. + * \return True, when both nodes were found in the physics representation and the relation was created.*/ + static bool createSliderConstraint(irr::scene::ISceneNode* nodeA, irr::scene::ISceneNode* nodeB, const irr::core::vector3df& posInA, const irr::core::vector3df& rotInA, const irr::core::vector3df& posInB, const irr::core::vector3df& rotInB); //! Remove an object from the physics /** Call this whenever you either remove the corresponding scene node from the ISceneManager or you don't want * to have it animated by the physics anymore. diff --git a/src/irrDynamics.cpp b/src/irrDynamics.cpp index 5594068..09eede0 100644 --- a/src/irrDynamics.cpp +++ b/src/irrDynamics.cpp @@ -136,7 +136,7 @@ void irrDynamics::removeObject(scene::ISceneNode* node) { irrDynamics* inst = getInstance(); std::map::iterator iter = inst->objects.find(node); - if (iter == inst->objects.end()) + if (iter != inst->objects.end()) { inst->world->removeRigidBody(iter->second); @@ -288,6 +288,54 @@ bool irrDynamics::createPoint2PointConstraint(scene::ISceneNode* nodeA, scene::I return true; } +bool irrDynamics::createSliderConstraint(scene::ISceneNode* nodeA, + scene::ISceneNode* nodeB, + const core::vector3df& posInA, + const core::vector3df& rotInA, + const core::vector3df& posInB, + const core::vector3df& rotInB) +{ + irrDynamics* inst = getInstance(); + //find the corresponding rigid bodies: + std::map::iterator iterA, iterB; + iterA = inst->objects.find(nodeA); + iterB = inst->objects.find(nodeB); + + if (iterA == inst->objects.end()) + { + printf("irrdynamics: Unable to find first node for constraint!\n"); + return false; + } + + if (iterB == inst->objects.end()) + { + printf("irrdynamics: Unable to find second node for constraint!\n"); + return false; + } + + btTransform matA, matB; + core::vector3df rotationRadians = rotInA; + rotationRadians *= core::DEGTORAD; + core::quaternion rotA(rotationRadians); + + rotationRadians = rotInB; + rotationRadians *= core::DEGTORAD; + core::quaternion rotB(rotationRadians); + + matA.setIdentity(); + matA.setOrigin(btVector3(posInA.X, posInA.Y, posInA.Z)); + matA.setRotation(btQuaternion(rotA.X, rotA.Y, rotA.Z, rotA.W)); + + matB.setIdentity(); + matB.setOrigin(btVector3(posInB.X, posInB.Y, posInB.Z)); + matB.setRotation(btQuaternion(rotB.X, rotB.Y, rotB.Z, rotB.W)); + + + btSliderConstraint* constraint = new btSliderConstraint(*(iterA->second), *(iterB->second), matA, matB, true); + inst->world->addConstraint(constraint); + return true; +} + void irrDynamics::applyCentralForce(scene::ISceneNode* node, const core::vector3df& force) { irrDynamics* inst = getInstance();