+ bugfix in btAlignedObjectArray, not calling destructors on resize to smaller array.

Thanks Benoit for pointing this out, and bugfix: http://code.google.com/p/bullet/issues/detail?id=218

+ Added point to point, hinge, slider and generic 6dof constraints to Maya Dynamica plugin
Thanks to Herbert Law for the constribution: http://code.google.com/p/bullet/issues/detail?id=221
This commit is contained in:
erwin.coumans
2009-05-06 19:55:05 +00:00
parent f3c3d2f156
commit d9c4529a26
56 changed files with 5851 additions and 1237 deletions

View File

@@ -0,0 +1,125 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//bt_hinge_constraint.h
#ifndef DYN_BT_HINGE_CONSTRAINT_H
#define DYN_BT_HINGE_CONSTRAINT_H
#include "bt_constraint.h"
#include "hinge_constraint_impl.h"
class bt_hinge_constraint_t: public bt_constraint_t, public hinge_constraint_impl_t {
public:
virtual void set_damping(float d) {
// btHingeConstraint* p2pc = static_cast<btHingeConstraint*>(m_constraint.get());
// p2pc->m_setting.m_damping = d;
}
virtual void set_limit(float lower, float upper, float softness, float bias_factor, float relaxation_factor) {
btHingeConstraint* hinge = static_cast<btHingeConstraint*>(m_constraint.get());
hinge->setLimit(lower, upper, softness, bias_factor, relaxation_factor);
}
virtual void set_axis(vec3f const &p) {
btHingeConstraint* hinge = static_cast<btHingeConstraint*>(m_constraint.get());
btVector3 axis(p[0], p[1], p[2]);
hinge->setAxis(axis);
}
virtual float damping() const {
// btHingeConstraint const* hc = static_cast<btHingeConstraint const*>(m_constraint.get());
// return hc->m_setting.m_damping;
return 0;
}
//
virtual void set_pivot(vec3f const &p) {
/* btHingeConstraint* p2pc = static_cast<btHingeConstraint*>(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 {
/* btHingeConstraint const* hc = static_cast<btHingeConstraint const*>(m_constraint.get());
p[0] = hc->getPivotInA().x();
p[1] = hc->getPivotInA().y();
p[2] = hc->getPivotInA().z();
*/ }
virtual void get_world_pivot(vec3f &p) const {
/* btHingeConstraint const* hc = static_cast<btHingeConstraint const*>(m_constraint.get());
p[0] = hc->getPivotInB().x();
p[1] = hc->getPivotInB().y();
p[2] = hc->getPivotInB().z();
*/ }
virtual void set_world(vec3f const &p) {
btHingeConstraint* hc = static_cast<btHingeConstraint*>(m_constraint.get());
btVector3 world(p[0], p[1], p[2]);
btVector3 pivotA = hc->getRigidBodyA().getWorldTransform().inverse() (world);
hc->getAFrame().getOrigin() = pivotA;
hc->getBFrame().getOrigin() = world;
// p2pc->buildJacobian();
}
virtual void get_world(vec3f &p) const {
btHingeConstraint const* hc = static_cast<btHingeConstraint const*>(m_constraint.get());
p[0] = hc->getBFrame().getOrigin().x();
p[1] = hc->getBFrame().getOrigin().y();
p[2] = hc->getBFrame().getOrigin().z();
}
virtual void enable_motor(bool enable, float velocity, float impulse) {
btHingeConstraint* hinge = static_cast<btHingeConstraint*>(m_constraint.get());
hinge->enableAngularMotor(enable, velocity, impulse);
}
virtual void update_constraint()
{
btHingeConstraint* hc = static_cast<btHingeConstraint*>(m_constraint.get());
btVector3 world = hc->getBFrame().getOrigin();
btVector3 pivotA = hc->getRigidBodyA().getWorldTransform().inverse() (world);
hc->getAFrame().getOrigin() = pivotA;
}
protected:
friend class bt_solver_t;
bt_hinge_constraint_t(rigid_body_impl_t* rb, vec3f const& pivot):
hinge_constraint_impl_t()
{
btRigidBody& bt_body = *static_cast<bt_rigid_body_t*>(rb)->body();
btVector3 pivotA = bt_body.getCenterOfMassPosition();
btVector3 btAxisA( 0.0f, 1.0f, 0.0f ); // pointing upwards, aka Y-axis
btHingeConstraint * hinge = new btHingeConstraint(bt_body, -pivotA, btAxisA);
m_constraint.reset(hinge);
rb->add_constraint(this);
}
private:
};
#endif //DYN_BT_HINGE_CONSTRAINT_H

View File

