Crash bug when "mesh" applied twice fixed
Constraints reworked - all of them could now work with one or two bodies Modification of constraint frames and initial positions of rigid bodies now allowed at start frame only Plugin version is set to 2.76
This commit is contained in:
@@ -18,6 +18,9 @@ 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>
|
||||
|
||||
Modified by Roman Ponomarev <rponom@gmail.com>
|
||||
01/22/2010 : Constraints reworked
|
||||
*/
|
||||
|
||||
//hingeConstraintNode.cpp
|
||||
@@ -39,18 +42,25 @@ Written by: Herbert Law <Herbert.Law@gmail.com>
|
||||
#include "mayaUtils.h"
|
||||
|
||||
#include "solver.h"
|
||||
#include "dSolverNode.h"
|
||||
#include "constraint/bt_hinge_constraint.h"
|
||||
|
||||
MTypeId hingeConstraintNode::typeId(0x10033B);
|
||||
MString hingeConstraintNode::typeName("dHingeConstraint");
|
||||
|
||||
MObject hingeConstraintNode::ia_rigidBody;
|
||||
MObject hingeConstraintNode::ia_rigidBodyA;
|
||||
MObject hingeConstraintNode::ia_rigidBodyB;
|
||||
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_rotationInA;
|
||||
MObject hingeConstraintNode::ia_rotationInB;
|
||||
|
||||
MObject hingeConstraintNode::ia_pivotInA;
|
||||
MObject hingeConstraintNode::ia_pivotInB;
|
||||
|
||||
MObject hingeConstraintNode::ia_enableAngularMotor;
|
||||
MObject hingeConstraintNode::ia_motorTargetVelocity;
|
||||
@@ -66,10 +76,15 @@ MStatus hingeConstraintNode::initialize()
|
||||
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_rigidBodyA = fnMsgAttr.create("inRigidBodyA", "inrba", &status);
|
||||
MCHECKSTATUS(status, "creating inRigidBodyA attribute")
|
||||
status = addAttribute(ia_rigidBodyA);
|
||||
MCHECKSTATUS(status, "adding inRigidBodyA 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")
|
||||
@@ -77,13 +92,13 @@ MStatus hingeConstraintNode::initialize()
|
||||
status = addAttribute(ia_damping);
|
||||
MCHECKSTATUS(status, "adding damping attribute")
|
||||
|
||||
ia_lowerLimit = fnNumericAttr.create("lowerLimit", "llmt", MFnNumericData::kDouble, -1.57, &status);
|
||||
ia_lowerLimit = fnNumericAttr.create("lowerLimit", "llmt", MFnNumericData::kDouble, -90.0, &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);
|
||||
ia_upperLimit = fnNumericAttr.create("upperLimit", "ulmt", MFnNumericData::kDouble, 90.0, &status);
|
||||
MCHECKSTATUS(status, "creating upper limit attribute")
|
||||
fnNumericAttr.setKeyable(true);
|
||||
status = addAttribute(ia_upperLimit);
|
||||
@@ -107,11 +122,30 @@ MStatus hingeConstraintNode::initialize()
|
||||
status = addAttribute(ia_relaxationFactor);
|
||||
MCHECKSTATUS(status, "adding relaxationFactor attribute")
|
||||
|
||||
ia_hingeAxis = fnNumericAttr.createPoint("hingeAxis", "hgAx", &status);
|
||||
status = fnNumericAttr.setDefault((double) 0.0, (double) 0.0, (double) 1.0);
|
||||
MCHECKSTATUS(status, "creating hingeAxis attribute")
|
||||
status = addAttribute(ia_hingeAxis);
|
||||
MCHECKSTATUS(status, "adding hingeAxis attribute")
|
||||
ia_rotationInA = fnNumericAttr.createPoint("rotationInA", "hgRotA", &status);
|
||||
status = fnNumericAttr.setDefault((double) 0.0, (double) 0.0, (double) 0.0);
|
||||
MCHECKSTATUS(status, "creating rotationInA attribute")
|
||||
status = addAttribute(ia_rotationInA);
|
||||
MCHECKSTATUS(status, "adding rotationInA attribute")
|
||||
|
||||
ia_rotationInB = fnNumericAttr.createPoint("rotationInB", "hgRotB", &status);
|
||||
status = fnNumericAttr.setDefault((double) 0.0, (double) 0.0, (double) 0.0);
|
||||
MCHECKSTATUS(status, "creating rotationInB attribute")
|
||||
status = addAttribute(ia_rotationInB);
|
||||
MCHECKSTATUS(status, "adding rotationInB attribute")
|
||||
|
||||
ia_pivotInA = fnNumericAttr.createPoint("pivotInA", "pivinA", &status);
|
||||
status = fnNumericAttr.setDefault((double) 0.0, (double) 0.0, (double) 0.0);
|
||||
MCHECKSTATUS(status, "creating pivotInA attribute")
|
||||
status = addAttribute(ia_pivotInA);
|
||||
MCHECKSTATUS(status, "adding pivotInA attribute")
|
||||
|
||||
ia_pivotInB = fnNumericAttr.createPoint("pivotInB", "pivinB", &status);
|
||||
status = fnNumericAttr.setDefault((double) 0.0, (double) 0.0, (double) 0.0);
|
||||
MCHECKSTATUS(status, "creating pivotInB attribute")
|
||||
status = addAttribute(ia_pivotInB);
|
||||
MCHECKSTATUS(status, "adding pivotInB attribute")
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -153,11 +187,17 @@ MStatus hingeConstraintNode::initialize()
|
||||
MCHECKSTATUS(status, "adding ca_constraintParam attribute")
|
||||
|
||||
|
||||
status = attributeAffects(ia_rigidBody, ca_constraint);
|
||||
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBody, ca_constraint)")
|
||||
status = attributeAffects(ia_rigidBodyA, ca_constraint);
|
||||
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBodyA, ca_constraint)")
|
||||
|
||||
status = attributeAffects(ia_rigidBody, ca_constraintParam);
|
||||
MCHECKSTATUS(status, "adding attributeAffects(ia_rigidBody, ca_constraintParam)")
|
||||
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)")
|
||||
@@ -175,8 +215,16 @@ MStatus hingeConstraintNode::initialize()
|
||||
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_rotationInA, ca_constraintParam);
|
||||
MCHECKSTATUS(status, "adding attributeAffects(ia_rotationInA, ca_constraintParam)")
|
||||
status = attributeAffects(ia_rotationInB, ca_constraintParam);
|
||||
MCHECKSTATUS(status, "adding attributeAffects(ia_rotationInB, ca_constraintParam)")
|
||||
|
||||
status = attributeAffects(ia_pivotInA, ca_constraintParam);
|
||||
MCHECKSTATUS(status, "adding attributeAffects(ia_pivotInA, ca_constraintParam)")
|
||||
status = attributeAffects(ia_pivotInB, ca_constraintParam);
|
||||
MCHECKSTATUS(status, "adding attributeAffects(ia_pivotInB, ca_constraintParam)")
|
||||
|
||||
|
||||
status = attributeAffects(ia_enableAngularMotor, ca_constraintParam);
|
||||
MCHECKSTATUS(status, "adding attributeAffects(ia_enableAngularMotor, ca_constraintParam)")
|
||||
@@ -203,7 +251,21 @@ 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);
|
||||
if (pNode->m_constraint)
|
||||
{
|
||||
bt_hinge_constraint_t* hinge_impl = dynamic_cast<bt_hinge_constraint_t*>(pNode->m_constraint->pubImpl());
|
||||
rigid_body_t::pointer rigid_bodyA = pNode->m_constraint->rigid_bodyA();
|
||||
if(rigid_bodyA)
|
||||
{
|
||||
rigid_bodyA->remove_constraint(hinge_impl);
|
||||
}
|
||||
rigid_body_t::pointer rigid_bodyB = pNode->m_constraint->rigid_bodyB();
|
||||
if(rigid_bodyB)
|
||||
{
|
||||
rigid_bodyB->remove_constraint(hinge_impl);
|
||||
}
|
||||
}
|
||||
constraint_t::pointer constraint = static_cast<constraint_t::pointer>(pNode->m_constraint);
|
||||
solver_t::remove_constraint(constraint);
|
||||
}
|
||||
|
||||
@@ -265,19 +327,37 @@ void hingeConstraintNode::draw( M3dView & view, const MDagPath &path,
|
||||
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;
|
||||
vec3f posA, posB, pivB;
|
||||
rigid_body_t::pointer rigid_bodyB = NULL;
|
||||
if (m_constraint)
|
||||
{
|
||||
vec3f pos;
|
||||
quatf rot;
|
||||
m_constraint->rigid_bodyA()->get_transform(pos, rot);
|
||||
m_constraint->worldToA(pos, posA);
|
||||
rigid_bodyB = m_constraint->rigid_bodyB();
|
||||
if(rigid_bodyB)
|
||||
{
|
||||
rigid_bodyB->get_transform(pos, rot);
|
||||
m_constraint->worldToA(pos, posB);
|
||||
}
|
||||
m_constraint->worldFromB(vec3f(0.f, 0.f, 0.f), pos);
|
||||
m_constraint->worldToA(pos, pivB);
|
||||
}
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glVertex3f(pos[0], pos[1], pos[2]);
|
||||
glVertex3f(posA[0], posA[1], posA[2]);
|
||||
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
glVertex3f(pivB[0], pivB[1], pivB[2]);
|
||||
|
||||
if(rigid_bodyB)
|
||||
{
|
||||
glVertex3f(pivB[0], pivB[1], pivB[2]);
|
||||
glVertex3f(posB[0], posB[1], posB[2]);
|
||||
}
|
||||
|
||||
|
||||
glVertex3f(-1.0, 0.0, 0.0);
|
||||
glVertex3f(1.0, 0.0, 0.0);
|
||||
@@ -287,6 +367,29 @@ void hingeConstraintNode::draw( M3dView & view, const MDagPath &path,
|
||||
|
||||
glVertex3f(0.0, 0.0, -1.0);
|
||||
glVertex3f(0.0, 0.0, 1.0);
|
||||
|
||||
vec3f posT, posP, posM;
|
||||
|
||||
m_constraint->worldFromB(vec3f(-1.f, 0.f, 0.f), posT);
|
||||
m_constraint->worldToA(posT, posM);
|
||||
m_constraint->worldFromB(vec3f( 1.f, 0.f, 0.f), posT);
|
||||
m_constraint->worldToA(posT, posP);
|
||||
glVertex3f(posM[0], posM[1], posM[2]);
|
||||
glVertex3f(posP[0], posP[1], posP[2]);
|
||||
m_constraint->worldFromB(vec3f( 0.f, -1.f, 0.f), posT);
|
||||
m_constraint->worldToA(posT, posM);
|
||||
m_constraint->worldFromB(vec3f( 0.f, 1.f, 0.f), posT);
|
||||
m_constraint->worldToA(posT, posP);
|
||||
glVertex3f(posM[0], posM[1], posM[2]);
|
||||
glVertex3f(posP[0], posP[1], posP[2]);
|
||||
m_constraint->worldFromB(vec3f( 0.f, 0.f, -1.f), posT);
|
||||
m_constraint->worldToA(posT, posM);
|
||||
m_constraint->worldFromB(vec3f( 0.f, 0.f, 1.f), posT);
|
||||
m_constraint->worldToA(posT, posP);
|
||||
glVertex3f(posM[0], posM[1], posM[2]);
|
||||
glVertex3f(posP[0], posP[1], posP[2]);
|
||||
|
||||
|
||||
glEnd();
|
||||
|
||||
glPopAttrib();
|
||||
@@ -316,31 +419,82 @@ void hingeConstraintNode::computeConstraint(const MPlug& plug, MDataBlock& data)
|
||||
// std::cout << "hingeConstraintNode::computeConstraint" << std::endl;
|
||||
|
||||
MObject thisObject(thisMObject());
|
||||
MPlug plgRigidBody(thisObject, ia_rigidBody);
|
||||
MPlug plgRigidBodyA(thisObject, ia_rigidBodyA);
|
||||
MPlug plgRigidBodyB(thisObject, ia_rigidBodyB);
|
||||
MObject update;
|
||||
//force evaluation of the rigidBody
|
||||
plgRigidBody.getValue(update);
|
||||
plgRigidBodyA.getValue(update);
|
||||
plgRigidBodyB.getValue(update);
|
||||
|
||||
rigid_body_t::pointer rigid_body;
|
||||
if(plgRigidBody.isConnected()) {
|
||||
rigid_body_t::pointer rigid_bodyA;
|
||||
if(plgRigidBodyA.isConnected()) {
|
||||
MPlugArray connections;
|
||||
plgRigidBody.connectedTo(connections, true, true);
|
||||
plgRigidBodyA.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();
|
||||
rigidBodyNode *pRigidBodyNodeA = static_cast<rigidBodyNode*>(fnNode.userNode());
|
||||
rigid_bodyA = pRigidBodyNodeA->rigid_body();
|
||||
} else {
|
||||
std::cout << "hingeConstraintNode connected to a non-rigidbody node!" << std::endl;
|
||||
std::cout << "hingeConstraintNode connected to a non-rigidbody node A!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
rigid_body_t::pointer rigid_bodyB;
|
||||
if(plgRigidBodyB.isConnected()) {
|
||||
MPlugArray connections;
|
||||
plgRigidBodyB.connectedTo(connections, true, true);
|
||||
if(connections.length() != 0) {
|
||||
MFnDependencyNode fnNode(connections[0].node());
|
||||
if(fnNode.typeId() == rigidBodyNode::typeId) {
|
||||
rigidBodyNode *pRigidBodyNodeB = static_cast<rigidBodyNode*>(fnNode.userNode());
|
||||
rigid_bodyB = pRigidBodyNodeB->rigid_body();
|
||||
} else {
|
||||
std::cout << "hingeConstraintNode connected to a non-rigidbody node B!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(rigid_body) {
|
||||
vec3f pivInA, pivInB;
|
||||
|
||||
if((rigid_bodyA != NULL) && (rigid_bodyB != NULL))
|
||||
{
|
||||
constraint_t::pointer constraint = static_cast<constraint_t::pointer>(m_constraint);
|
||||
solver_t::remove_constraint(constraint);
|
||||
float3& mPivInA = data.inputValue(ia_pivotInA).asFloat3();
|
||||
float3& mPivInB = data.inputValue(ia_pivotInB).asFloat3();
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
pivInA[i] = (float)mPivInA[i];
|
||||
pivInB[i] = (float)mPivInB[i];
|
||||
}
|
||||
float3& mRotInA = data.inputValue(ia_rotationInA).asFloat3();
|
||||
MEulerRotation meulerA(deg2rad(mRotInA[0]), deg2rad(mRotInA[1]), deg2rad(mRotInA[2]));
|
||||
MQuaternion mquatA = meulerA.asQuaternion();
|
||||
quatf rotA((float)mquatA.w, (float)mquatA.x, (float)mquatA.y, (float)mquatA.z);
|
||||
float3& mRotInB = data.inputValue(ia_rotationInB).asFloat3();
|
||||
MEulerRotation meulerB(deg2rad(mRotInB[0]), deg2rad(mRotInB[1]), deg2rad(mRotInB[2]));
|
||||
MQuaternion mquatB = meulerB.asQuaternion();
|
||||
quatf rotB((float)mquatB.w, (float)mquatB.x, (float)mquatB.y, (float)mquatB.z);
|
||||
m_constraint = solver_t::create_hinge_constraint(rigid_bodyA, pivInA, rotA, rigid_bodyB, pivInB, rotB);
|
||||
constraint = static_cast<constraint_t::pointer>(m_constraint);
|
||||
solver_t::add_constraint(constraint);
|
||||
}
|
||||
else if(rigid_bodyA != NULL)
|
||||
{
|
||||
//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);
|
||||
float3& mPivInA = data.inputValue(ia_pivotInA).asFloat3();
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
pivInA[i] = (float)mPivInA[i];
|
||||
}
|
||||
float3& mRotInA = data.inputValue(ia_rotationInA).asFloat3();
|
||||
MEulerRotation meuler(deg2rad(mRotInA[0]), deg2rad(mRotInA[1]), deg2rad(mRotInA[2]));
|
||||
MQuaternion mquat = meuler.asQuaternion();
|
||||
quatf rotA((float)mquat.w, (float)mquat.x, (float)mquat.y, (float)mquat.z);
|
||||
m_constraint = solver_t::create_hinge_constraint(rigid_bodyA, pivInA, rotA);
|
||||
constraint = static_cast<constraint_t::pointer>(m_constraint);
|
||||
solver_t::add_constraint(constraint);
|
||||
}
|
||||
@@ -349,11 +503,8 @@ void hingeConstraintNode::computeConstraint(const MPlug& plug, MDataBlock& data)
|
||||
data.setClean(plug);
|
||||
}
|
||||
|
||||
|
||||
void hingeConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data)
|
||||
{
|
||||
// std::cout << "hingeConstraintNode::computeWorldMatrix" << std::endl;
|
||||
|
||||
MObject thisObject(thisMObject());
|
||||
MFnDagNode fnDagNode(thisObject);
|
||||
|
||||
@@ -361,31 +512,117 @@ void hingeConstraintNode::computeWorldMatrix(const MPlug& plug, MDataBlock& data
|
||||
MPlug(thisObject, ca_constraint).getValue(update);
|
||||
MPlug(thisObject, ca_constraintParam).getValue(update);
|
||||
|
||||
|
||||
MStatus status;
|
||||
|
||||
MFnTransform fnParentTransform(fnDagNode.parent(0, &status));
|
||||
|
||||
double fixScale[3] = { 1., 1., 1. }; // lock scale
|
||||
fnParentTransform.setScale(fixScale);
|
||||
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]));
|
||||
}
|
||||
}
|
||||
|
||||
if(dSolverNode::isStartTime)
|
||||
{ // allow to edit pivots
|
||||
MPlug plgRigidBodyA(thisObject, ia_rigidBodyA);
|
||||
MPlug plgRigidBodyB(thisObject, ia_rigidBodyB);
|
||||
MObject update;
|
||||
//force evaluation of the rigidBody
|
||||
plgRigidBodyA.getValue(update);
|
||||
if(plgRigidBodyA.isConnected())
|
||||
{
|
||||
MPlugArray connections;
|
||||
plgRigidBodyA.connectedTo(connections, true, true);
|
||||
if(connections.length() != 0)
|
||||
{
|
||||
MFnDependencyNode fnNode(connections[0].node());
|
||||
if(fnNode.typeId() == rigidBodyNode::typeId)
|
||||
{
|
||||
MObject rbAObj = fnNode.object();
|
||||
rigidBodyNode *pRigidBodyNodeA = static_cast<rigidBodyNode*>(fnNode.userNode());
|
||||
MPlug(rbAObj, pRigidBodyNodeA->worldMatrix).elementByLogicalIndex(0).getValue(update);
|
||||
}
|
||||
}
|
||||
}
|
||||
plgRigidBodyB.getValue(update);
|
||||
if(plgRigidBodyB.isConnected())
|
||||
{
|
||||
MPlugArray connections;
|
||||
plgRigidBodyB.connectedTo(connections, true, true);
|
||||
if(connections.length() != 0)
|
||||
{
|
||||
MFnDependencyNode fnNode(connections[0].node());
|
||||
if(fnNode.typeId() == rigidBodyNode::typeId)
|
||||
{
|
||||
MObject rbBObj = fnNode.object();
|
||||
rigidBodyNode *pRigidBodyNodeB = static_cast<rigidBodyNode*>(fnNode.userNode());
|
||||
MPlug(rbBObj, pRigidBodyNodeB->worldMatrix).elementByLogicalIndex(0).getValue(update);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_constraint)
|
||||
{
|
||||
MQuaternion mrotation;
|
||||
fnParentTransform.getRotation(mrotation, MSpace::kTransform);
|
||||
bool doUpdatePivot = m_constraint->getPivotChanged();
|
||||
if(!doUpdatePivot)
|
||||
{
|
||||
vec3f worldP;
|
||||
quatf worldR;
|
||||
m_constraint->get_world(worldP, worldR);
|
||||
float deltaPX = worldP[0] - float(mtranslation.x);
|
||||
float deltaPY = worldP[1] - float(mtranslation.y);
|
||||
float deltaPZ = worldP[2] - float(mtranslation.z);
|
||||
float deltaRX = (float)mrotation.x - worldR[1];
|
||||
float deltaRY = (float)mrotation.y - worldR[2];
|
||||
float deltaRZ = (float)mrotation.z - worldR[3];
|
||||
float deltaRW = (float)mrotation.w - worldR[0];
|
||||
float deltaSq = deltaPX * deltaPX + deltaPY * deltaPY + deltaPZ * deltaPZ
|
||||
+ deltaRX * deltaRX + deltaRY * deltaRY + deltaRZ * deltaRZ + deltaRW * deltaRW;
|
||||
doUpdatePivot = (deltaSq > FLT_EPSILON);
|
||||
}
|
||||
if(doUpdatePivot)
|
||||
{
|
||||
m_constraint->set_world(vec3f((float) mtranslation[0], (float) mtranslation[1], (float) mtranslation[2]),
|
||||
quatf((float)mrotation.w, (float)mrotation.x, (float)mrotation.y, (float)mrotation.z));
|
||||
vec3f pivInA, pivInB;
|
||||
quatf rotInA, rotInB;
|
||||
m_constraint->get_frameA(pivInA, rotInA);
|
||||
m_constraint->get_frameB(pivInB, rotInB);
|
||||
MDataHandle hPivInA = data.outputValue(ia_pivotInA);
|
||||
float3 &ihPivInA = hPivInA.asFloat3();
|
||||
MDataHandle hPivInB = data.outputValue(ia_pivotInB);
|
||||
float3 &ihPivInB = hPivInB.asFloat3();
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
ihPivInA[i] = pivInA[i];
|
||||
ihPivInB[i] = pivInB[i];
|
||||
}
|
||||
MDataHandle hRotInA = data.outputValue(ia_rotationInA);
|
||||
float3 &hrotInA = hRotInA.asFloat3();
|
||||
MQuaternion mrotA(rotInA[1], rotInA[2], rotInA[3], rotInA[0]);
|
||||
MEulerRotation newrotA(mrotA.asEulerRotation());
|
||||
hrotInA[0] = rad2deg((float)newrotA.x);
|
||||
hrotInA[1] = rad2deg((float)newrotA.y);
|
||||
hrotInA[2] = rad2deg((float)newrotA.z);
|
||||
MDataHandle hRotInB = data.outputValue(ia_rotationInB);
|
||||
float3 &hrotInB = hRotInB.asFloat3();
|
||||
MQuaternion mrotB(rotInB[1], rotInB[2], rotInB[3], rotInB[0]);
|
||||
MEulerRotation newrotB(mrotB.asEulerRotation());
|
||||
hrotInB[0] = rad2deg((float)newrotB.x);
|
||||
hrotInB[1] = rad2deg((float)newrotB.y);
|
||||
hrotInB[2] = rad2deg((float)newrotB.z);
|
||||
m_constraint->setPivotChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // if not start time, lock position and rotation
|
||||
if(m_constraint)
|
||||
{
|
||||
vec3f worldP;
|
||||
quatf worldR;
|
||||
m_constraint->get_world(worldP, worldR);
|
||||
fnParentTransform.setTranslation(MVector(worldP[0], worldP[1], worldP[2]), MSpace::kTransform);
|
||||
fnParentTransform.setRotation(MQuaternion(worldR[1], worldR[2], worldR[3], worldR[0]));
|
||||
}
|
||||
}
|
||||
data.setClean(plug);
|
||||
}
|
||||
|
||||
@@ -405,12 +642,7 @@ void hingeConstraintNode::computeConstraintParam(const MPlug& plug, MDataBlock&
|
||||
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]));
|
||||
|
||||
m_constraint->set_limit(deg2rad(lower), deg2rad(upper), limit_softness, bias_factor, relaxation_factor);
|
||||
bool enable_motor = data.inputValue(ia_enableAngularMotor).asBool();
|
||||
float motorTargetVelocity = (float) data.inputValue(ia_motorTargetVelocity).asDouble();
|
||||
float maxMotorImpulse = (float) data.inputValue(ia_maxMotorImpulse).asDouble();
|
||||
|
||||
Reference in New Issue
Block a user