diff --git a/Extras/MayaPlugin/Makefile b/Extras/MayaPlugin/Makefile index 592a7fabb..b9e43c523 100644 --- a/Extras/MayaPlugin/Makefile +++ b/Extras/MayaPlugin/Makefile @@ -36,20 +36,30 @@ GL_LIB=-lGL -lGLU MAYA_INCLUDE=-I$(MAYA)/include MAYA_LIB=-L$(MAYA)/lib -lOpenMaya -lFoundation -lOpenMayaUI -lOpenMayaFX -SOURCES = pluginMain.cpp colladaExport.cpp rigidBodyNode.cpp rigidBodyArrayNode.cpp collisionShapeNode.cpp \ - solver.cpp bt_solver.cpp dSolverNode.cpp dSolverCmd.cpp dRigidBodyCmd.cpp dRigidBodyArrayCmd.cpp \ - pdbIO.cpp drawUtils.cpp +SOURCES = bt_solver.cpp dRigidBodyArrayCmd.cpp pdbIO.cpp \ + colladaExport.cpp dRigidBodyCmd.cpp pluginMain.cpp \ + collisionShapeNode.cpp dSolverCmd.cpp rigidBodyArrayNode.cpp \ + dNailConstraintCmd.cpp dSolverNode.cpp rigidBodyNode.cpp \ + drawUtils.cpp nailConstraintNode.cpp solver.cpp + + + +HEADERS = box_shape.h collisionShapeNode.h nail_constraint.h \ + box_shape_impl.h constraint.h nail_constraint_impl.h \ + bt_box_shape.h constraint_impl.h nailConstraintNode.h \ + bt_collision_shape.h convex_hull_shape.h pdbIO.h \ + bt_constraint.h convex_hull_shape_impl.h plane_shape.h \ + bt_convex_hull_shape.h dNailConstraintCmd.h plane_shape_impl.h \ + bt_mesh_shape.h drawUtils.h rigidBodyArrayNode.h \ + bt_nail_constraint.h dRigidBodyArrayCmd.h rigid_body.h \ + bt_plane_shape.h dRigidBodyCmd.h rigid_body_impl.h \ + bt_rigid_body.h dSolverCmd.h rigidBodyNode.h \ + bt_solver.h dSolverNode.h shared_ptr.h \ + bt_sphere_shape.h mathUtils.h solver.h \ + colladaExport.h mayaUtils.h solver_impl.h \ + collision_shape.h mesh_shape.h sphere_shape.h \ + collision_shape_impl.h mesh_shape_impl.h sphere_shape_impl.h -HEADERS = box_shape.h bt_sphere_shape.h dSolverNode.h rigid_body_impl.h \ - box_shape_impl.h collision_shape.h mathUtils.h rigidBodyNode.h \ - bt_box_shape.h collision_shape_impl.h mayaUtils.h solver.h \ - bt_collision_shape.h collisionShapeNode.h mesh_shape.h solver_impl.h \ - bt_convex_hull_shape.h convex_hull_shape.h mesh_shape_impl.h sphere_shape.h \ - bt_mesh_shape.h convex_hull_shape_impl.h plane_shape.h sphere_shape_impl.h \ - bt_plane_shape.h dRigidBodyArrayCmd.h plane_shape_impl.h \ - bt_rigid_body.h dRigidBodyCmd.h rigidBodyArrayNode.h \ - bt_solver.h dSolverCmd.h rigid_body.h pdbIO.h \ - shared_ptr.h drawUtils.h INCLUDE_FLAGS= $(GL_INCLUDE) $(BULLET_INCLUDE) $(MAYA_INCLUDE) diff --git a/Extras/MayaPlugin/bt_constraint.h b/Extras/MayaPlugin/bt_constraint.h new file mode 100644 index 000000000..d0081f377 --- /dev/null +++ b/Extras/MayaPlugin/bt_constraint.h @@ -0,0 +1,52 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//bt_constraint.h + +#ifndef DYN_BT_CONSTRAINT_H +#define DYN_BT_CONSTRAINT_H + +#include "btBulletCollisionCommon.h" +#include "btBulletDynamicsCommon.h" + +class bt_constraint_t +{ +public: + +protected: + friend class bt_solver_t; + + bt_constraint_t() { } + + btTypedConstraint* constraint() { return m_constraint.get(); } + void set_constraint(btTypedConstraint *constraint) { return m_constraint.reset(constraint); } + +public: + friend class bt_rigid_body_t; + + virtual ~bt_constraint_t() { } + +protected: + shared_ptr m_constraint; +}; + +#endif diff --git a/Extras/MayaPlugin/bt_nail_constraint.h b/Extras/MayaPlugin/bt_nail_constraint.h new file mode 100644 index 000000000..5a8b2c928 --- /dev/null +++ b/Extras/MayaPlugin/bt_nail_constraint.h @@ -0,0 +1,82 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//bt_nail_constraint.h + +#ifndef DYN_BT_NAIL_CONSTRAINT_H +#define DYN_BT_NAIL_CONSTRAINT_H + +#include "bt_constraint.h" +#include "nail_constraint_impl.h" + +class bt_nail_constraint_t: public bt_constraint_t, public nail_constraint_impl_t { +public: + + virtual void set_damping(float d) { + btPoint2PointConstraint* p2pc = static_cast(m_constraint.get()); + p2pc->m_setting.m_damping = d; + } + + virtual float damping() const { + btPoint2PointConstraint const* p2pc = static_cast(m_constraint.get()); + return p2pc->m_setting.m_damping; + } + + // + virtual void set_pivot(vec3f const &p) { + btPoint2PointConstraint* p2pc = static_cast(m_constraint.get()); + btVector3 bt_pivot(p[0], p[1], p[2]); + p2pc->setPivotA(bt_pivot); + p2pc->setPivotB(m_constraint->getRigidBodyA().getCenterOfMassTransform()(bt_pivot)); + // p2pc->buildJacobian(); + } + + virtual void get_pivot(vec3f &p) const { + btPoint2PointConstraint const* p2pc = static_cast(m_constraint.get()); + p[0] = p2pc->getPivotInA().x(); + p[1] = p2pc->getPivotInA().y(); + p[2] = p2pc->getPivotInA().z(); + } + + virtual void get_world_pivot(vec3f &p) const { + btPoint2PointConstraint const* p2pc = static_cast(m_constraint.get()); + p[0] = p2pc->getPivotInB().x(); + p[1] = p2pc->getPivotInB().y(); + p[2] = p2pc->getPivotInB().z(); + } + +protected: + friend class bt_solver_t; + + bt_nail_constraint_t(rigid_body_impl_t* rb, vec3f const& pivot): + nail_constraint_impl_t() + { + btRigidBody& bt_body = *static_cast(rb)->body(); + + m_constraint.reset(new btPoint2PointConstraint(bt_body, btVector3(pivot[0], pivot[1], pivot[2]))); + } + +private: + +}; + +#endif diff --git a/Extras/MayaPlugin/bt_rigid_body.h b/Extras/MayaPlugin/bt_rigid_body.h index d58ce5b3c..ad3b54c66 100644 --- a/Extras/MayaPlugin/bt_rigid_body.h +++ b/Extras/MayaPlugin/bt_rigid_body.h @@ -43,21 +43,14 @@ public: const btTransform& btxform = m_body->getWorldTransform(); btQuaternion q = btxform.getRotation(); btVector3 p = btxform.getOrigin(); - // position = vec3f(p.x(), p.y(), p.z()) - m_collision_shape->center(); position = vec3f(p.x(), p.y(), p.z()); - //rotation = qprod(quatf(q.w(), q.x(), q.y(), q.z()), qconj(m_collision_shape->rotation())); rotation = quatf(q.w(), q.x(), q.y(), q.z()); } virtual void set_transform(vec3f const &position, quatf const &rotation) { -// vec3f tp = position + m_collision_shape->center(); vec3f tp = position; - // quatf tr = qprod(rotation, m_collision_shape->rotation()); quatf tr = rotation; - // std::cout << "----------" << std::endl; - // std::cout << rotation << std::endl; - // std::cout << m_collision_shape->rotation() << std::endl; btTransform xform(btQuaternion(tr[1], tr[2], tr[3], tr[0]), btVector3(tp[0], tp[1], tp[2])); m_body->setWorldTransform(xform); @@ -103,7 +96,6 @@ public: virtual void set_restitution(float r) { - // std::cout << r << std::endl; m_body->setRestitution(r); } diff --git a/Extras/MayaPlugin/bt_solver.h b/Extras/MayaPlugin/bt_solver.h index cbee13dfa..a48bbf155 100644 --- a/Extras/MayaPlugin/bt_solver.h +++ b/Extras/MayaPlugin/bt_solver.h @@ -37,6 +37,7 @@ Written by: Nicola Candussi #include "bt_box_shape.h" #include "bt_convex_hull_shape.h" #include "bt_mesh_shape.h" +#include "bt_nail_constraint.h" class bt_solver_t: public solver_impl_t { @@ -71,6 +72,11 @@ public: return new bt_mesh_shape_t(vertices, num_vertices, normals, indices, num_indices); } + virtual nail_constraint_impl_t* create_nail_constraint(rigid_body_impl_t* rb, vec3f const& pivot) + { + return new bt_nail_constraint_t(rb, pivot); + } + virtual void add_rigid_body(rigid_body_impl_t* rb) { bt_rigid_body_t* bt_body = static_cast(rb); @@ -83,6 +89,18 @@ public: m_dynamicsWorld->removeRigidBody(bt_body->body()); } + virtual void add_constraint(constraint_impl_t* c) + { + bt_constraint_t* btc = dynamic_cast(c); + m_dynamicsWorld->addConstraint(btc->constraint()); + } + + virtual void remove_constraint(constraint_impl_t* c) + { + bt_constraint_t* btc = dynamic_cast(c); + m_dynamicsWorld->removeConstraint(btc->constraint()); + } + virtual void set_gravity(vec3f const& g) { m_dynamicsWorld->setGravity(btVector3(g[0], g[1], g[2])); diff --git a/Extras/MayaPlugin/constraint.h b/Extras/MayaPlugin/constraint.h new file mode 100644 index 000000000..fdc5aa871 --- /dev/null +++ b/Extras/MayaPlugin/constraint.h @@ -0,0 +1,52 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//constraint.h + +#ifndef DYN_CONSTRAINT_H +#define DYN_CONSTRAINT_H + +#include "shared_ptr.h" +#include "constraint_impl.h" + +class constraint_t +{ +public: + //typedefs + typedef shared_ptr pointer; + +public: + virtual ~constraint_t() {} + +protected: + friend class solver_t; + + constraint_t(constraint_impl_t* impl): m_impl(impl) { } + + constraint_impl_t* impl() { return m_impl.get(); } + constraint_impl_t const* impl() const { return m_impl.get(); } + +protected: + shared_ptr m_impl; +}; + +#endif diff --git a/Extras/MayaPlugin/constraint_impl.h b/Extras/MayaPlugin/constraint_impl.h new file mode 100644 index 000000000..36d69b435 --- /dev/null +++ b/Extras/MayaPlugin/constraint_impl.h @@ -0,0 +1,37 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//constraint_impl.h + +#ifndef DYN_CONSTRAINT_IMPL_H +#define DYN_CONSTRAINT_IMPL_H + +class constraint_impl_t +{ +public: + // + +public: + virtual ~constraint_impl_t() {}; +}; + +#endif diff --git a/Extras/MayaPlugin/dNailConstraintCmd.cpp b/Extras/MayaPlugin/dNailConstraintCmd.cpp new file mode 100644 index 000000000..d9d2a5894 --- /dev/null +++ b/Extras/MayaPlugin/dNailConstraintCmd.cpp @@ -0,0 +1,133 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//dNailConstraintCmd.cpp + +#include +#include +#include + +#include "nailConstraintNode.h" +#include "dNailConstraintCmd.h" + + +MString dNailConstraintCmd::typeName("dNailConstraint"); + +dNailConstraintCmd::dNailConstraintCmd() + : m_argDatabase(0), + m_dagModifier(0) +{ +} + + +dNailConstraintCmd::~dNailConstraintCmd() +{ + if (m_argDatabase) { + delete m_argDatabase; + } + + if (m_dagModifier) { + delete m_dagModifier; + } +} + + +void * +dNailConstraintCmd::creator() +{ + return new dNailConstraintCmd; +} + + +MSyntax +dNailConstraintCmd::syntax() +{ + MSyntax syntax; + syntax.enableQuery(false); + syntax.enableEdit(false); + + syntax.addFlag("-n", "-name", MSyntax::kString); + // syntax.addFlag("-fn", "-filename", MSyntax::kString); + // syntax.addFlag("-col", "-color", MSyntax::kString); + // syntax.addFlag("-dia", "-diameter", MSyntax::kDouble); + + return syntax; +} + + +MStatus +dNailConstraintCmd::doIt(const MArgList &args) +{ + MStatus stat; + m_argDatabase = new MArgDatabase(syntax(), args, &stat); + if (stat == MS::kFailure) { + return stat; + } + return redoIt(); +} + + +MStatus +dNailConstraintCmd::undoIt() +{ + MGlobal::setActiveSelectionList(m_undoSelectionList); + + if (m_dagModifier) { + m_dagModifier->undoIt(); + delete m_dagModifier; + m_dagModifier = 0; + } + + return MS::kSuccess; +} + + +MStatus +dNailConstraintCmd::redoIt() +{ + MGlobal::getActiveSelectionList(m_undoSelectionList); + + MString name; + if (m_argDatabase->isFlagSet("-name")) { + m_argDatabase->getFlagArgument("-name", 0, name); + } + if (!name.length()) { + name = "dNailConstraint"; + } + + m_dagModifier = new MDagModifier; + + MObject parentObj = m_dagModifier->createNode("transform"); + m_dagModifier->renameNode(parentObj, name + "#"); + m_dagModifier->doIt(); + + MObject dConstraintObj = m_dagModifier->createNode(nailConstraintNode::typeId, parentObj); + std::string dConstraintName = MFnDependencyNode(parentObj).name().asChar(); + std::string::size_type pos = dConstraintName.find_last_not_of("0123456789"); + dConstraintName.insert(pos + 1, "Shape"); + m_dagModifier->renameNode(dConstraintObj, dConstraintName.c_str()); + m_dagModifier->doIt(); + + setResult(MFnDependencyNode(dConstraintObj).name()); + + return MS::kSuccess; +} diff --git a/Extras/MayaPlugin/dNailConstraintCmd.h b/Extras/MayaPlugin/dNailConstraintCmd.h new file mode 100644 index 000000000..d09a092bc --- /dev/null +++ b/Extras/MayaPlugin/dNailConstraintCmd.h @@ -0,0 +1,58 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//dNailConstraintCmd.h + +#ifndef DYN_NAIL_CONSTRAINT_CMD_H +#define DYN_NAIL_CONSTRAINT_CMD_H + +#include +#include +#include + +#include + +class dNailConstraintCmd : public MPxCommand +{ +public: + dNailConstraintCmd(); + virtual ~dNailConstraintCmd(); + + static void *creator(); + static MSyntax syntax(); + + MStatus doIt(const MArgList &i_mArgList); + MStatus redoIt(); + MStatus undoIt(); + bool isUndoable() const { return true; } + bool hasSyntax() const { return true; } + + static MString typeName; + +protected: + MArgDatabase *m_argDatabase; + MDagModifier *m_dagModifier; + + MSelectionList m_undoSelectionList; +}; + +#endif diff --git a/Extras/MayaPlugin/dRigidBodyCmd.cpp b/Extras/MayaPlugin/dRigidBodyCmd.cpp index ac76d84bc..181a56dec 100644 --- a/Extras/MayaPlugin/dRigidBodyCmd.cpp +++ b/Extras/MayaPlugin/dRigidBodyCmd.cpp @@ -20,7 +20,7 @@ not be misrepresented as being the original software. Written by: Nicola Candussi */ -//dRidigBodyCmd.cpp +//dRigidBodyCmd.cpp #include #include diff --git a/Extras/MayaPlugin/mathUtils.h b/Extras/MayaPlugin/mathUtils.h index c94455fb5..3f2bb0619 100644 --- a/Extras/MayaPlugin/mathUtils.h +++ b/Extras/MayaPlugin/mathUtils.h @@ -31,6 +31,7 @@ Written by: Nicola Candussi using namespace mvl; typedef vec vec3f; +typedef vec vec4f; typedef mat mat4x4f; typedef mat mat3x3f; typedef vec quatf; diff --git a/Extras/MayaPlugin/nailConstraintNode.cpp b/Extras/MayaPlugin/nailConstraintNode.cpp new file mode 100644 index 000000000..57328b656 --- /dev/null +++ b/Extras/MayaPlugin/nailConstraintNode.cpp @@ -0,0 +1,324 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//nailConstraintNode.cpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rigidBodyNode.h" +#include "nailConstraintNode.h" +#include "mayaUtils.h" + +#include "solver.h" + +MTypeId nailConstraintNode::typeId(0x10033A); +MString nailConstraintNode::typeName("dNailConstraint"); + +MObject nailConstraintNode::ia_rigidBody; +MObject nailConstraintNode::ia_damping; +MObject nailConstraintNode::ca_constraint; +MObject nailConstraintNode::ca_constraintParam; + + +MStatus nailConstraintNode::initialize() +{ + MStatus status; + MFnMessageAttribute fnMsgAttr; + MFnNumericAttribute fnNumericAttr; + MFnMatrixAttribute fnMatrixAttr; + + ia_rigidBody = fnMsgAttr.create("inRigidBody", "inrb", &status); + MCHECKSTATUS(status, "creating inRigidBody attribute") + status = addAttribute(ia_rigidBody); + MCHECKSTATUS(status, "adding inRigidBody attribute") + + ia_damping = fnNumericAttr.create("damping", "dmp", MFnNumericData::kDouble, 1.0, &status); + MCHECKSTATUS(status, "creating damping attribute") + fnNumericAttr.setKeyable(true); + status = addAttribute(ia_damping); + MCHECKSTATUS(status, "adding damping attribute") + + ca_constraint = fnNumericAttr.create("ca_constraint", "caco", MFnNumericData::kBoolean, 0, &status); + MCHECKSTATUS(status, "creating ca_constraint attribute") + fnNumericAttr.setConnectable(false); + fnNumericAttr.setHidden(true); + fnNumericAttr.setStorable(false); + fnNumericAttr.setKeyable(false); + status = addAttribute(ca_constraint); + MCHECKSTATUS(status, "adding ca_constraint attribute") + + ca_constraintParam = fnNumericAttr.create("ca_constraintParam", "cacop", MFnNumericData::kBoolean, 0, &status); + MCHECKSTATUS(status, "creating ca_constraintParam attribute") + fnNumericAttr.setConnectable(false); + fnNumericAttr.setHidden(true); + fnNumericAttr.setStorable(false); + fnNumericAttr.setKeyable(false); + status = addAttribute(ca_constraintParam); + MCHECKSTATUS(status, "adding ca_constraintParam attribute") + + + status = attributeAffects(ia_rigidBody, ca_constraint); + MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBody, ca_constraint)") + + status = attributeAffects(ia_rigidBody, ca_constraintParam); + MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBody, ca_constraintParam)") + + status = attributeAffects(ia_damping, ca_constraintParam); + MCHECKSTATUS(status, "adding attributeAffects(ia_damping, ca_constraintParam)") + + return MS::kSuccess; +} + +nailConstraintNode::nailConstraintNode() +{ + // std::cout << "nailConstraintNode::nailConstraintNode" << std::endl; +} + +nailConstraintNode::~nailConstraintNode() +{ + // std::cout << "nailConstraintNode::~nailConstraintNode" << std::endl; +} + +void nailConstraintNode::nodeRemoved(MObject& node, void *clientData) +{ + // std::cout << "nailConstraintNode::nodeRemoved" << std::endl; + MFnDependencyNode fnNode(node); + nailConstraintNode *pNode = static_cast(fnNode.userNode()); + constraint_t::pointer constraint = static_cast(pNode->m_constraint); + solver_t::remove_constraint(constraint); +} + +void* nailConstraintNode::creator() +{ + return new nailConstraintNode(); +} + + +bool nailConstraintNode::setInternalValueInContext ( const MPlug & plug, + const MDataHandle & dataHandle, + MDGContext & ctx) +{ + /* if ((plug == pdbFiles) || (plug == ia_scale) || (plug == ia_percent)) { + m_framesDirty = true; + } else if(plug == textureFiles) { + gpufx::m_renderer.setColorTextureDirty(); + }*/ + return false; //setInternalValueInContext(plug,dataHandle,ctx); +} + +MStatus nailConstraintNode::compute(const MPlug& plug, MDataBlock& data) +{ + //std::cout << "nailConstraintNode::compute: " << plug.name() << std::endl; + //MTime time = data.inputValue( nailConstraintNode::inTime ).asTime(); + if(plug == ca_constraint) { + computeConstraint(plug, data); + } else if(plug == ca_constraintParam) { + computeConstraintParam(plug, data); + } else if(plug.isElement()) { + if(plug.array() == worldMatrix && plug.logicalIndex() == 0) { + computeWorldMatrix(plug, data); + } else { + return MStatus::kUnknownParameter; + } + } else { + return MStatus::kUnknownParameter; + } + return MStatus::kSuccess; +} + +void nailConstraintNode::draw( M3dView & view, const MDagPath &path, + M3dView::DisplayStyle style, + M3dView::DisplayStatus status ) +{ + // std::cout << "nailConstraintNode::draw" << std::endl; + + update(); + + view.beginGL(); + glPushAttrib( GL_ALL_ATTRIB_BITS ); + + glDisable(GL_LIGHTING); + + if( !(status == M3dView::kActive || + status == M3dView::kLead || + status == M3dView::kHilite || + ( style != M3dView::kGouraudShaded && style != M3dView::kFlatShaded )) ) { + glColor3f(1.0, 1.0, 0.0); + } + + glBegin(GL_LINES); + glVertex3f(-1.0, 0.0, 0.0); + glVertex3f(1.0, 0.0, 0.0); + + glVertex3f(0.0, -1.0, 0.0); + glVertex3f(0.0, 1.0, 0.0); + + glVertex3f(0.0, 0.0, -1.0); + glVertex3f(0.0, 0.0, 1.0); + glEnd(); + + glPopAttrib(); + view.endGL(); +} + +bool nailConstraintNode::isBounded() const +{ + //return true; + return false; +} + +MBoundingBox nailConstraintNode::boundingBox() const +{ + // std::cout << "nailConstraintNode::boundingBox()" << std::endl; + //load the pdbs + MObject node = thisMObject(); + + MPoint corner1(-1, -1, -1); + MPoint corner2(1, 1, 1); + return MBoundingBox(corner1, corner2); +} + +//standard attributes +void nailConstraintNode::computeConstraint(const MPlug& plug, MDataBlock& data) +{ + // std::cout << "nailConstraintNode::computeConstraint" << std::endl; + + MObject thisObject(thisMObject()); + MPlug plgRigidBody(thisObject, ia_rigidBody); + MObject update; + //force evaluation of the rigidBody + plgRigidBody.getValue(update); + + rigid_body_t::pointer rigid_body; + if(plgRigidBody.isConnected()) { + MPlugArray connections; + plgRigidBody.connectedTo(connections, true, true); + if(connections.length() != 0) { + MFnDependencyNode fnNode(connections[0].node()); + if(fnNode.typeId() == rigidBodyNode::typeId) { + rigidBodyNode *pRigidBodyNode = static_cast(fnNode.userNode()); + rigid_body = pRigidBodyNode->rigid_body(); + } else { + std::cout << "nailConstraintNode connected to a non-rigidbody node!" << std::endl; + } + } + } + + if(rigid_body) { + //not connected to a rigid body, put a default one + constraint_t::pointer constraint = static_cast(m_constraint); + solver_t::remove_constraint(constraint); + m_constraint = solver_t::create_nail_constraint(rigid_body); + constraint = static_cast(m_constraint); + solver_t::add_constraint(constraint); + } + + data.outputValue(ca_constraint).set(true); + data.setClean(plug); +} + + +void nailConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data) +{ + // std::cout << "nailConstraintNode::computeWorldMatrix" << std::endl; + + MObject thisObject(thisMObject()); + MFnDagNode fnDagNode(thisObject); + + MObject update; + MPlug(thisObject, ca_constraint).getValue(update); + MPlug(thisObject, ca_constraintParam).getValue(update); + + + MStatus status; + + MFnTransform fnParentTransform(fnDagNode.parent(0, &status)); + + MVector mtranslation = fnParentTransform.getTranslation(MSpace::kTransform, &status); + + // MQuaternion mrotation; + // fnParentTransform.getRotation(mrotation, MSpace::kTransform); + + if(m_constraint) { + vec3f world_pivot; + m_constraint->get_world_pivot(world_pivot); + if(world_pivot[0] != float(mtranslation.x) || + world_pivot[1] != float(mtranslation.y) || + world_pivot[2] != float(mtranslation.z)) { + + mat4x4f xform; + m_constraint->rigid_body()->get_transform(xform); + vec4f pivot = prod(trans(xform), vec4f(mtranslation.x, mtranslation.y, mtranslation.z, 1.0)); + m_constraint->set_pivot(vec3f(pivot[0], pivot[1], pivot[2])); + } + } + + data.setClean(plug); +} + +void nailConstraintNode::computeConstraintParam(const MPlug& plug, MDataBlock& data) +{ + // std::cout << "nailConstraintNode::computeRigidBodyParam" << std::endl; + + MObject thisObject(thisMObject()); + MObject update; + + MPlug(thisObject, ca_constraint).getValue(update); + if(m_constraint) { + m_constraint->set_damping(data.inputValue(ia_damping).asDouble()); + } + + data.outputValue(ca_constraintParam).set(true); + data.setClean(plug); +} + +nail_constraint_t::pointer nailConstraintNode::constraint() +{ + // std::cout << "nailConstraintNode::rigid_body" << std::endl; + + MObject thisObject(thisMObject()); + MObject update; + MPlug(thisObject, ca_constraint).getValue(update); + MPlug(thisObject, ca_constraintParam).getValue(update); + + return m_constraint; +} + +void nailConstraintNode::update() +{ + MObject thisObject(thisMObject()); + + MObject update; + MPlug(thisObject, ca_constraint).getValue(update); + MPlug(thisObject, ca_constraintParam).getValue(update); + MPlug(thisObject, worldMatrix).elementByLogicalIndex(0).getValue(update); +} diff --git a/Extras/MayaPlugin/nailConstraintNode.h b/Extras/MayaPlugin/nailConstraintNode.h new file mode 100644 index 000000000..bda62bbad --- /dev/null +++ b/Extras/MayaPlugin/nailConstraintNode.h @@ -0,0 +1,94 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//nailConstraintNode.h + +#ifndef DYN_NAIL_CONSTRAINT_NODE_H +#define DYN_NAIL_CONSTRAINT_NODE_H + +#include +#include +#include + +#include "solver.h" + +class nailConstraintNode: public MPxLocatorNode +{ +public: + nailConstraintNode(); + virtual ~nailConstraintNode(); + + virtual bool setInternalValueInContext ( const MPlug & plug, + const MDataHandle & dataHandle, + MDGContext & ctx); + + // virtual MStatus setDependentsDirty ( const MPlug & plug, MPlugArray & plugArray); + + virtual MStatus compute( const MPlug& plug, MDataBlock& data ); + + virtual void draw( M3dView & view, const MDagPath & path, + M3dView::DisplayStyle style, + M3dView::DisplayStatus status ); + + + virtual bool isBounded() const ; + virtual MBoundingBox boundingBox() const; + + virtual bool excludeAsLocator() const { return false; } + virtual bool isTransparent() const { return false; } + + static void * creator(); + static MStatus initialize(); + +public: + + nail_constraint_t::pointer constraint(); + +public: + + //Attributes + static MObject ia_rigidBody; + static MObject ia_damping; + + static MObject ca_constraint; + static MObject ca_constraintParam; + +public: + static MTypeId typeId; + static MString typeName; + +private: + void update(); + void computeConstraint(const MPlug& plug, MDataBlock& data); + void computeConstraintParam(const MPlug& plug, MDataBlock& data); + void computeWorldMatrix(const MPlug& plug, MDataBlock& data); + +public: + static void nodeRemoved(MObject& node, void *clientData); + +private: + nail_constraint_t::pointer m_constraint; +}; + + + +#endif diff --git a/Extras/MayaPlugin/nail_constraint.h b/Extras/MayaPlugin/nail_constraint.h new file mode 100644 index 000000000..48fd6b273 --- /dev/null +++ b/Extras/MayaPlugin/nail_constraint.h @@ -0,0 +1,91 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//nail_constraint.h + +#ifndef DYN_NAIL_CONSTRAINT_H +#define DYN_NAIL_CONSTRAINT_H + +#include "shared_ptr.h" +#include "rigid_body.h" +#include "mathUtils.h" + +#include "constraint.h" +#include "nail_constraint_impl.h" + +class nail_constraint_t: public constraint_t +{ +public: + //typedefs + typedef shared_ptr pointer; + + // + rigid_body_t::pointer rigid_body() { return m_rigid_body; } + + // + void set_pivot(vec3f const& p) + { + nail_constraint_impl_t* nail_impl = dynamic_cast(impl()); + nail_impl->set_pivot(p); + } + + //local space pivot + void get_pivot(vec3f& p) const { + nail_constraint_impl_t const* nail_impl = dynamic_cast(impl()); + nail_impl->get_pivot(p); + } + + // + void get_world_pivot(vec3f& p) const { + nail_constraint_impl_t const* nail_impl = dynamic_cast(impl()); + nail_impl->get_world_pivot(p); + } + + // + void set_damping(float d) { + nail_constraint_impl_t* nail_impl = dynamic_cast(impl()); + nail_impl->set_damping(d); + } + + float damping() const { + nail_constraint_impl_t const* nail_impl = dynamic_cast(impl()); + return nail_impl->damping(); + } + +public: + virtual ~nail_constraint_t() {}; + +protected: + friend class solver_t; + nail_constraint_t(nail_constraint_impl_t* impl, rigid_body_t::pointer& rigid_body): + constraint_t(impl), + m_rigid_body(rigid_body) + { + } + +private: + rigid_body_t::pointer m_rigid_body; +}; + + + +#endif diff --git a/Extras/MayaPlugin/nail_constraint_impl.h b/Extras/MayaPlugin/nail_constraint_impl.h new file mode 100644 index 000000000..b44974a36 --- /dev/null +++ b/Extras/MayaPlugin/nail_constraint_impl.h @@ -0,0 +1,46 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//nail_constraint_impl.h + +#ifndef DYN_NAIL_CONSTRAINT_IMPL_H +#define DYN_NAIL_CONSTRAINT_IMPL_H + +#include "constraint_impl.h" + +class nail_constraint_impl_t: public constraint_impl_t +{ +public: + // + virtual void set_pivot(vec3f const& p) = 0; + virtual void get_pivot(vec3f& p) const = 0; + virtual void get_world_pivot(vec3f& p) const = 0; + + // + virtual void set_damping(float d) = 0; + virtual float damping() const = 0; + +public: + virtual ~nail_constraint_impl_t() {}; +}; + +#endif diff --git a/Extras/MayaPlugin/pluginMain.cpp b/Extras/MayaPlugin/pluginMain.cpp index d8fc7830a..50bd2dc2c 100644 --- a/Extras/MayaPlugin/pluginMain.cpp +++ b/Extras/MayaPlugin/pluginMain.cpp @@ -29,10 +29,12 @@ Written by: Nicola Candussi #include "rigidBodyNode.h" #include "rigidBodyArrayNode.h" #include "collisionShapeNode.h" +#include "nailConstraintNode.h" #include "dSolverNode.h" #include "dSolverCmd.h" #include "dRigidBodyCmd.h" #include "dRigidBodyArrayCmd.h" +#include "dNailConstraintCmd.h" #include "mvl/util.h" #include "colladaExport.h" @@ -63,7 +65,7 @@ MStatus initializePlugin( MObject obj ) MCHECKSTATUS(status,"registerFileTranslator COLLADA Physics export") -// + // status = plugin.registerNode( rigidBodyNode::typeName, rigidBodyNode::typeId, rigidBodyNode::creator, rigidBodyNode::initialize, @@ -87,6 +89,15 @@ MStatus initializePlugin( MObject obj ) MPxNode::kDependNode ); MCHECKSTATUS(status, "registering collisionShapeNode") + // + status = plugin.registerNode( nailConstraintNode::typeName, nailConstraintNode::typeId, + nailConstraintNode::creator, + nailConstraintNode::initialize, + MPxNode::kLocatorNode ); + MCHECKSTATUS(status, "registering nailConstraintNode") + MDGMessage::addNodeRemovedCallback(nailConstraintNode::nodeRemoved, nailConstraintNode::typeName); + + // status = plugin.registerNode( dSolverNode::typeName, dSolverNode::typeId, dSolverNode::creator, @@ -110,6 +121,11 @@ MStatus initializePlugin( MObject obj ) dRigidBodyArrayCmd::syntax); MCHECKSTATUS(status, "registering dRigidBodyArrayCmd") + status = plugin.registerCommand( dNailConstraintCmd::typeName, + dNailConstraintCmd::creator, + dNailConstraintCmd::syntax); + MCHECKSTATUS(status, "registering dNailConstraintCmd") + MGlobal::executeCommand( "source dynamicaUI.mel" ); MGlobal::executeCommand( "dynamicaUI_initialize" ); @@ -121,6 +137,9 @@ MStatus uninitializePlugin( MObject obj ) MStatus status; MFnPlugin plugin( obj ); + status = plugin.deregisterCommand(dNailConstraintCmd::typeName); + MCHECKSTATUS(status, "deregistering dNailConstraintCmd") + status = plugin.deregisterCommand(dRigidBodyArrayCmd::typeName); MCHECKSTATUS(status, "deregistering dRigidBodyArrayCmd") @@ -133,6 +152,9 @@ MStatus uninitializePlugin( MObject obj ) status = plugin.deregisterNode(dSolverNode::typeId); MCHECKSTATUS(status, "deregistering dSolverNode") + status = plugin.deregisterNode(nailConstraintNode::typeId); + MCHECKSTATUS(status, "deregistering nailConstraintNode") + status = plugin.deregisterNode(collisionShapeNode::typeId); MCHECKSTATUS(status, "deregistering collisionShapeNode") diff --git a/Extras/MayaPlugin/rigid_body_impl.h b/Extras/MayaPlugin/rigid_body_impl.h index 0b73d6694..cd8669d94 100644 --- a/Extras/MayaPlugin/rigid_body_impl.h +++ b/Extras/MayaPlugin/rigid_body_impl.h @@ -26,7 +26,6 @@ Written by: Nicola Candussi #ifndef DYN_RIGID_BODY_IMPL_H #define DYN_RIGID_BODY_IMPL_H -#include "rigid_body_impl.h" #include "mathUtils.h" class rigid_body_impl_t diff --git a/Extras/MayaPlugin/scripts/AEdNailConstraintTemplate.mel b/Extras/MayaPlugin/scripts/AEdNailConstraintTemplate.mel new file mode 100644 index 000000000..00cb1fc81 --- /dev/null +++ b/Extras/MayaPlugin/scripts/AEdNailConstraintTemplate.mel @@ -0,0 +1,39 @@ +/* +Bullet Continuous Collision Detection and Physics Library Maya Plugin +Copyright (c) 2008 Walt Disney Studios + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising +from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must +not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Written by: Nicola Candussi +*/ + +//AEdNailConstraintTemplate.mel + +global proc AEdNailConstraintTemplate( string $nodeName ) +{ + + editorTemplate -beginScrollLayout; + + editorTemplate -addControl damping; + editorTemplate -addControl inRigidBody; + + AEdependNodeTemplate $nodeName; + + editorTemplate -addExtraControls; + editorTemplate -endScrollLayout; + +} + diff --git a/Extras/MayaPlugin/scripts/dynamicaUI.mel b/Extras/MayaPlugin/scripts/dynamicaUI.mel index f5fa86b64..868dee250 100644 --- a/Extras/MayaPlugin/scripts/dynamicaUI.mel +++ b/Extras/MayaPlugin/scripts/dynamicaUI.mel @@ -308,6 +308,21 @@ global proc string dynamicaUI_createMainTab() } setParent ..; } + + frameLayout -collapsable true -label "Constraints" -borderStyle "in"; + { + rowLayout -nc 5; + { + string $createNailConstraintBtn = `iconTextButton -style "iconAndTextVertical" -label "Nail" + -width 100 -image1 "dynamicaCreateNailConstraint.xpm" -c ("dynamicaUI_createNailConstraint") + -ann "Create a nail constraint"`; + + + setParent ..; + } + setParent ..; + } + setParent ..; } return $mainForm; @@ -643,6 +658,28 @@ global proc dynamicaUI_createPassiveMeshRBArray() dynamicaUI_createRigidBodyArray(false, 1); } +global proc dynamicaUI_createNailConstraint() +{ + string $selection[] = `ls -selection -dag -leaf -showType -type "geometry"`; + + //create dSolver node if necessary + dSolver; + + string $newConstraints[]; + + for($i = 0; $i < size($selection) / 2; $i++) { + if($selection[$i * 2 + 1] == "dRigidBody") { + string $constraintNode = `dNailConstraint`; + connectAttr ($selection[$i * 2] + ".message") ($constraintNode + ".inRigidBody"); + string $constraintTransforms[] = `listRelatives -parent $constraintNode`; + $newConstraints[$i] = $constraintTransforms[0]; + } + } + + select -r $newConstraints; + +} + global proc dyn_demo1() { dynamicaUI_createActiveSphereRBArray(); diff --git a/Extras/MayaPlugin/solver.cpp b/Extras/MayaPlugin/solver.cpp index 4459fa292..ebc976b7c 100644 --- a/Extras/MayaPlugin/solver.cpp +++ b/Extras/MayaPlugin/solver.cpp @@ -27,6 +27,7 @@ Written by: Nicola Candussi shared_ptr solver_t::m_impl; std::set solver_t::m_rigid_bodies; +std::set solver_t::m_constraints; shared_ptr solver_t::get_solver() { @@ -84,6 +85,12 @@ rigid_body_t::pointer solver_t::create_rigid_body(collision_shape_t::pointer& cs return rigid_body_t::pointer(new rigid_body_t(m_impl->create_rigid_body(cs->impl()), cs)); } +nail_constraint_t::pointer solver_t::create_nail_constraint(rigid_body_t::pointer& rb, vec3f const& pivot) +{ + return nail_constraint_t::pointer(new nail_constraint_t(m_impl->create_nail_constraint(rb->impl(), pivot), rb)); +} + + //add/remove from world void solver_t::add_rigid_body(rigid_body_t::pointer& rb) { @@ -114,6 +121,35 @@ void solver_t::remove_all_rigid_bodies() m_rigid_bodies.clear(); } +void solver_t::add_constraint(constraint_t::pointer& c) +{ + if(c) { + if(m_constraints.find(c) == m_constraints.end()) { + m_constraints.insert(c); + m_impl->add_constraint(c->impl()); + } + } +} + +void solver_t::remove_constraint(constraint_t::pointer& c) +{ + if(c) { + if(m_constraints.find(c) != m_constraints.end()) { + m_impl->remove_constraint(c->impl()); + m_constraints.erase(c); + } + } +} + +void solver_t::remove_all_constraints() +{ + std::set::iterator it; + for(it = m_constraints.begin(); it != m_constraints.end(); ++it) { + m_impl->remove_constraint(const_cast((*it).get())->impl()); + } + m_constraints.clear(); +} + void solver_t::set_gravity(vec3f const& g) { m_impl->set_gravity(g); diff --git a/Extras/MayaPlugin/solver.h b/Extras/MayaPlugin/solver.h index 479ff3be6..818fec989 100644 --- a/Extras/MayaPlugin/solver.h +++ b/Extras/MayaPlugin/solver.h @@ -38,6 +38,7 @@ Written by: Nicola Candussi #include "box_shape.h" #include "convex_hull_shape.h" #include "mesh_shape.h" +#include "nail_constraint.h" #include "solver_impl.h" class solver_t @@ -63,11 +64,18 @@ public: static rigid_body_t::pointer create_rigid_body(collision_shape_t::pointer& cs); + static nail_constraint_t::pointer create_nail_constraint(rigid_body_t::pointer& rb, vec3f const& pivot = vec3f(0, 0, 0)); + //add/remove from world static void add_rigid_body(rigid_body_t::pointer& rb); static void remove_rigid_body(rigid_body_t::pointer& rb); static void remove_all_rigid_bodies(); + //add/remove from world + static void add_constraint(constraint_t::pointer& c); + static void remove_constraint(constraint_t::pointer& c); + static void remove_all_constraints(); + // static void set_gravity(vec3f const& g); @@ -82,6 +90,7 @@ public: private: static shared_ptr m_impl; static std::set m_rigid_bodies; + static std::set m_constraints; }; diff --git a/Extras/MayaPlugin/solver_impl.h b/Extras/MayaPlugin/solver_impl.h index 24616b651..40996a401 100644 --- a/Extras/MayaPlugin/solver_impl.h +++ b/Extras/MayaPlugin/solver_impl.h @@ -26,6 +26,7 @@ Written by: Nicola Candussi #define DYN_SOLVER_IMPL_H #include "rigid_body_impl.h" +#include "nail_constraint_impl.h" #include "collision_shape_impl.h" class solver_impl_t @@ -46,11 +47,17 @@ public: unsigned int const *indices, size_t num_indices) = 0; virtual rigid_body_impl_t* create_rigid_body(collision_shape_impl_t* cs) = 0; - + + virtual nail_constraint_impl_t* create_nail_constraint(rigid_body_impl_t* rb, vec3f const& pivot) = 0; + virtual void add_rigid_body(rigid_body_impl_t* rb) = 0; virtual void remove_rigid_body(rigid_body_impl_t* rb) = 0; + virtual void add_constraint(constraint_impl_t* rb) = 0; + + virtual void remove_constraint(constraint_impl_t* rb) = 0; + virtual void set_gravity(vec3f const& g) = 0; virtual void set_split_impulse(bool enabled) = 0;