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
550 lines
20 KiB
C++
550 lines
20 KiB
C++
/*
|
|
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>
|
|
*/
|
|
|
|
//rigidBodyNode.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 "collisionShapeNode.h"
|
|
#include "mayaUtils.h"
|
|
|
|
#include "solver.h"
|
|
|
|
MTypeId rigidBodyNode::typeId(0x10032f);
|
|
MString rigidBodyNode::typeName("dRigidBody");
|
|
|
|
MObject rigidBodyNode::ia_collisionShape;
|
|
MObject rigidBodyNode::ia_solver;
|
|
MObject rigidBodyNode::ia_mass;
|
|
MObject rigidBodyNode::ia_restitution;
|
|
MObject rigidBodyNode::ia_friction;
|
|
MObject rigidBodyNode::ia_linearDamping;
|
|
MObject rigidBodyNode::ia_angularDamping;
|
|
MObject rigidBodyNode::ia_initialPosition;
|
|
MObject rigidBodyNode::ia_initialRotation;
|
|
MObject rigidBodyNode::ia_initialVelocity;
|
|
MObject rigidBodyNode::ia_initialSpin;
|
|
MObject rigidBodyNode::ca_rigidBody;
|
|
MObject rigidBodyNode::ca_rigidBodyParam;
|
|
MObject rigidBodyNode::ca_solver;
|
|
|
|
|
|
MStatus rigidBodyNode::initialize()
|
|
{
|
|
MStatus status;
|
|
MFnMessageAttribute fnMsgAttr;
|
|
MFnNumericAttribute fnNumericAttr;
|
|
MFnMatrixAttribute fnMatrixAttr;
|
|
|
|
ia_collisionShape = fnMsgAttr.create("inCollisionShape", "incs", &status);
|
|
MCHECKSTATUS(status, "creating inCollisionShape attribute")
|
|
status = addAttribute(ia_collisionShape);
|
|
MCHECKSTATUS(status, "adding inCollisionShape attribute")
|
|
|
|
ia_solver = fnMsgAttr.create("solver", "solv", &status);
|
|
MCHECKSTATUS(status, "creating solver attribute")
|
|
status = addAttribute(ia_solver);
|
|
MCHECKSTATUS(status, "adding solver attribute")
|
|
|
|
ia_mass = fnNumericAttr.create("mass", "ma", MFnNumericData::kDouble, 1.0, &status);
|
|
MCHECKSTATUS(status, "creating mass attribute")
|
|
fnNumericAttr.setKeyable(true);
|
|
status = addAttribute(ia_mass);
|
|
MCHECKSTATUS(status, "adding mass attribute")
|
|
|
|
ia_restitution = fnNumericAttr.create("restitution", "rst", MFnNumericData::kDouble, 0.1, &status);
|
|
MCHECKSTATUS(status, "creating restitution attribute")
|
|
fnNumericAttr.setKeyable(true);
|
|
status = addAttribute(ia_restitution);
|
|
MCHECKSTATUS(status, "adding restitution attribute")
|
|
|
|
ia_friction = fnNumericAttr.create("friction", "fc", MFnNumericData::kDouble, 0.5, &status);
|
|
MCHECKSTATUS(status, "creating friction attribute")
|
|
fnNumericAttr.setKeyable(true);
|
|
status = addAttribute(ia_friction);
|
|
MCHECKSTATUS(status, "adding friction attribute")
|
|
|
|
ia_linearDamping = fnNumericAttr.create("linearDamping", "ld", MFnNumericData::kDouble, 0.3, &status);
|
|
MCHECKSTATUS(status, "creating linearDamping attribute")
|
|
fnNumericAttr.setKeyable(true);
|
|
status = addAttribute(ia_linearDamping);
|
|
MCHECKSTATUS(status, "adding linearDamping attribute")
|
|
|
|
ia_angularDamping = fnNumericAttr.create("angularDamping", "ad", MFnNumericData::kDouble, 0.3, &status);
|
|
MCHECKSTATUS(status, "creating angularDamping attribute")
|
|
fnNumericAttr.setKeyable(true);
|
|
status = addAttribute(ia_angularDamping);
|
|
MCHECKSTATUS(status, "adding angularDamping attribute")
|
|
|
|
ia_initialPosition = fnNumericAttr.createPoint("initialPosition", "inpo", &status);
|
|
MCHECKSTATUS(status, "creating initialPosition attribute")
|
|
status = addAttribute(ia_initialPosition);
|
|
MCHECKSTATUS(status, "adding initialPosition attribute")
|
|
|
|
ia_initialRotation = fnNumericAttr.createPoint("initialRotation", "inro", &status);
|
|
MCHECKSTATUS(status, "creating initialRotation attribute")
|
|
status = addAttribute(ia_initialRotation);
|
|
MCHECKSTATUS(status, "adding initialRotation attribute")
|
|
|
|
ia_initialVelocity = fnNumericAttr.createPoint("initialVelocity", "inve", &status);
|
|
MCHECKSTATUS(status, "creating initialVelocity attribute")
|
|
status = addAttribute(ia_initialVelocity);
|
|
MCHECKSTATUS(status, "adding initialVelocity attribute")
|
|
|
|
ia_initialSpin = fnNumericAttr.createPoint("initialSpin", "insp", &status);
|
|
MCHECKSTATUS(status, "creating initialSpin attribute")
|
|
status = addAttribute(ia_initialSpin);
|
|
MCHECKSTATUS(status, "adding initialSpin attribute")
|
|
|
|
ca_rigidBody = fnNumericAttr.create("ca_rigidBody", "carb", MFnNumericData::kBoolean, 0, &status);
|
|
MCHECKSTATUS(status, "creating ca_rigidBody attribute")
|
|
fnNumericAttr.setConnectable(false);
|
|
fnNumericAttr.setHidden(true);
|
|
fnNumericAttr.setStorable(false);
|
|
fnNumericAttr.setKeyable(false);
|
|
status = addAttribute(ca_rigidBody);
|
|
MCHECKSTATUS(status, "adding ca_rigidBody attribute")
|
|
|
|
ca_rigidBodyParam = fnNumericAttr.create("ca_rigidBodyParam", "carbp", MFnNumericData::kBoolean, 0, &status);
|
|
MCHECKSTATUS(status, "creating ca_rigidBodyParam attribute")
|
|
fnNumericAttr.setConnectable(false);
|
|
fnNumericAttr.setHidden(true);
|
|
fnNumericAttr.setStorable(false);
|
|
fnNumericAttr.setKeyable(false);
|
|
status = addAttribute(ca_rigidBodyParam);
|
|
MCHECKSTATUS(status, "adding ca_rigidBodyParam attribute")
|
|
|
|
ca_solver = fnNumericAttr.create("ca_solver", "caso", MFnNumericData::kBoolean, 0, &status);
|
|
MCHECKSTATUS(status, "creating ca_solver attribute")
|
|
fnNumericAttr.setConnectable(false);
|
|
fnNumericAttr.setHidden(true);
|
|
fnNumericAttr.setStorable(false);
|
|
fnNumericAttr.setKeyable(false);
|
|
status = addAttribute(ca_solver);
|
|
MCHECKSTATUS(status, "adding ca_solver attribute")
|
|
|
|
status = attributeAffects(ia_collisionShape, ca_rigidBody);
|
|
MCHECKSTATUS(status, "adding attributeAffects(ia_collisionShape, ca_rigidBody)")
|
|
|
|
status = attributeAffects(ia_collisionShape, ca_rigidBodyParam);
|
|
MCHECKSTATUS(status, "adding attributeAffects(ia_collisionShape, ca_rigidBodyParam)")
|
|
|
|
status = attributeAffects(ia_mass, ca_rigidBodyParam);
|
|
MCHECKSTATUS(status, "adding attributeAffects(ia_mass, ca_rigidBodyParam)")
|
|
|
|
status = attributeAffects(ia_restitution, ca_rigidBodyParam);
|
|
MCHECKSTATUS(status, "adding attributeAffects(ia_restitution, ca_rigidBodyParam)")
|
|
|
|
status = attributeAffects(ia_friction, ca_rigidBodyParam);
|
|
MCHECKSTATUS(status, "adding attributeAffects(ia_friction, ca_rigidBodyParam)")
|
|
|
|
status = attributeAffects(ia_linearDamping, ca_rigidBodyParam);
|
|
MCHECKSTATUS(status, "adding attributeAffects(ia_linearDamping, ca_rigidBodyParam)")
|
|
|
|
status = attributeAffects(ia_angularDamping, ca_rigidBodyParam);
|
|
MCHECKSTATUS(status, "adding attributeAffects(ia_angularDamping, ca_rigidBodyParam)")
|
|
|
|
status = attributeAffects(ia_solver, ca_solver);
|
|
MCHECKSTATUS(status, "adding attributeAffects(ia_solver, ca_solver)")
|
|
|
|
|
|
return MS::kSuccess;
|
|
}
|
|
|
|
rigidBodyNode::rigidBodyNode()
|
|
{
|
|
// std::cout << "rigidBodyNode::rigidBodyNode" << std::endl;
|
|
}
|
|
|
|
rigidBodyNode::~rigidBodyNode()
|
|
{
|
|
// std::cout << "rigidBodyNode::~rigidBodyNode" << std::endl;
|
|
}
|
|
|
|
void rigidBodyNode::nodeRemoved(MObject& node, void *clientData)
|
|
{
|
|
// std::cout << "rigidBodyNode::nodeRemoved" << std::endl;
|
|
MFnDependencyNode fnNode(node);
|
|
solver_t::remove_rigid_body(static_cast<rigidBodyNode*>(fnNode.userNode())->m_rigid_body);
|
|
}
|
|
|
|
void* rigidBodyNode::creator()
|
|
{
|
|
return new rigidBodyNode();
|
|
}
|
|
|
|
|
|
bool rigidBodyNode::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 rigidBodyNode::setDependentsDirty( const MPlug & plug, MPlugArray & plugArray)
|
|
{
|
|
std::cout << "rigidBodyNode::setDependentsDirty: " << plug.name().asChar() << std::endl;
|
|
MObject thisNode = thisMObject();
|
|
if(plug == ia_solver) {
|
|
MPlug plgAffected(thisNode, ca_update);
|
|
plugArray.append(plgAffected);
|
|
plgAffected.setValue(true);
|
|
} else if(plug == ia_collisionShape) {
|
|
//ia_collisionShape -> ca_rigidBody
|
|
MPlug plgAffected(thisNode, ca_rigidBody);
|
|
plugArray.append(plgAffected);
|
|
plgAffected.setValue(true);
|
|
|
|
//ia_collisionShape -> ca_rigidBodyParam
|
|
plgAffected.setAttribute(ca_rigidBodyParam);
|
|
plugArray.append(plgAffected);
|
|
plgAffected.setValue(true);
|
|
} else if(plug == ca_rigidBody) {
|
|
//ca_rigidBody -> ca_update
|
|
MPlug plgAffected(thisNode, ca_update);
|
|
plugArray.append(plgAffected);
|
|
plgAffected.setValue(true);
|
|
|
|
//ca_rigidBody -> ca_rigidBodyParam
|
|
plgAffected.setAttribute(ca_rigidBodyParam);
|
|
plugArray.append(plgAffected);
|
|
plgAffected.setValue(true);
|
|
} else if(plug == ia_mass) {
|
|
//ia_mass -> ca_rigidBodyParam
|
|
MPlug plgAffected(thisNode, ca_rigidBodyParam);
|
|
plugArray.append(plgAffected);
|
|
plgAffected.setValue(true);
|
|
|
|
plgAffected.setAttribute(ca_update);
|
|
plugArray.append(plgAffected);
|
|
plgAffected.setValue(true);
|
|
} else if(plug == ca_rigidBodyParam) {
|
|
//ca_rigidBodyParam -> ca_update
|
|
MPlug plgAffected(thisNode, ca_update);
|
|
plugArray.append(plgAffected);
|
|
plgAffected.setValue(true);
|
|
}
|
|
return MS::kSuccess;
|
|
}*/
|
|
|
|
|
|
MStatus rigidBodyNode::compute(const MPlug& plug, MDataBlock& data)
|
|
{
|
|
//std::cout << "rigidBodyNode::compute: " << plug.name() << std::endl;
|
|
//MTime time = data.inputValue( rigidBodyNode::inTime ).asTime();
|
|
if(plug == ca_rigidBody) {
|
|
computeRigidBody(plug, data);
|
|
} else if(plug == ca_rigidBodyParam) {
|
|
computeRigidBodyParam(plug, data);
|
|
} else if(plug == ca_solver) {
|
|
data.inputValue(ia_solver).asBool();
|
|
} 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 rigidBodyNode::draw( M3dView & view, const MDagPath &path,
|
|
M3dView::DisplayStyle style,
|
|
M3dView::DisplayStatus status )
|
|
{
|
|
// std::cout << "rigidBodyNode::draw" << std::endl;
|
|
|
|
update();
|
|
|
|
view.beginGL();
|
|
glPushAttrib( GL_ALL_ATTRIB_BITS );
|
|
|
|
if(m_rigid_body) {
|
|
//remove the scale, since it's already included in the node transform
|
|
vec3f scale;
|
|
m_rigid_body->collision_shape()->get_scale(scale);
|
|
|
|
glPushMatrix();
|
|
glScalef(1/scale[0], 1/scale[1], 1/scale[2]);
|
|
|
|
if(style == M3dView::kFlatShaded ||
|
|
style == M3dView::kGouraudShaded) {
|
|
glEnable(GL_LIGHTING);
|
|
float material[] = { 0.4, 0.7, 1.0, 1.0 };
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, material);
|
|
m_rigid_body->collision_shape()->gl_draw(collision_shape_t::kDSSolid);
|
|
}
|
|
|
|
|
|
if( status == M3dView::kActive ||
|
|
status == M3dView::kLead ||
|
|
status == M3dView::kHilite ||
|
|
( style != M3dView::kGouraudShaded && style != M3dView::kFlatShaded ) ) {
|
|
|
|
glDisable(GL_LIGHTING);
|
|
m_rigid_body->collision_shape()->gl_draw(collision_shape_t::kDSWireframe);
|
|
|
|
}
|
|
glPopMatrix();
|
|
}
|
|
glPopAttrib();
|
|
view.endGL();
|
|
}
|
|
|
|
bool rigidBodyNode::isBounded() const
|
|
{
|
|
//return true;
|
|
return false;
|
|
}
|
|
|
|
MBoundingBox rigidBodyNode::boundingBox() const
|
|
{
|
|
// std::cout << "rigidBodyNode::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 rigidBodyNode::computeRigidBody(const MPlug& plug, MDataBlock& data)
|
|
{
|
|
// std::cout << "rigidBodyNode::computeRigidBody" << std::endl;
|
|
|
|
MObject thisObject(thisMObject());
|
|
MPlug plgCollisionShape(thisObject, ia_collisionShape);
|
|
MObject update;
|
|
//force evaluation of the shape
|
|
plgCollisionShape.getValue(update);
|
|
|
|
vec3f prevCenter(0, 0, 0);
|
|
quatf prevRotation(qidentity<float>());
|
|
if(m_rigid_body) {
|
|
prevCenter = m_rigid_body->collision_shape()->center();
|
|
prevRotation = m_rigid_body->collision_shape()->rotation();
|
|
}
|
|
|
|
collision_shape_t::pointer collision_shape;
|
|
if(plgCollisionShape.isConnected()) {
|
|
MPlugArray connections;
|
|
plgCollisionShape.connectedTo(connections, true, true);
|
|
if(connections.length() != 0) {
|
|
MFnDependencyNode fnNode(connections[0].node());
|
|
if(fnNode.typeId() == collisionShapeNode::typeId) {
|
|
collisionShapeNode *pCollisionShapeNode = static_cast<collisionShapeNode*>(fnNode.userNode());
|
|
collision_shape = pCollisionShapeNode->collisionShape();
|
|
} else {
|
|
std::cout << "rigidBodyNode connected to a non-collision shape node!" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!collision_shape) {
|
|
//not connected to a collision shape, put a default one
|
|
collision_shape = solver_t::create_sphere_shape();
|
|
}
|
|
|
|
/* vec3f deltaCenter = prevCenter - collision_shape->center();
|
|
quatf deltaRotation = qprod(qconj(collision_shape->rotation()), prevRotation);
|
|
|
|
MDataHandle hInitPos = data.outputValue(ia_initialPosition);
|
|
float3 &ipos = hInitPos.asFloat3();
|
|
|
|
MDataHandle hInitRot = data.outputValue(ia_initialRotation);
|
|
float3 &irot = hInitRot.asFloat3();
|
|
MQuaternion iquat = MEulerRotation(deg2rad(irot[0]), deg2rad(irot[1]), deg2rad(irot[2])).asQuaternion();
|
|
|
|
// MVector deltapos(mtranslation.x - pos[0], mtranslation.y - pos[1], mtranslation.z - pos[2]);
|
|
// MQuaternion deltarot = MQuaternion(rot[1], rot[2], rot[3], rot[0]).conjugate() * mrotation;
|
|
|
|
MVector newipos(ipos[0] + deltaCenter[0], ipos[1] + deltaCenter[1], ipos[2] + deltaCenter[2]); */
|
|
// MEulerRotation newirot((iquat * deltarot).asEulerRotation());
|
|
|
|
//hInitPos.set3Float(newipos.x, newipos.y, newipos.z);
|
|
// hInitRot.set3Float(rad2deg(newirot.x), rad2deg(newirot.y), rad2deg(newirot.z));*/
|
|
|
|
solver_t::remove_rigid_body(m_rigid_body);
|
|
m_rigid_body = solver_t::create_rigid_body(collision_shape);
|
|
solver_t::add_rigid_body(m_rigid_body);
|
|
|
|
data.outputValue(ca_rigidBody).set(true);
|
|
data.setClean(plug);
|
|
}
|
|
|
|
|
|
void rigidBodyNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data)
|
|
{
|
|
// std::cout << "rigidBodyNode::computeWorldMatrix" << std::endl;
|
|
|
|
MObject thisObject(thisMObject());
|
|
MFnDagNode fnDagNode(thisObject);
|
|
|
|
MObject update;
|
|
MPlug(thisObject, ca_rigidBody).getValue(update);
|
|
MPlug(thisObject, ca_rigidBodyParam).getValue(update);
|
|
|
|
vec3f pos;
|
|
quatf rot;
|
|
|
|
MStatus status;
|
|
|
|
MFnTransform fnParentTransform(fnDagNode.parent(0, &status));
|
|
|
|
MVector mtranslation = fnParentTransform.getTranslation(MSpace::kTransform, &status);
|
|
|
|
MQuaternion mrotation;
|
|
fnParentTransform.getRotation(mrotation, MSpace::kTransform);
|
|
double mscale[3];
|
|
fnParentTransform.getScale(mscale);
|
|
|
|
m_rigid_body->get_transform(pos, rot);
|
|
|
|
MDataHandle hInitPos = data.outputValue(ia_initialPosition);
|
|
float3 &ipos = hInitPos.asFloat3();
|
|
|
|
MDataHandle hInitRot = data.outputValue(ia_initialRotation);
|
|
float3 &irot = hInitRot.asFloat3();
|
|
MQuaternion iquat = MEulerRotation(deg2rad(irot[0]), deg2rad(irot[1]), deg2rad(irot[2])).asQuaternion();
|
|
|
|
MVector deltapos(mtranslation.x - pos[0], mtranslation.y - pos[1], mtranslation.z - pos[2]);
|
|
MQuaternion deltarot = MQuaternion(rot[1], rot[2], rot[3], rot[0]).conjugate() * mrotation;
|
|
|
|
MVector newipos(ipos[0] + deltapos.x, ipos[1] + deltapos.y, ipos[2] + deltapos.z);
|
|
MEulerRotation newirot((iquat * deltarot).asEulerRotation());
|
|
|
|
float3 &ihpos = hInitPos.asFloat3();
|
|
//hInitPos.set3Float(newipos.x, newipos.y, newipos.z);
|
|
//for Maya 8.5
|
|
ihpos[0] = newipos.x;
|
|
ihpos[1] = newipos.y;
|
|
ihpos[2] = newipos.z;
|
|
|
|
float3 &ihrot = hInitRot.asFloat3();
|
|
//hInitRot.set3Float(rad2deg(newirot.x), rad2deg(newirot.y), rad2deg(newirot.z));
|
|
//for Maya 8.5
|
|
ihrot[0] = rad2deg(newirot.x);
|
|
ihrot[1] = rad2deg(newirot.y);
|
|
ihrot[2] = rad2deg(newirot.z);
|
|
|
|
|
|
m_rigid_body->set_transform(vec3f(mtranslation.x, mtranslation.y, mtranslation.z),
|
|
quatf(mrotation.w, mrotation.x, mrotation.y, mrotation.z));
|
|
|
|
if(pos[0] != float(mtranslation.x) ||
|
|
pos[1] != float(mtranslation.y) ||
|
|
pos[2] != float(mtranslation.z))
|
|
{
|
|
m_rigid_body->update_constraint();
|
|
}
|
|
|
|
data.setClean(plug);
|
|
|
|
//set the scale to the collision shape
|
|
m_rigid_body->collision_shape()->set_scale(vec3f(mscale[0], mscale[1], mscale[2]));
|
|
/*
|
|
MPlug plgCollisionShape(thisObject, ia_collisionShape);
|
|
//force evaluation of the shape
|
|
plgCollisionShape.getValue(update);
|
|
|
|
if(plgCollisionShape.isConnected()) {
|
|
MPlugArray connections;
|
|
plgCollisionShape.connectedTo(connections, true, true);
|
|
if(connections.length() != 0) {
|
|
MFnDependencyNode fnNode(connections[0].node());
|
|
if(fnNode.typeId() == collisionShapeNode::typeId) {
|
|
MPlug plgScale(fnNode.object(), collisionShapeNode::ia_scale);
|
|
plgScale.child(0).setValue(mscale[0]);
|
|
plgScale.child(1).setValue(mscale[1]);
|
|
plgScale.child(2).setValue(mscale[2]);
|
|
} else {
|
|
std::cout << "rigidBodyNode connected to a non-collision shape node!" << std::endl;
|
|
}
|
|
}
|
|
}*/
|
|
|
|
}
|
|
|
|
void rigidBodyNode::computeRigidBodyParam(const MPlug& plug, MDataBlock& data)
|
|
{
|
|
// std::cout << "rigidBodyNode::computeRigidBodyParam" << std::endl;
|
|
|
|
MObject thisObject(thisMObject());
|
|
MObject update;
|
|
|
|
MPlug(thisObject, ca_rigidBody).getValue(update);
|
|
double mass = data.inputValue(ia_mass).asDouble();
|
|
m_rigid_body->set_mass(mass);
|
|
m_rigid_body->set_inertia(mass * m_rigid_body->collision_shape()->local_inertia());
|
|
m_rigid_body->set_restitution(data.inputValue(ia_restitution).asDouble());
|
|
m_rigid_body->set_friction(data.inputValue(ia_friction).asDouble());
|
|
m_rigid_body->set_linear_damping(data.inputValue(ia_linearDamping).asDouble());
|
|
m_rigid_body->set_angular_damping(data.inputValue(ia_angularDamping).asDouble());
|
|
|
|
data.outputValue(ca_rigidBodyParam).set(true);
|
|
data.setClean(plug);
|
|
}
|
|
|
|
rigid_body_t::pointer rigidBodyNode::rigid_body()
|
|
{
|
|
// std::cout << "rigidBodyNode::rigid_body" << std::endl;
|
|
|
|
MObject thisObject(thisMObject());
|
|
MObject update;
|
|
MPlug(thisObject, ca_rigidBody).getValue(update);
|
|
MPlug(thisObject, ca_rigidBodyParam).getValue(update);
|
|
|
|
return m_rigid_body;
|
|
}
|
|
|
|
void rigidBodyNode::update()
|
|
{
|
|
MObject thisObject(thisMObject());
|
|
|
|
MObject update;
|
|
MPlug(thisObject, ca_rigidBody).getValue(update);
|
|
MPlug(thisObject, ca_rigidBodyParam).getValue(update);
|
|
MPlug(thisObject, ca_solver).getValue(update);
|
|
MPlug(thisObject, worldMatrix).elementByLogicalIndex(0).getValue(update);
|
|
// MPlug plg = MPlug(thisObject, worldMatrix).elementByLogicalIndex(0);
|
|
}
|