@@ -0,0 +1,106 @@
/*
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 <nicola@fluidinteractive.com>
*/
//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<btPoint2PointConstraint*>(m_constraint.get());
p2pc->m_setting.m_damping = d;
}
virtual float damping() const {
btPoint2PointConstraint const* p2pc = static_cast<btPoint2PointConstraint const*>(m_constraint.get());
return p2pc->m_setting.m_damping;
}
//
virtual void set_pivotA(vec3f const &p) {
btPoint2PointConstraint* p2pc = static_cast<btPoint2PointConstraint*>(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_pivotA(vec3f &p) const {
btPoint2PointConstraint const* p2pc = static_cast<btPoint2PointConstraint const*>(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<btPoint2PointConstraint const*>(m_constraint.get());
p[0] = p2pc->getPivotInB().x();
p[1] = p2pc->getPivotInB().y();
p[2] = p2pc->getPivotInB().z();
}
virtual void set_world(vec3f const &p) {
btPoint2PointConstraint* p2pc = static_cast<btPoint2PointConstraint*>(m_constraint.get());
btVector3 world(p[0], p[1], p[2]);
btVector3 pivotA = p2pc->getRigidBodyA().getWorldTransform().inverse() (world);
p2pc->setPivotA(pivotA);
p2pc->setPivotB(world);
p2pc->buildJacobian();
}
virtual void get_world(vec3f &p) const {
btPoint2PointConstraint const* p2pc = static_cast<btPoint2PointConstraint const*>(m_constraint.get());
p[0] = p2pc->getPivotInB().x();
p[1] = p2pc->getPivotInB().y();
p[2] = p2pc->getPivotInB().z();
}
virtual void update_constraint()
{
btPoint2PointConstraint* p2pc = static_cast<btPoint2PointConstraint*>(m_constraint.get());
btVector3 world = p2pc->getPivotInB();
btVector3 pivotA = p2pc->getRigidBodyA().getWorldTransform().inverse() (world);
p2pc->setPivotA(pivotA);
}
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<bt_rigid_body_t*>(rb)->body();
btVector3 pivotA = bt_body.getCenterOfMassPosition();
m_constraint.reset(new btPoint2PointConstraint(bt_body, -pivotA));
rb->add_constraint(this);
}
private:
};
#endif

View File

@@ -0,0 +1,123 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//bt_sixdof_constraint.h
#ifndef DYN_BT_SIXDOF_CONSTRAINT_H
#define DYN_BT_SIXDOF_CONSTRAINT_H
#include "bt_constraint.h"
#include "sixdof_constraint_impl.h"
class bt_sixdof_constraint_t: public bt_constraint_t, public sixdof_constraint_impl_t {
public:
virtual void set_damping(float d) {
// btGeneric6DofConstraint* p2pc = static_cast<btGeneric6DofConstraint*>(m_constraint.get());
// p2pc->m_setting.m_damping = d;
}
virtual void set_LinLimit(float lower, float upper) {
btGeneric6DofConstraint* sixdof = static_cast<btGeneric6DofConstraint*>(m_constraint.get());
// sixdof->setLowerLinLimit(lower);
// sixdof->setUpperLinLimit(upper);
}
virtual void set_AngLimit(float lower, float upper) {
btGeneric6DofConstraint* sixdof = static_cast<btGeneric6DofConstraint*>(m_constraint.get());
// sixdof->setLowerAngLimit(lower);
// sixdof->setUpperAngLimit(upper);
}
virtual float damping() const {
// btGeneric6DofConstraint const* hc = static_cast<btGeneric6DofConstraint const*>(m_constraint.get());
// return hc->m_setting.m_damping;
return 0;
}
//
virtual void set_pivot(vec3f const &p) {
/* btGeneric6DofConstraint* p2pc = static_cast<btGeneric6DofConstraint*>(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 {
/* btGeneric6DofConstraint const* hc = static_cast<btGeneric6DofConstraint const*>(m_constraint.get());
p[0] = hc->getPivotInA().x();
p[1] = hc->getPivotInA().y();
p[2] = hc->getPivotInA().z();
*/ }
virtual void get_world_pivot(vec3f &p) const {
/* btGeneric6DofConstraint const* hc = static_cast<btGeneric6DofConstraint const*>(m_constraint.get());
p[0] = hc->getPivotInB().x();
p[1] = hc->getPivotInB().y();
p[2] = hc->getPivotInB().z();
*/ }
virtual void set_world(vec3f const &p) {
btGeneric6DofConstraint* constraint = static_cast<btGeneric6DofConstraint*>(m_constraint.get());
btTransform framInA = constraint->getRigidBodyA().getCenterOfMassTransform().inverse();
btTransform framInB = constraint->getRigidBodyB().getCenterOfMassTransform().inverse();
constraint->getFrameOffsetA() = framInA;
constraint->getFrameOffsetB() = framInB;
world = p;
}
virtual void get_world(vec3f &p) const {
/* btGeneric6DofConstraint const* hc = static_cast<btGeneric6DofConstraint const*>(m_constraint.get());
p[0] = hc->getFrameOffsetB().getOrigin().x();
p[1] = hc->getFrameOffsetB().getOrigin().y();
p[2] = hc->getFrameOffsetB().getOrigin().z();
*/ p = world;
}
virtual void update_constraint()
{
btGeneric6DofConstraint* constraint = static_cast<btGeneric6DofConstraint*>(m_constraint.get());
constraint->getFrameOffsetA() = constraint->getRigidBodyA().getCenterOfMassTransform().inverse();
constraint->getFrameOffsetB() = constraint->getRigidBodyB().getCenterOfMassTransform().inverse();
}
protected:
friend class bt_solver_t;
vec3f world;
bt_sixdof_constraint_t(rigid_body_impl_t* rbA, vec3f const& pivotA, rigid_body_impl_t* rbB, vec3f const& pivotB):
sixdof_constraint_impl_t()
{
btRigidBody& bt_bodyA = *static_cast<bt_rigid_body_t*>(rbA)->body();
btRigidBody& bt_bodyB = *static_cast<bt_rigid_body_t*>(rbB)->body();
btTransform framInA = bt_bodyA.getCenterOfMassTransform().inverse();
btTransform framInB = bt_bodyB.getCenterOfMassTransform().inverse();
btGeneric6DofConstraint * sixdof = new btGeneric6DofConstraint(bt_bodyA, bt_bodyB, framInA, framInB, true);
m_constraint.reset(sixdof);
rbA->add_constraint(this);
}
private:
};
#endif //DYN_BT_SIXDOF_CONSTRAINT_H

View File

@@ -0,0 +1,128 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//bt_slider_constraint.h
#ifndef DYN_BT_SLIDER_CONSTRAINT_H
#define DYN_BT_SLIDER_CONSTRAINT_H
#include "bt_constraint.h"
#include "slider_constraint_impl.h"
class bt_slider_constraint_t: public bt_constraint_t, public slider_constraint_impl_t {
public:
virtual void set_damping(float d) {
// btSliderConstraint* p2pc = static_cast<btSliderConstraint*>(m_constraint.get());
// p2pc->m_setting.m_damping = d;
}
virtual void set_LinLimit(float lower, float upper) {
btSliderConstraint* slider = static_cast<btSliderConstraint*>(m_constraint.get());
slider->setLowerLinLimit(lower);
slider->setUpperLinLimit(upper);
}
virtual void set_AngLimit(float lower, float upper) {
btSliderConstraint* slider = static_cast<btSliderConstraint*>(m_constraint.get());
slider->setLowerAngLimit(lower);
slider->setUpperAngLimit(upper);
}
virtual float damping() const {
// btSliderConstraint const* hc = static_cast<btSliderConstraint const*>(m_constraint.get());
// return hc->m_setting.m_damping;
return 0;
}
//
virtual void set_pivot(vec3f const &p) {
/* btSliderConstraint* p2pc = static_cast<btSliderConstraint*>(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 {
/* btSliderConstraint const* hc = static_cast<btSliderConstraint const*>(m_constraint.get());
p[0] = hc->getPivotInA().x();
p[1] = hc->getPivotInA().y();
p[2] = hc->getPivotInA().z();
*/ }
virtual void get_world_pivot(vec3f &p) const {
/* btSliderConstraint const* hc = static_cast<btSliderConstraint const*>(m_constraint.get());
p[0] = hc->getPivotInB().x();
p[1] = hc->getPivotInB().y();
p[2] = hc->getPivotInB().z();
*/ }
virtual void set_world(vec3f const &p) {
/* btSliderConstraint* hc = static_cast<btSliderConstraint*>(m_constraint.get());
btVector3 world(p[0], p[1], p[2]);
btVector3 pivotA = hc->getRigidBodyA().getWorldTransform().inverse() (world);
hc->getFrameOffsetA().getOrigin() = pivotA;
hc->getFrameOffsetB().getOrigin() = world;
*/ // p2pc->buildJacobian();
world = p;
}
virtual void get_world(vec3f &p) const {
/* btSliderConstraint const* hc = static_cast<btSliderConstraint const*>(m_constraint.get());
p[0] = hc->getFrameOffsetB().getOrigin().x();
p[1] = hc->getFrameOffsetB().getOrigin().y();
p[2] = hc->getFrameOffsetB().getOrigin().z();
*/ p = world;
}
virtual void update_constraint()
{
/* btRigidBody& bt_bodyA = *static_cast<bt_rigid_body_t*>(rbA)->body();
btRigidBody& bt_bodyB = *static_cast<bt_rigid_body_t*>(rbB)->body();
btTransform framInA = btTransform::getIdentity();
btTransform framInB = btTransform::getIdentity();
btSliderConstraint* slider = static_cast<btSliderConstraint*>(m_constraint.get());
slider->getFrameOffsetA();
*/ }
protected:
friend class bt_solver_t;
vec3f world;
bt_slider_constraint_t(rigid_body_impl_t* rbA, vec3f const& pivotA, rigid_body_impl_t* rbB, vec3f const& pivotB):
slider_constraint_impl_t()
{
btRigidBody& bt_bodyA = *static_cast<bt_rigid_body_t*>(rbA)->body();
btRigidBody& bt_bodyB = *static_cast<bt_rigid_body_t*>(rbB)->body();
btTransform framInA = btTransform::getIdentity();
btTransform framInB = btTransform::getIdentity();
btSliderConstraint * slider = new btSliderConstraint(bt_bodyA, bt_bodyB, framInA, framInB, true);
m_constraint.reset(slider);
rbA->add_constraint(this);
}
private:
};
#endif //DYN_BT_SLIDER_CONSTRAINT_H

View File

@@ -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 <nicola@fluidinteractive.com>
*/
//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<constraint_t> 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<constraint_impl_t> m_impl;
};
#endif

View File

@@ -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 <nicola@fluidinteractive.com>
*/
//constraint_impl.h
#ifndef DYN_CONSTRAINT_IMPL_H
#define DYN_CONSTRAINT_IMPL_H
class constraint_impl_t
{
public:
//
public:
virtual ~constraint_impl_t() {};
};
#endif

View File

@@ -0,0 +1,133 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//dHingeConstraintCmd.cpp
#include <maya/MGlobal.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MSyntax.h>
#include "hingeConstraintNode.h"
#include "dHingeConstraintCmd.h"
MString dHingeConstraintCmd::typeName("dHingeConstraint");
dHingeConstraintCmd::dHingeConstraintCmd()
: m_argDatabase(0),
m_dagModifier(0)
{
}
dHingeConstraintCmd::~dHingeConstraintCmd()
{
if (m_argDatabase) {
delete m_argDatabase;
}
if (m_dagModifier) {
delete m_dagModifier;
}
}
void *
dHingeConstraintCmd::creator()
{
return new dHingeConstraintCmd;
}
MSyntax
dHingeConstraintCmd::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
dHingeConstraintCmd::doIt(const MArgList &args)
{
MStatus stat;
m_argDatabase = new MArgDatabase(syntax(), args, &stat);
if (stat == MS::kFailure) {
return stat;
}
return redoIt();
}
MStatus
dHingeConstraintCmd::undoIt()
{
MGlobal::setActiveSelectionList(m_undoSelectionList);
if (m_dagModifier) {
m_dagModifier->undoIt();
delete m_dagModifier;
m_dagModifier = 0;
}
return MS::kSuccess;
}
MStatus
dHingeConstraintCmd::redoIt()
{
MGlobal::getActiveSelectionList(m_undoSelectionList);
MString name;
if (m_argDatabase->isFlagSet("-name")) {
m_argDatabase->getFlagArgument("-name", 0, name);
}
if (!name.length()) {
name = "dHingeConstraint";
}
m_dagModifier = new MDagModifier;
MObject parentObj = m_dagModifier->createNode("transform");
m_dagModifier->renameNode(parentObj, name + "#");
m_dagModifier->doIt();
MObject dConstraintObj = m_dagModifier->createNode(hingeConstraintNode::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;
}

View File

@@ -0,0 +1,58 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//dHingeConstraintCmd.h
#ifndef DYN_HINGE_CONSTRAINT_CMD_H
#define DYN_HINGE_CONSTRAINT_CMD_H
#include <maya/MArgDatabase.h>
#include <maya/MDagModifier.h>
#include <maya/MSelectionList.h>
#include <maya/MPxCommand.h>
class dHingeConstraintCmd : public MPxCommand
{
public:
dHingeConstraintCmd();
virtual ~dHingeConstraintCmd();
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 //DYN_HINGE_CONSTRAINT_CMD_H

View File

@@ -0,0 +1,133 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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 <nicola@fluidinteractive.com>
*/
//dNailConstraintCmd.cpp
#include <maya/MGlobal.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MSyntax.h>
#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;
}

View File

@@ -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 <nicola@fluidinteractive.com>
*/
//dNailConstraintCmd.h
#ifndef DYN_NAIL_CONSTRAINT_CMD_H
#define DYN_NAIL_CONSTRAINT_CMD_H
#include <maya/MArgDatabase.h>
#include <maya/MDagModifier.h>
#include <maya/MSelectionList.h>
#include <maya/MPxCommand.h>
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

View File

@@ -0,0 +1,133 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//dSliderConstraintCmd.cpp
#include <maya/MGlobal.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MSyntax.h>
#include "sliderConstraintNode.h"
#include "dSliderConstraintCmd.h"
MString dSliderConstraintCmd::typeName("dSliderConstraint");
dSliderConstraintCmd::dSliderConstraintCmd()
: m_argDatabase(0),
m_dagModifier(0)
{
}
dSliderConstraintCmd::~dSliderConstraintCmd()
{
if (m_argDatabase) {
delete m_argDatabase;
}
if (m_dagModifier) {
delete m_dagModifier;
}
}
void *
dSliderConstraintCmd::creator()
{
return new dSliderConstraintCmd;
}
MSyntax
dSliderConstraintCmd::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
dSliderConstraintCmd::doIt(const MArgList &args)
{
MStatus stat;
m_argDatabase = new MArgDatabase(syntax(), args, &stat);
if (stat == MS::kFailure) {
return stat;
}
return redoIt();
}
MStatus
dSliderConstraintCmd::undoIt()
{
MGlobal::setActiveSelectionList(m_undoSelectionList);
if (m_dagModifier) {
m_dagModifier->undoIt();
delete m_dagModifier;
m_dagModifier = 0;
}
return MS::kSuccess;
}
MStatus
dSliderConstraintCmd::redoIt()
{
MGlobal::getActiveSelectionList(m_undoSelectionList);
MString name;
if (m_argDatabase->isFlagSet("-name")) {
m_argDatabase->getFlagArgument("-name", 0, name);
}
if (!name.length()) {
name = "dSliderConstraint";
}
m_dagModifier = new MDagModifier;
MObject parentObj = m_dagModifier->createNode("transform");
m_dagModifier->renameNode(parentObj, name + "#");
m_dagModifier->doIt();
MObject dConstraintObj = m_dagModifier->createNode(sliderConstraintNode::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;
}

View File

@@ -0,0 +1,58 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//dSliderConstraintCmd.h
#ifndef DYN_SLIDER_CONSTRAINT_CMD_H
#define DYN_SLIDER_CONSTRAINT_CMD_H
#include <maya/MArgDatabase.h>
#include <maya/MDagModifier.h>
#include <maya/MSelectionList.h>
#include <maya/MPxCommand.h>
class dSliderConstraintCmd : public MPxCommand
{
public:
dSliderConstraintCmd();
virtual ~dSliderConstraintCmd();
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 //DYN_SLIDER_CONSTRAINT_CMD_H

View File

@@ -0,0 +1,133 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//dSixdofConstraintCmd.cpp
#include <maya/MGlobal.h>
#include <maya/MItDependencyNodes.h>
#include <maya/MSyntax.h>
#include "sixdofConstraintNode.h"
#include "dSixdofConstraintCmd.h"
MString dSixdofConstraintCmd::typeName("dSixdofConstraint");
dSixdofConstraintCmd::dSixdofConstraintCmd()
: m_argDatabase(0),
m_dagModifier(0)
{
}
dSixdofConstraintCmd::~dSixdofConstraintCmd()
{
if (m_argDatabase) {
delete m_argDatabase;
}
if (m_dagModifier) {
delete m_dagModifier;
}
}
void *
dSixdofConstraintCmd::creator()
{
return new dSixdofConstraintCmd;
}
MSyntax
dSixdofConstraintCmd::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
dSixdofConstraintCmd::doIt(const MArgList &args)
{
MStatus stat;
m_argDatabase = new MArgDatabase(syntax(), args, &stat);
if (stat == MS::kFailure) {
return stat;
}
return redoIt();
}
MStatus
dSixdofConstraintCmd::undoIt()
{
MGlobal::setActiveSelectionList(m_undoSelectionList);
if (m_dagModifier) {
m_dagModifier->undoIt();
delete m_dagModifier;
m_dagModifier = 0;
}
return MS::kSuccess;
}
MStatus
dSixdofConstraintCmd::redoIt()
{
MGlobal::getActiveSelectionList(m_undoSelectionList);
MString name;
if (m_argDatabase->isFlagSet("-name")) {
m_argDatabase->getFlagArgument("-name", 0, name);
}
if (!name.length()) {
name = "dSixdofConstraint";
}
m_dagModifier = new MDagModifier;
MObject parentObj = m_dagModifier->createNode("transform");
m_dagModifier->renameNode(parentObj, name + "#");
m_dagModifier->doIt();
MObject dConstraintObj = m_dagModifier->createNode(sixdofConstraintNode::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;
}

View File

@@ -0,0 +1,58 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//dSixdofConstraintCmd.h
#ifndef DYN_SIXDOF_CONSTRAINT_CMD_H
#define DYN_SIXDOF_CONSTRAINT_CMD_H
#include <maya/MArgDatabase.h>
#include <maya/MDagModifier.h>
#include <maya/MSelectionList.h>
#include <maya/MPxCommand.h>
class dSixdofConstraintCmd : public MPxCommand
{
public:
dSixdofConstraintCmd();
virtual ~dSixdofConstraintCmd();
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 //DYN_SIXDOF_CONSTRAINT_CMD_H

View File

@@ -0,0 +1,443 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//hingeConstraintNode.cpp
#include <maya/MFnDependencyNode.h>
#include <maya/MPlugArray.h>
#include <maya/MFnMessageAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MMatrix.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnTransform.h>
#include <maya/MQuaternion.h>
#include <maya/MEulerRotation.h>
#include <maya/MVector.h>
#include "rigidBodyNode.h"
#include "hingeConstraintNode.h"
#include "mayaUtils.h"
#include "solver.h"
MTypeId hingeConstraintNode::typeId(0x10033B);
MString hingeConstraintNode::typeName("dHingeConstraint");
MObject hingeConstraintNode::ia_rigidBody;
MObject hingeConstraintNode::ia_damping;
MObject hingeConstraintNode::ia_lowerLimit;
MObject hingeConstraintNode::ia_upperLimit;
MObject hingeConstraintNode::ia_limitSoftness;
MObject hingeConstraintNode::ia_biasFactor;
MObject hingeConstraintNode::ia_relaxationFactor;
MObject hingeConstraintNode::ia_hingeAxis;
MObject hingeConstraintNode::ia_enableAngularMotor;
MObject hingeConstraintNode::ia_motorTargetVelocity;
MObject hingeConstraintNode::ia_maxMotorImpulse;
MObject hingeConstraintNode::ca_constraint;
MObject hingeConstraintNode::ca_constraintParam;
MStatus hingeConstraintNode::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")
ia_lowerLimit = fnNumericAttr.create("lowerLimit", "llmt", MFnNumericData::kDouble, -1.57, &status);
MCHECKSTATUS(status, "creating lower limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_lowerLimit);
MCHECKSTATUS(status, "adding lower limit attribute")
ia_upperLimit = fnNumericAttr.create("upperLimit", "ulmt", MFnNumericData::kDouble, 1.57, &status);
MCHECKSTATUS(status, "creating upper limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_upperLimit);
MCHECKSTATUS(status, "adding upper limit attribute")
ia_limitSoftness = fnNumericAttr.create("limitSoftness", "lmSo", MFnNumericData::kDouble, 0.9, &status);
MCHECKSTATUS(status, "creating limitSoftness attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_limitSoftness);
MCHECKSTATUS(status, "adding limitSoftness attribute")
ia_biasFactor = fnNumericAttr.create("biasFactor", "biFa", MFnNumericData::kDouble, 0.3, &status);
MCHECKSTATUS(status, "creating biasFactor attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_biasFactor);
MCHECKSTATUS(status, "adding biasFactor attribute")
ia_relaxationFactor = fnNumericAttr.create("relaxationFactor", "reFa", MFnNumericData::kDouble, 1.0, &status);
MCHECKSTATUS(status, "creating relaxationFactor attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_relaxationFactor);
MCHECKSTATUS(status, "adding relaxationFactor attribute")
ia_hingeAxis = fnNumericAttr.createPoint("hingeAxis", "hgAx", &status);
MCHECKSTATUS(status, "creating hingeAxis attribute")
status = addAttribute(ia_hingeAxis);
MCHECKSTATUS(status, "adding hingeAxis attribute")
//------------------------------------------------------------------------------
ia_enableAngularMotor = fnNumericAttr.create("enableAngularMotor", "enAM", MFnNumericData::kBoolean, false, &status);
MCHECKSTATUS(status, "creating enableAngularMotor attribute")
status = addAttribute(ia_enableAngularMotor);
MCHECKSTATUS(status, "adding enableAngularMotor attribute")
ia_motorTargetVelocity = fnNumericAttr.create("motorTargetVelocity", "mTV", MFnNumericData::kDouble, 1, &status);
MCHECKSTATUS(status, "creating motorTargetVelocity attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_motorTargetVelocity);
MCHECKSTATUS(status, "adding motorTargetVelocity attribute")
ia_maxMotorImpulse = fnNumericAttr.create("maxMotorImpulse", "mMI", MFnNumericData::kDouble, 1, &status);
MCHECKSTATUS(status, "creating maxMotorImpulse attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_maxMotorImpulse);
MCHECKSTATUS(status, "adding maxMotorImpulse 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)")
status = attributeAffects(ia_lowerLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_lowerLimit, ca_constraintParam)")
status = attributeAffects(ia_upperLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_upperLimit, ca_constraintParam)")
status = attributeAffects(ia_limitSoftness, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_limitSoftness, ca_constraintParam)")
status = attributeAffects(ia_biasFactor, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_biasFactor, ca_constraintParam)")
status = attributeAffects(ia_relaxationFactor, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_relaxationFactor, ca_constraintParam)")
status = attributeAffects(ia_hingeAxis, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_hingeAxis, ca_constraintParam)")
status = attributeAffects(ia_enableAngularMotor, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_enableAngularMotor, ca_constraintParam)")
status = attributeAffects(ia_motorTargetVelocity, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_motorTargetVelocity, ca_constraintParam)")
status = attributeAffects(ia_maxMotorImpulse, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_maxMotorImpulse, ca_constraintParam)")
return MS::kSuccess;
}
hingeConstraintNode::hingeConstraintNode()
{
// std::cout << "hingeConstraintNode::hingeConstraintNode" << std::endl;
}
hingeConstraintNode::~hingeConstraintNode()
{
// std::cout << "hingeConstraintNode::~hingeConstraintNode" << std::endl;
}
void hingeConstraintNode::nodeRemoved(MObject& node, void *clientData)
{
// std::cout << "hingeConstraintNode::nodeRemoved" << std::endl;
MFnDependencyNode fnNode(node);
hingeConstraintNode *pNode = static_cast<hingeConstraintNode*>(fnNode.userNode());
constraint_t::pointer constraint = static_cast<constraint_t::pointer>(pNode->m_constraint);
solver_t::remove_constraint(constraint);
}
void* hingeConstraintNode::creator()
{
return new hingeConstraintNode();
}
bool hingeConstraintNode::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 hingeConstraintNode::compute(const MPlug& plug, MDataBlock& data)
{
//std::cout << "hingeConstraintNode::compute: " << plug.name() << std::endl;
//MTime time = data.inputValue( hingeConstraintNode::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 hingeConstraintNode::draw( M3dView & view, const MDagPath &path,
M3dView::DisplayStyle style,
M3dView::DisplayStatus status )
{
// std::cout << "hingeConstraintNode::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);
}
vec3f pos;
if (m_constraint) {
vec3f world;
m_constraint->get_world(world);
vec3f posA;
quatf rotA;
m_constraint->rigid_body()->get_transform(posA, rotA);
pos = posA - world;
}
glBegin(GL_LINES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(pos[0], pos[1], pos[2]);
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 hingeConstraintNode::isBounded() const
{
//return true;
return false;
}
MBoundingBox hingeConstraintNode::boundingBox() const
{
// std::cout << "hingeConstraintNode::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 hingeConstraintNode::computeConstraint(const MPlug& plug, MDataBlock& data)
{
// std::cout << "hingeConstraintNode::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<rigidBodyNode*>(fnNode.userNode());
rigid_body = pRigidBodyNode->rigid_body();
} else {
std::cout << "hingeConstraintNode 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<constraint_t::pointer>(m_constraint);
solver_t::remove_constraint(constraint);
m_constraint = solver_t::create_hinge_constraint(rigid_body);
constraint = static_cast<constraint_t::pointer>(m_constraint);
solver_t::add_constraint(constraint);
}
data.outputValue(ca_constraint).set(true);
data.setClean(plug);
}
void hingeConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data)
{
// std::cout << "hingeConstraintNode::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(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]));
m_constraint->set_world(vec3f((float) mtranslation[0], (float) mtranslation[1], (float) mtranslation[2]));
}
}
data.setClean(plug);
}
void hingeConstraintNode::computeConstraintParam(const MPlug& plug, MDataBlock& data)
{
//std::cout << "hingeConstraintNode::computeRigidBodyParam data.className=" << std::endl;
MObject thisObject(thisMObject());
MObject update;
MPlug(thisObject, ca_constraint).getValue(update);
if(m_constraint) {
float damping = (float) data.inputValue(ia_damping).asDouble();
m_constraint->set_damping(damping);
float lower = (float) data.inputValue(ia_lowerLimit).asDouble();
float upper = (float) data.inputValue(ia_upperLimit).asDouble();
float limit_softness = (float) data.inputValue(ia_limitSoftness).asDouble();
float bias_factor = (float) data.inputValue(ia_biasFactor).asDouble();
float relaxation_factor = (float) data.inputValue(ia_relaxationFactor).asDouble();
m_constraint->set_limit(lower, upper, limit_softness, bias_factor, relaxation_factor);
float* axis = data.inputValue(ia_hingeAxis).asFloat3();
m_constraint->set_axis(vec3f(axis[0], axis[1], axis[2]));
bool enable_motor = data.inputValue(ia_enableAngularMotor).asBool();
float motorTargetVelocity = (float) data.inputValue(ia_motorTargetVelocity).asDouble();
float maxMotorImpulse = (float) data.inputValue(ia_maxMotorImpulse).asDouble();
m_constraint->enable_motor(enable_motor, motorTargetVelocity, maxMotorImpulse);
}
data.outputValue(ca_constraintParam).set(true);
data.setClean(plug);
}
hinge_constraint_t::pointer hingeConstraintNode::constraint()
{
// std::cout << "hingeConstraintNode::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 hingeConstraintNode::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);
}

View File

@@ -0,0 +1,106 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//hingeConstraintNode.h
#ifndef DYN_HINGE_CONSTRAINT_NODE_H
#define DYN_HINGE_CONSTRAINT_NODE_H
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPxLocatorNode.h>
#include "solver.h"
class hingeConstraintNode: public MPxLocatorNode
{
public:
hingeConstraintNode();
virtual ~hingeConstraintNode();
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:
hinge_constraint_t::pointer constraint();
public:
//Attributes
static MObject ia_rigidBody;
static MObject ia_damping;
static MObject ia_lowerLimit;
static MObject ia_upperLimit;
static MObject ia_limitSoftness;
static MObject ia_biasFactor;
static MObject ia_relaxationFactor;
static MObject ia_hingeAxis;
static MObject ca_constraint;
static MObject ca_constraintParam;
static MObject ia_enableAngularMotor;
static MObject ia_motorTargetVelocity;
static MObject ia_maxMotorImpulse;
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:
hinge_constraint_t::pointer m_constraint;
};
#endif //DYN_HINGE_CONSTRAINT_NODE_H

View File

@@ -0,0 +1,52 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//hinge_constraint_impl.h
#ifndef DYN_HINGE_CONSTRAINT_IMPL_H
#define DYN_HINGE_CONSTRAINT_IMPL_H
#include "constraint_impl.h"
class hinge_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_world(vec3f const& p) = 0;
virtual void get_world(vec3f& p) const = 0;
//
virtual void set_damping(float d) = 0;
virtual float damping() const = 0;
virtual void set_limit(float lower, float upper, float softness, float bias_factor, float relaxation_factor) = 0;
virtual void set_axis(vec3f const& p) = 0;
virtual void enable_motor(bool enable, float velocity, float impulse) = 0;
public:
virtual ~hinge_constraint_impl_t() {};
};
#endif //DYN_HINGE_CONSTRAINT_IMPL_H

View File

@@ -0,0 +1,339 @@
/*
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 <nicola@fluidinteractive.com>
*/
//nailConstraintNode.cpp
#include <maya/MFnDependencyNode.h>
#include <maya/MPlugArray.h>
#include <maya/MFnMessageAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MMatrix.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnTransform.h>
#include <maya/MQuaternion.h>
#include <maya/MEulerRotation.h>
#include <maya/MVector.h>
#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<nailConstraintNode*>(fnNode.userNode());
constraint_t::pointer constraint = static_cast<constraint_t::pointer>(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);
}
vec3f pos;
if (m_constraint) {
vec3f world;
m_constraint->get_world(world);
vec3f posA;
quatf rotA;
m_constraint->rigid_body()->get_transform(posA, rotA);
pos = posA - world;
}
glBegin(GL_LINES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(pos[0], pos[1], pos[2]);
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<rigidBodyNode*>(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<constraint_t::pointer>(m_constraint);
solver_t::remove_constraint(constraint);
m_constraint = solver_t::create_nail_constraint(rigid_body);
constraint = static_cast<constraint_t::pointer>(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;
m_constraint->get_world(world);
if(world[0] != float(mtranslation.x) ||
world[1] != float(mtranslation.y) ||
world[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));
std::cout << "pivot (" << pivot[0] << "," << pivot[0] << "," << pivot[0] << ")" << std::endl;
*/
// std::cout << "mtranslation (" << mtranslation[0] << "," << mtranslation[0] << "," << mtranslation[0] << ")" << std::endl;
m_constraint->set_world(vec3f((float) mtranslation[0], (float) mtranslation[1], (float) mtranslation[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((float) 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);
}

View File

@@ -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 <nicola@fluidinteractive.com>
*/
//nailConstraintNode.h
#ifndef DYN_NAIL_CONSTRAINT_NODE_H
#define DYN_NAIL_CONSTRAINT_NODE_H
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPxLocatorNode.h>
#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

View File

@@ -0,0 +1,96 @@
/*
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 <nicola@fluidinteractive.com>
*/
//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<nail_constraint_t> pointer;
//
rigid_body_t::pointer rigid_body() { return m_rigid_body; }
//
void set_pivotA(vec3f const& p) {
nail_constraint_impl_t* nail_impl = dynamic_cast<nail_constraint_impl_t*>(impl());
nail_impl->set_pivotA(p);
}
//local space pivot
void get_pivotA(vec3f& p) const {
nail_constraint_impl_t const* nail_impl = dynamic_cast<nail_constraint_impl_t const*>(impl());
nail_impl->get_pivotA(p);
}
//
void set_world(vec3f const& p) {
nail_constraint_impl_t* nail_impl = dynamic_cast<nail_constraint_impl_t*>(impl());
nail_impl->set_world(p);
}
//
void get_world(vec3f& p) const {
nail_constraint_impl_t const* nail_impl = dynamic_cast<nail_constraint_impl_t const*>(impl());
nail_impl->get_world(p);
}
//
void set_damping(float d) {
nail_constraint_impl_t* nail_impl = dynamic_cast<nail_constraint_impl_t*>(impl());
nail_impl->set_damping(d);
}
float damping() const {
nail_constraint_impl_t const* nail_impl = dynamic_cast<nail_constraint_impl_t const*>(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

View File

@@ -0,0 +1,47 @@
/*
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 <nicola@fluidinteractive.com>
*/
//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_pivotA(vec3f const& p) = 0;
virtual void get_pivotA(vec3f& p) const = 0;
virtual void set_world(vec3f const& p) = 0;
virtual void get_world(vec3f& p) const = 0;
//
virtual void set_damping(float d) = 0;
virtual float damping() const = 0;
public:
virtual ~nail_constraint_impl_t() {};
};
#endif

View File

@@ -0,0 +1,419 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//sixdofConstraintNode.cpp
#include <maya/MFnDependencyNode.h>
#include <maya/MPlugArray.h>
#include <maya/MFnMessageAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MMatrix.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnTransform.h>
#include <maya/MQuaternion.h>
#include <maya/MEulerRotation.h>
#include <maya/MVector.h>
#include "rigidBodyNode.h"
#include "sixdofConstraintNode.h"
#include "mayaUtils.h"
#include "solver.h"
MTypeId sixdofConstraintNode::typeId(0x10033D);
MString sixdofConstraintNode::typeName("dSixdofConstraint");
MObject sixdofConstraintNode::ia_rigidBodyA;
MObject sixdofConstraintNode::ia_rigidBodyB;
MObject sixdofConstraintNode::ia_damping;
MObject sixdofConstraintNode::ca_constraint;
MObject sixdofConstraintNode::ca_constraintParam;
MObject sixdofConstraintNode::ia_lowerLinLimit;
MObject sixdofConstraintNode::ia_upperLinLimit;
MObject sixdofConstraintNode::ia_lowerAngLimit;
MObject sixdofConstraintNode::ia_upperAngLimit;
MStatus sixdofConstraintNode::initialize()
{
MStatus status;
MFnMessageAttribute fnMsgAttr;
MFnNumericAttribute fnNumericAttr;
MFnMatrixAttribute fnMatrixAttr;
ia_rigidBodyA = fnMsgAttr.create("inRigidBodyA", "inrbA", &status);
MCHECKSTATUS(status, "creating inRigidBodyA attribute")
status = addAttribute(ia_rigidBodyA);
MCHECKSTATUS(status, "adding inRigidBody attribute")
ia_rigidBodyB = fnMsgAttr.create("inRigidBodyB", "inrbB", &status);
MCHECKSTATUS(status, "creating inRigidBodyB attribute")
status = addAttribute(ia_rigidBodyB);
MCHECKSTATUS(status, "adding inRigidBodyB 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")
ia_lowerLinLimit = fnNumericAttr.create("lowerLinLimit", "lllt", MFnNumericData::kDouble, 1, &status);
MCHECKSTATUS(status, "creating lower linear limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_lowerLinLimit);
MCHECKSTATUS(status, "adding lower linear limit attribute")
ia_upperLinLimit = fnNumericAttr.create("upperLinLimit", "ullt", MFnNumericData::kDouble, -1, &status);
MCHECKSTATUS(status, "creating upper linear limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_upperLinLimit);
MCHECKSTATUS(status, "adding upper linear limit attribute")
ia_lowerAngLimit = fnNumericAttr.create("lowerAngLimit", "lalt", MFnNumericData::kDouble, 0, &status);
MCHECKSTATUS(status, "creating lower angular limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_lowerAngLimit);
MCHECKSTATUS(status, "adding lower angular limit attribute")
ia_upperAngLimit = fnNumericAttr.create("upperAngLimit", "ualt", MFnNumericData::kDouble, 0, &status);
MCHECKSTATUS(status, "creating upper angular limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_upperAngLimit);
MCHECKSTATUS(status, "adding upper angular limit 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_rigidBodyA, ca_constraint);
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyA, ca_constraint)")
status = attributeAffects(ia_rigidBodyA, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyA, ca_constraintParam)")
status = attributeAffects(ia_rigidBodyB, ca_constraint);
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyB, ca_constraint)")
status = attributeAffects(ia_rigidBodyB, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyB, ca_constraintParam)")
status = attributeAffects(ia_damping, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_damping, ca_constraintParam)")
status = attributeAffects(ia_lowerLinLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_lowerLinLimit, ca_constraintParam)")
status = attributeAffects(ia_upperLinLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_upperLinLimit, ca_constraintParam)")
status = attributeAffects(ia_lowerAngLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_lowerAngLimit, ca_constraintParam)")
status = attributeAffects(ia_upperAngLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_upperAngLimit, ca_constraintParam)")
return MS::kSuccess;
}
sixdofConstraintNode::sixdofConstraintNode()
{
// std::cout << "sixdofConstraintNode::sixdofConstraintNode" << std::endl;
}
sixdofConstraintNode::~sixdofConstraintNode()
{
// std::cout << "sixdofConstraintNode::~sixdofConstraintNode" << std::endl;
}
void sixdofConstraintNode::nodeRemoved(MObject& node, void *clientData)
{
// std::cout << "sixdofConstraintNode::nodeRemoved" << std::endl;
MFnDependencyNode fnNode(node);
sixdofConstraintNode *pNode = static_cast<sixdofConstraintNode*>(fnNode.userNode());
constraint_t::pointer constraint = static_cast<constraint_t::pointer>(pNode->m_constraint);
solver_t::remove_constraint(constraint);
}
void* sixdofConstraintNode::creator()
{
return new sixdofConstraintNode();
}
bool sixdofConstraintNode::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 sixdofConstraintNode::compute(const MPlug& plug, MDataBlock& data)
{
//std::cout << "sixdofConstraintNode::compute: " << plug.name() << std::endl;
//MTime time = data.inputValue( sixdofConstraintNode::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 sixdofConstraintNode::draw( M3dView & view, const MDagPath &path,
M3dView::DisplayStyle style,
M3dView::DisplayStatus status )
{
// std::cout << "sixdofConstraintNode::draw" << std::endl;
update();
view.beginGL();
glPushAttrib( GL_ALL_ATTRIB_BITS );
// glPushMatrix();
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);
}
vec3f posA;
vec3f posB;
if (m_constraint) {
vec3f world;
m_constraint->get_world(world);
quatf rotA;
m_constraint->rigid_bodyA()->get_transform(posA, rotA);
posA = posA - world;
quatf rotB;
m_constraint->rigid_bodyB()->get_transform(posB, rotB);
posB = posB - world;
}
// glLoadIdentity();
glBegin(GL_LINES);
glVertex3f(posA[0], posA[1], posA[2]);
glVertex3f(posB[0], posB[1], posB[2]);
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();
// glPopMatrix();
glPopAttrib();
view.endGL();
}
bool sixdofConstraintNode::isBounded() const
{
//return true;
return false;
}
MBoundingBox sixdofConstraintNode::boundingBox() const
{
// std::cout << "sixdofConstraintNode::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 sixdofConstraintNode::computeConstraint(const MPlug& plug, MDataBlock& data)
{
// std::cout << "sixdofConstraintNode::computeConstraint" << std::endl;
MObject thisObject(thisMObject());
MPlug plgRigidBodyA(thisObject, ia_rigidBodyA);
MPlug plgRigidBodyB(thisObject, ia_rigidBodyB);
MObject update;
//force evaluation of the rigidBody
plgRigidBodyA.getValue(update);
plgRigidBodyB.getValue(update);
rigid_body_t::pointer rigid_bodyA;
if(plgRigidBodyA.isConnected()) {
MPlugArray connections;
plgRigidBodyA.connectedTo(connections, true, true);
if(connections.length() != 0) {
MFnDependencyNode fnNodeA(connections[0].node());
if(fnNodeA.typeId() == rigidBodyNode::typeId) {
rigidBodyNode *pRigidBodyNodeA = static_cast<rigidBodyNode*>(fnNodeA.userNode());
rigid_bodyA = pRigidBodyNodeA->rigid_body();
} else {
std::cout << "sixdofConstraintNode connected to a non-rigidbody node!" << std::endl;
}
}
}
rigid_body_t::pointer rigid_bodyB;
if(plgRigidBodyB.isConnected()) {
MPlugArray connections;
plgRigidBodyB.connectedTo(connections, true, true);
if(connections.length() != 0) {
MFnDependencyNode fnNodeB(connections[0].node());
if(fnNodeB.typeId() == rigidBodyNode::typeId) {
rigidBodyNode *pRigidBodyNodeB = static_cast<rigidBodyNode*>(fnNodeB.userNode());
rigid_bodyB = pRigidBodyNodeB->rigid_body();
} else {
std::cout << "sixdofConstraintNode connected to a non-rigidbody node!" << std::endl;
}
}
}
if(rigid_bodyA && rigid_bodyB) {
//not connected to a rigid body, put a default one
constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
solver_t::remove_constraint(constraint);
m_constraint = solver_t::create_sixdof_constraint(rigid_bodyA, vec3f(), rigid_bodyB, vec3f());
constraint = static_cast<constraint_t::pointer>(m_constraint);
solver_t::add_constraint(constraint);
}
data.outputValue(ca_constraint).set(true);
data.setClean(plug);
}
void sixdofConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data)
{
// std::cout << "sixdofConstraintNode::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(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]));
m_constraint->set_world(vec3f((float) mtranslation[0], (float) mtranslation[1], (float) mtranslation[2]));
}
}
data.setClean(plug);
}
void sixdofConstraintNode::computeConstraintParam(const MPlug& plug, MDataBlock& data)
{
// std::cout << "sixdofConstraintNode::computeRigidBodyParam" << std::endl;
MObject thisObject(thisMObject());
MObject update;
MPlug(thisObject, ca_constraint).getValue(update);
if(m_constraint) {
m_constraint->set_damping((float) data.inputValue(ia_damping).asDouble());
float lin_lower = (float) data.inputValue(ia_lowerLinLimit).asDouble();
float lin_upper = (float) data.inputValue(ia_upperLinLimit).asDouble();
m_constraint->set_LinLimit(lin_lower, lin_upper);
float ang_lower = (float) data.inputValue(ia_lowerAngLimit).asDouble();
float ang_upper = (float) data.inputValue(ia_upperAngLimit).asDouble();
m_constraint->set_AngLimit(ang_lower, ang_upper);
}
data.outputValue(ca_constraintParam).set(true);
data.setClean(plug);
}
sixdof_constraint_t::pointer sixdofConstraintNode::constraint()
{
// std::cout << "sixdofConstraintNode::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 sixdofConstraintNode::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);
}

View File

@@ -0,0 +1,100 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//sixdofConstraintNode.h
#ifndef DYN_SIXDOF_CONSTRAINT_NODE_H
#define DYN_SIXDOF_CONSTRAINT_NODE_H
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPxLocatorNode.h>
#include "solver.h"
class sixdofConstraintNode: public MPxLocatorNode
{
public:
sixdofConstraintNode();
virtual ~sixdofConstraintNode();
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:
sixdof_constraint_t::pointer constraint();
public:
//Attributes
static MObject ia_rigidBodyA;
static MObject ia_rigidBodyB;
static MObject ia_damping;
static MObject ia_lowerLinLimit;
static MObject ia_upperLinLimit;
static MObject ia_lowerAngLimit;
static MObject ia_upperAngLimit;
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:
sixdof_constraint_t::pointer m_constraint;
};
#endif //DYN_SIXDOF_CONSTRAINT_NODE_H

View File

@@ -0,0 +1,116 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//sixdof_constraint.h
#ifndef DYN_SIXDOF_CONSTRAINT_H
#define DYN_SIXDOF_CONSTRAINT_H
#include "shared_ptr.h"
#include "rigid_body.h"
#include "mathUtils.h"
#include "constraint.h"
#include "sixdof_constraint_impl.h"
class sixdof_constraint_t: public constraint_t
{
public:
//typedefs
typedef shared_ptr<sixdof_constraint_t> pointer;
//
rigid_body_t::pointer rigid_bodyA() { return m_rigid_bodyA; }
rigid_body_t::pointer rigid_bodyB() { return m_rigid_bodyB; }
//
void set_pivot(vec3f const& p)
{
sixdof_constraint_impl_t* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t*>(impl());
sixdof_impl->set_pivot(p);
}
//local space pivot
void get_pivot(vec3f& p) const {
sixdof_constraint_impl_t const* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t const*>(impl());
sixdof_impl->get_pivot(p);
}
//
void get_world_pivot(vec3f& p) const {
sixdof_constraint_impl_t const* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t const*>(impl());
sixdof_impl->get_world_pivot(p);
}
//
void set_damping(float d) {
sixdof_constraint_impl_t* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t*>(impl());
sixdof_impl->set_damping(d);
}
float damping() const {
sixdof_constraint_impl_t const* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t const*>(impl());
return sixdof_impl->damping();
}
void set_world(vec3f const& p)
{
sixdof_constraint_impl_t* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t*>(impl());
sixdof_impl->set_world(p);
}
//local space pivot
void get_world(vec3f& p) const {
sixdof_constraint_impl_t const* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t const*>(impl());
sixdof_impl->get_world(p);
}
void set_LinLimit(float lower, float upper) {
sixdof_constraint_impl_t* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t*>(impl());
sixdof_impl->set_LinLimit(lower, upper);
}
void set_AngLimit(float lower, float upper) {
sixdof_constraint_impl_t* sixdof_impl = dynamic_cast<sixdof_constraint_impl_t*>(impl());
sixdof_impl->set_AngLimit(lower, upper);
}
public:
virtual ~sixdof_constraint_t() {};
protected:
friend class solver_t;
sixdof_constraint_t(sixdof_constraint_impl_t* impl, rigid_body_t::pointer& rigid_bodyA, rigid_body_t::pointer& rigid_bodyB):
constraint_t(impl),
m_rigid_bodyA(rigid_bodyA),
m_rigid_bodyB(rigid_bodyB)
{
}
private:
rigid_body_t::pointer m_rigid_bodyA;
rigid_body_t::pointer m_rigid_bodyB;
};
#endif //DYN_SIXDOF_CONSTRAINT_H

View File

@@ -0,0 +1,50 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//sixdof_constraint_impl.h
#ifndef DYN_SIXDOF_CONSTRAINT_IMPL_H
#define DYN_SIXDOF_CONSTRAINT_IMPL_H
#include "constraint_impl.h"
class sixdof_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_world(vec3f const& p) = 0;
virtual void get_world(vec3f& p) const = 0;
//
virtual void set_damping(float d) = 0;
virtual float damping() const = 0;
virtual void set_LinLimit(float lower, float upper) = 0;
virtual void set_AngLimit(float lower, float upper) = 0;
public:
virtual ~sixdof_constraint_impl_t() {};
};
#endif //DYN_SIXDOF_CONSTRAINT_IMPL_H

View File

@@ -0,0 +1,419 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//sliderConstraintNode.cpp
#include <maya/MFnDependencyNode.h>
#include <maya/MPlugArray.h>
#include <maya/MFnMessageAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MMatrix.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnTransform.h>
#include <maya/MQuaternion.h>
#include <maya/MEulerRotation.h>
#include <maya/MVector.h>
#include "rigidBodyNode.h"
#include "sliderConstraintNode.h"
#include "mayaUtils.h"
#include "solver.h"
MTypeId sliderConstraintNode::typeId(0x10033C);
MString sliderConstraintNode::typeName("dSliderConstraint");
MObject sliderConstraintNode::ia_rigidBodyA;
MObject sliderConstraintNode::ia_rigidBodyB;
MObject sliderConstraintNode::ia_damping;
MObject sliderConstraintNode::ca_constraint;
MObject sliderConstraintNode::ca_constraintParam;
MObject sliderConstraintNode::ia_lowerLinLimit;
MObject sliderConstraintNode::ia_upperLinLimit;
MObject sliderConstraintNode::ia_lowerAngLimit;
MObject sliderConstraintNode::ia_upperAngLimit;
MStatus sliderConstraintNode::initialize()
{
MStatus status;
MFnMessageAttribute fnMsgAttr;
MFnNumericAttribute fnNumericAttr;
MFnMatrixAttribute fnMatrixAttr;
ia_rigidBodyA = fnMsgAttr.create("inRigidBodyA", "inrbA", &status);
MCHECKSTATUS(status, "creating inRigidBodyA attribute")
status = addAttribute(ia_rigidBodyA);
MCHECKSTATUS(status, "adding inRigidBody attribute")
ia_rigidBodyB = fnMsgAttr.create("inRigidBodyB", "inrbB", &status);
MCHECKSTATUS(status, "creating inRigidBodyB attribute")
status = addAttribute(ia_rigidBodyB);
MCHECKSTATUS(status, "adding inRigidBodyB 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")
ia_lowerLinLimit = fnNumericAttr.create("lowerLinLimit", "lllt", MFnNumericData::kDouble, 1, &status);
MCHECKSTATUS(status, "creating lower linear limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_lowerLinLimit);
MCHECKSTATUS(status, "adding lower linear limit attribute")
ia_upperLinLimit = fnNumericAttr.create("upperLinLimit", "ullt", MFnNumericData::kDouble, -1, &status);
MCHECKSTATUS(status, "creating upper linear limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_upperLinLimit);
MCHECKSTATUS(status, "adding upper linear limit attribute")
ia_lowerAngLimit = fnNumericAttr.create("lowerAngLimit", "lalt", MFnNumericData::kDouble, 0, &status);
MCHECKSTATUS(status, "creating lower angular limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_lowerAngLimit);
MCHECKSTATUS(status, "adding lower angular limit attribute")
ia_upperAngLimit = fnNumericAttr.create("upperAngLimit", "ualt", MFnNumericData::kDouble, 0, &status);
MCHECKSTATUS(status, "creating upper angular limit attribute")
fnNumericAttr.setKeyable(true);
status = addAttribute(ia_upperAngLimit);
MCHECKSTATUS(status, "adding upper angular limit 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_rigidBodyA, ca_constraint);
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyA, ca_constraint)")
status = attributeAffects(ia_rigidBodyA, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyA, ca_constraintParam)")
status = attributeAffects(ia_rigidBodyB, ca_constraint);
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyB, ca_constraint)")
status = attributeAffects(ia_rigidBodyB, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyB, ca_constraintParam)")
status = attributeAffects(ia_damping, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_damping, ca_constraintParam)")
status = attributeAffects(ia_lowerLinLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_lowerLinLimit, ca_constraintParam)")
status = attributeAffects(ia_upperLinLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_upperLinLimit, ca_constraintParam)")
status = attributeAffects(ia_lowerAngLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_lowerAngLimit, ca_constraintParam)")
status = attributeAffects(ia_upperAngLimit, ca_constraintParam);
MCHECKSTATUS(status, "adding attributeAffects(ia_upperAngLimit, ca_constraintParam)")
return MS::kSuccess;
}
sliderConstraintNode::sliderConstraintNode()
{
// std::cout << "sliderConstraintNode::sliderConstraintNode" << std::endl;
}
sliderConstraintNode::~sliderConstraintNode()
{
// std::cout << "sliderConstraintNode::~sliderConstraintNode" << std::endl;
}
void sliderConstraintNode::nodeRemoved(MObject& node, void *clientData)
{
// std::cout << "sliderConstraintNode::nodeRemoved" << std::endl;
MFnDependencyNode fnNode(node);
sliderConstraintNode *pNode = static_cast<sliderConstraintNode*>(fnNode.userNode());
constraint_t::pointer constraint = static_cast<constraint_t::pointer>(pNode->m_constraint);
solver_t::remove_constraint(constraint);
}
void* sliderConstraintNode::creator()
{
return new sliderConstraintNode();
}
bool sliderConstraintNode::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 sliderConstraintNode::compute(const MPlug& plug, MDataBlock& data)
{
//std::cout << "sliderConstraintNode::compute: " << plug.name() << std::endl;
//MTime time = data.inputValue( sliderConstraintNode::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 sliderConstraintNode::draw( M3dView & view, const MDagPath &path,
M3dView::DisplayStyle style,
M3dView::DisplayStatus status )
{
// std::cout << "sliderConstraintNode::draw" << std::endl;
update();
view.beginGL();
glPushAttrib( GL_ALL_ATTRIB_BITS );
// glPushMatrix();
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);
}
vec3f posA;
vec3f posB;
if (m_constraint) {
vec3f world;
m_constraint->get_world(world);
quatf rotA;
m_constraint->rigid_bodyA()->get_transform(posA, rotA);
posA = posA - world;
quatf rotB;
m_constraint->rigid_bodyB()->get_transform(posB, rotB);
posB = posB - world;
}
// glLoadIdentity();
glBegin(GL_LINES);
glVertex3f(posA[0], posA[1], posA[2]);
glVertex3f(posB[0], posB[1], posB[2]);
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();
// glPopMatrix();
glPopAttrib();
view.endGL();
}
bool sliderConstraintNode::isBounded() const
{
//return true;
return false;
}
MBoundingBox sliderConstraintNode::boundingBox() const
{
// std::cout << "sliderConstraintNode::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 sliderConstraintNode::computeConstraint(const MPlug& plug, MDataBlock& data)
{
// std::cout << "sliderConstraintNode::computeConstraint" << std::endl;
MObject thisObject(thisMObject());
MPlug plgRigidBodyA(thisObject, ia_rigidBodyA);
MPlug plgRigidBodyB(thisObject, ia_rigidBodyB);
MObject update;
//force evaluation of the rigidBody
plgRigidBodyA.getValue(update);
plgRigidBodyB.getValue(update);
rigid_body_t::pointer rigid_bodyA;
if(plgRigidBodyA.isConnected()) {
MPlugArray connections;
plgRigidBodyA.connectedTo(connections, true, true);
if(connections.length() != 0) {
MFnDependencyNode fnNodeA(connections[0].node());
if(fnNodeA.typeId() == rigidBodyNode::typeId) {
rigidBodyNode *pRigidBodyNodeA = static_cast<rigidBodyNode*>(fnNodeA.userNode());
rigid_bodyA = pRigidBodyNodeA->rigid_body();
} else {
std::cout << "sliderConstraintNode connected to a non-rigidbody node!" << std::endl;
}
}
}
rigid_body_t::pointer rigid_bodyB;
if(plgRigidBodyB.isConnected()) {
MPlugArray connections;
plgRigidBodyB.connectedTo(connections, true, true);
if(connections.length() != 0) {
MFnDependencyNode fnNodeB(connections[0].node());
if(fnNodeB.typeId() == rigidBodyNode::typeId) {
rigidBodyNode *pRigidBodyNodeB = static_cast<rigidBodyNode*>(fnNodeB.userNode());
rigid_bodyB = pRigidBodyNodeB->rigid_body();
} else {
std::cout << "sliderConstraintNode connected to a non-rigidbody node!" << std::endl;
}
}
}
if(rigid_bodyA && rigid_bodyB) {
//not connected to a rigid body, put a default one
constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
solver_t::remove_constraint(constraint);
m_constraint = solver_t::create_slider_constraint(rigid_bodyA, vec3f(), rigid_bodyB, vec3f());
constraint = static_cast<constraint_t::pointer>(m_constraint);
solver_t::add_constraint(constraint);
}
data.outputValue(ca_constraint).set(true);
data.setClean(plug);
}
void sliderConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data)
{
// std::cout << "sliderConstraintNode::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(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]));
m_constraint->set_world(vec3f((float) mtranslation[0], (float) mtranslation[1], (float) mtranslation[2]));
}
}
data.setClean(plug);
}
void sliderConstraintNode::computeConstraintParam(const MPlug& plug, MDataBlock& data)
{
// std::cout << "sliderConstraintNode::computeRigidBodyParam" << std::endl;
MObject thisObject(thisMObject());
MObject update;
MPlug(thisObject, ca_constraint).getValue(update);
if(m_constraint) {
m_constraint->set_damping((float) data.inputValue(ia_damping).asDouble());
float lin_lower = (float) data.inputValue(ia_lowerLinLimit).asDouble();
float lin_upper = (float) data.inputValue(ia_upperLinLimit).asDouble();
m_constraint->set_LinLimit(lin_lower, lin_upper);
float ang_lower = (float) data.inputValue(ia_lowerAngLimit).asDouble();
float ang_upper = (float) data.inputValue(ia_upperAngLimit).asDouble();
m_constraint->set_AngLimit(ang_lower, ang_upper);
}
data.outputValue(ca_constraintParam).set(true);
data.setClean(plug);
}
slider_constraint_t::pointer sliderConstraintNode::constraint()
{
// std::cout << "sliderConstraintNode::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 sliderConstraintNode::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);
}

View File

@@ -0,0 +1,100 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//sliderConstraintNode.h
#ifndef DYN_SLIDER_CONSTRAINT_NODE_H
#define DYN_SLIDER_CONSTRAINT_NODE_H
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPxLocatorNode.h>
#include "solver.h"
class sliderConstraintNode: public MPxLocatorNode
{
public:
sliderConstraintNode();
virtual ~sliderConstraintNode();
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:
slider_constraint_t::pointer constraint();
public:
//Attributes
static MObject ia_rigidBodyA;
static MObject ia_rigidBodyB;
static MObject ia_damping;
static MObject ia_lowerLinLimit;
static MObject ia_upperLinLimit;
static MObject ia_lowerAngLimit;
static MObject ia_upperAngLimit;
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:
slider_constraint_t::pointer m_constraint;
};
#endif //DYN_SLIDER_CONSTRAINT_NODE_H

View File

@@ -0,0 +1,116 @@
/*
Bullet Continuous Collision Detection and Physics Library Maya Plugin
Copyright (c) 2008 Herbert Law
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: Herbert Law <Herbert.Law@gmail.com>
*/
//slider_constraint.h
#ifndef DYN_SLIDER_CONSTRAINT_H
#define DYN_SLIDER_CONSTRAINT_H
#include "shared_ptr.h"
#include "rigid_body.h"
#include "mathUtils.h"
#include "constraint.h"
#include "slider_constraint_impl.h"
class slider_constraint_t: public constraint_t
{
public:
//typedefs
typedef shared_ptr<slider_constraint_t> pointer;
//
rigid_body_t::pointer rigid_bodyA() { return m_rigid_bodyA; }
rigid_body_t::pointer rigid_bodyB() { return m_rigid_bodyB; }
//
void set_pivot(vec3f const& p)
{
slider_constraint_impl_t* slider_impl = dynamic_cast<slider_constraint_impl_t*>(impl());
slider_impl->set_pivot(p);
}
//local space pivot
void get_pivot(vec3f& p) const {
slider_constraint_impl_t const* slider_impl = dynamic_cast<slider_constraint_impl_t const*>(impl());
slider_impl->get_pivot(p);
}
//
void get_world_pivot(vec3f& p) const {
slider_constraint_impl_t const* slider_impl = dynamic_cast<slider_constraint_impl_t const*>(impl());
slider_impl->get_world_pivot(p);
}
//
void set_damping(float d) {
slider_constraint_impl_t* slider_impl = dynamic_cast<slider_constraint_impl_t*>(impl());
slider_impl->set_damping(d);
}
float damping() const {
slider_constraint_impl_t const* slider_impl = dynamic_cast<slider_constraint_impl_t const*>(impl());
return slider_impl->damping();
}
void set_world(vec3f const& p)
{
slider_constraint_impl_t* slider_impl = dynamic_cast<slider_constraint_impl_t*>(impl());
slider_impl->set_world(p);
}
//local space pivot
void get_world(vec3f& p) const {
slider_constraint_impl_t const* slider_impl = dynamic_cast<slider_constraint_impl_t const*>(impl());
slider_impl->get_world(p);
}
void set_LinLimit(float lower, float upper) {
slider_constraint_impl_t* slider_impl = dynamic_cast<slider_constraint_impl_t*>(impl());
slider_impl->set_LinLimit(lower, upper);
}
void set_AngLimit(float lower, float upper) {
slider_constraint_impl_t* slider_impl = dynamic_cast<slider_constraint_impl_t*>(impl());
slider_impl->set_AngLimit(lower, upper);
}
public:
virtual ~slider_constraint_t() {};
protected:
friend class solver_t;
slider_constraint_t(slider_constraint_impl_t* impl, rigid_body_t::pointer& rigid_bodyA, rigid_body_t::pointer& rigid_bodyB):
constraint_t(impl),
m_rigid_bodyA(rigid_bodyA),
m_rigid_bodyB(rigid_bodyB)
{
}
private:
rigid_body_t::pointer m_rigid_bodyA;
rigid_body_t::pointer m_rigid_bodyB;
};
#endif //DYN_SLIDER_CONSTRAINT_H