提交 e3628589 编写于 作者: R Rémi Arnaud

Merge pull request #405 from fl4re/fix/maya-physics-reversed-constraint

Fixed reversed constraint export + constraint transform
......@@ -74,6 +74,7 @@ namespace COLLADAMaya
COLLADASW::StreamWriter& getStreamWriter();
DocumentExporter& getDocumentExporter();
void exportTranslationWithoutConversion(const MVector & translation, const String & sid = "");
void exportTranslation(const MVector & translation, const String & sid = "");
void exportRotation(const MEulerRotation & rotation, const String & sid = "");
void exportAttributes(const MObject & object, const std::set<MString, MStringComp> & attributes);
......@@ -82,6 +83,7 @@ namespace COLLADAMaya
void exportRigidBodyPhysXXML(const MObject& shape);
void exportRigidConstraintPhysXXML(const MObject& constraint);
MObject getNodeRigidBody(const MObject& node);
MObject getShapeRigidBody(const MObject& shape);
void getShapeLocalPose(const MObject& rigidBody, const MObject& shape, MMatrix& localPose);
bool getShapeVertices(const MObject& shape, std::vector<PhysXXML::Point> & vertices, MString & meshId);
......@@ -140,14 +142,15 @@ namespace COLLADAMaya
PhysXXML::PxRigidStatic* findPxRigidStatic(const String& name);
PhysXXML::PxMaterial* findPxMaterial(uint64_t ref);
PhysXXML::PxMaterial* findPxMaterial(const MObject& rigidBody);
PhysXXML::PxShape* findPxShape(const MObject& rigidBody, const MObject& shape);
PhysXXML::PxRigidStatic* findPxRigidStatic(uint64_t id);
PhysXXML::PxRigidStatic* findPxRigidStatic(const MObject& rigidBody);
PhysXXML::PxRigidDynamic* findPxRigidDynamic(uint64_t id);
PhysXXML::PxRigidDynamic* findPxRigidDynamic(const MObject& rigidBody);
PhysXXML::PxD6Joint* findPxD6Joint(const MObject& rigidConstraint);
private:
PhysXXML::PxMaterial* findPxMaterial(const MObject& rigidBody);
PhysXXML::PxShape* findPxShape(const MObject& rigidBody, const MObject& shape);
PhysXXML::PxRigidStatic* findPxRigidStatic(const MObject& rigidBody);
PhysXXML::PxRigidDynamic* findPxRigidDynamic(const MObject& rigidBody);
PhysXXML::PxD6Joint* findPxD6Joint(const MObject& rigidConstraint);
void exportRotate(const MVector & axis, double angle, const String & sid = "");
static bool ElementHas(const SceneElement & element, SceneElement::Type type, Filter filter);
......
......@@ -1013,7 +1013,9 @@ namespace COLLADAMaya
PxMaterial* findMaterial(uint64_t ref);
PxMaterial* findMaterial(const String& bodyName, const String& shapeName);
PxShape* findShape(const String& bodyName, const String& shapeName);
PxRigidStatic* findRigidStatic(uint64_t id);
PxRigidStatic* findRigidStatic(const String& bodyName);
PxRigidDynamic* findRigidDynamic(uint64_t id);
PxRigidDynamic* findRigidDynamic(const String& bodyName);
PxD6Joint* findD6Joint(const String& jointName);
};
......
......@@ -652,6 +652,11 @@ namespace COLLADAMaya
return mPhysXDoc->findShape(targetName.asChar(), shapeName.asChar());
}
PhysXXML::PxRigidStatic* PhysXExporter::findPxRigidStatic(uint64_t id)
{
return mPhysXDoc->findRigidStatic(id);
}
PhysXXML::PxRigidStatic* PhysXExporter::findPxRigidStatic(const MObject& rigidBody)
{
MObject target;
......@@ -666,6 +671,11 @@ namespace COLLADAMaya
return mPhysXDoc->findRigidStatic(name);
}
PhysXXML::PxRigidDynamic* PhysXExporter::findPxRigidDynamic(uint64_t id)
{
return mPhysXDoc->findRigidDynamic(id);
}
PhysXXML::PxRigidDynamic* PhysXExporter::findPxRigidDynamic(const MObject& rigidBody)
{
MObject target;
......@@ -682,6 +692,54 @@ namespace COLLADAMaya
return mPhysXDoc->findD6Joint(constraintName.asChar());
}
MObject PhysXExporter::getNodeRigidBody(const MObject& node)
{
if (node.isNull())
return MObject::kNullObj;
class RigidBodyParser
{
public:
RigidBodyParser(PhysXExporter & exporter, const MObject & node)
: mPhysXExporter(exporter)
, mNode(node)
{}
bool operator()(SceneElement & element)
{
if (element.getType() == SceneElement::PHYSX_RIGID_BODY &&
element.getIsLocal())
{
const MObject & rigidBody = element.getNode();
MObject target;
mPhysXExporter.getRigidBodyTarget(rigidBody, target);
if (target == mNode)
{
mRigidBody = rigidBody;
return false;
}
}
return true;
}
const MObject & getRigidBody() const
{
return mRigidBody;
}
private:
PhysXExporter & mPhysXExporter;
const MObject & mNode;
MObject mRigidBody;
};
RigidBodyParser parser(*this, node);
parseSceneElements(parser);
return parser.getRigidBody();
}
MObject PhysXExporter::getShapeRigidBody(const MObject& shape)
{
class FindShapeRigidBody
......@@ -2101,39 +2159,16 @@ namespace COLLADAMaya
private:
void exportRotateTranslate(const MObject & rigidConstraint)
{
// get attached rigid body (parent)
MObject ref;
PhysXExporter::GetPluggedObject(rigidConstraint, ATTR_RIGID_BODY_1, ref);
PhysXXML::PxD6Joint* pxJoint = getPhysXExporter().findPxD6Joint(rigidConstraint);
if (!pxJoint)
return;
MMatrix refLocalToWorld = MMatrix::identity;
if (!ref.isNull())
{
MDagPath refDagPath;
MDagPath::getAPathTo(ref, refDagPath);
refLocalToWorld = refDagPath.inclusiveMatrix();
}
MVector translation = pxJoint->localPose.eActor0.translation;
MEulerRotation rotation;
rotation = pxJoint->localPose.eActor0.rotation;
MDagPath constraintDagPath;
MDagPath::getAPathTo(rigidConstraint, constraintDagPath);
MMatrix constraintLocalToWorld = constraintDagPath.inclusiveMatrix();
MMatrix constraintLocalToRef = constraintLocalToWorld * refLocalToWorld.inverse();
MTransformationMatrix constraintLocalToRefTM(constraintLocalToRef);
MVector translation = constraintLocalToRefTM.getTranslation(MSpace::kTransform);
double angles[3];
MTransformationMatrix::RotationOrder rotationOrder;
constraintLocalToRefTM.getRotation(angles, rotationOrder);
MEulerRotation rotation;
rotation.x = angles[0];
rotation.y = angles[1];
rotation.z = angles[2];
rotation.order = static_cast<MEulerRotation::RotationOrder>(
static_cast<int>(rotationOrder)-MTransformationMatrix::kXYZ + MEulerRotation::kXYZ
);
getPhysXExporter().exportTranslation(translation, ATTR_TRANSLATE);
getPhysXExporter().exportRotation(rotation, ATTR_ROTATE);
getPhysXExporter().exportRotation(rotation, ATTR_ROTATE);
getPhysXExporter().exportTranslationWithoutConversion(translation, ATTR_TRANSLATE);
}
};
......@@ -2152,86 +2187,13 @@ namespace COLLADAMaya
private:
void exportRotateTranslate(const MObject & rigidConstraint)
{
// get attached rigid body (child)
MObject attachment;
PhysXExporter::GetPluggedObject(rigidConstraint, ATTR_RIGID_BODY_2, attachment);
MDagPath constraintDagPath;
MDagPath attachmentDagPath;
MDagPath::getAPathTo(rigidConstraint, constraintDagPath);
MDagPath::getAPathTo(attachment, attachmentDagPath);
MMatrix constraintLocalToWorld = constraintDagPath.inclusiveMatrix();
MMatrix attachmentLocalToWorld = attachmentDagPath.inclusiveMatrix();
MTransformationMatrix constraintLocalToWorldTM(constraintLocalToWorld);
MTransformationMatrix attachmentLocalToWorldTM(attachmentLocalToWorld);
int dummy = 0;
MString orientationMode;
DagHelper::getPlugValue(rigidConstraint, ATTR_ORIENTATION_MODE, dummy, orientationMode);
if (orientationMode == TARGET_ORIGIN)
{
// World space target origin
MVector targetOrigin = attachmentLocalToWorldTM.translation(MSpace::kTransform);
PhysXXML::PxD6Joint* pxJoint = getPhysXExporter().findPxD6Joint(rigidConstraint);
MVector translation = pxJoint->localPose.eActor1.translation;
MEulerRotation rotation;
rotation = pxJoint->localPose.eActor1.rotation;
// World space constraint origin
MVector constraintOrigin = constraintLocalToWorldTM.translation(MSpace::kTransform);
MVector x = targetOrigin - constraintOrigin;
// if target origin and constraint origin are at the same place, we'll get wrong results
if (x.length() < getPhysXExporter().getDocumentExporter().getTolerance()) {
MGlobal::displayWarning("constraint origin and target origin too close");
}
x.normalize();
MVector z = constraintLocalToWorld[2];
MVector y = z ^ x;
y.normalize();
z = x ^ y;
z.normalize();
MMatrix adjustedConstraintLocalToWorld = MMatrix::identity;
adjustedConstraintLocalToWorld(0, 0) = x.x;
adjustedConstraintLocalToWorld(0, 1) = x.y;
adjustedConstraintLocalToWorld(0, 2) = x.z;
adjustedConstraintLocalToWorld(1, 0) = y.x;
adjustedConstraintLocalToWorld(1, 1) = y.y;
adjustedConstraintLocalToWorld(1, 2) = y.z;
adjustedConstraintLocalToWorld(2, 0) = z.x;
adjustedConstraintLocalToWorld(2, 1) = z.y;
adjustedConstraintLocalToWorld(2, 2) = z.z;
adjustedConstraintLocalToWorld(3, 0) = constraintOrigin.x;
adjustedConstraintLocalToWorld(3, 1) = constraintOrigin.y;
adjustedConstraintLocalToWorld(3, 2) = constraintOrigin.z;
MMatrix constraintLocalToAttachment = adjustedConstraintLocalToWorld * attachmentLocalToWorld.inverse();
MTransformationMatrix constraintLocalToAttachmentTM(constraintLocalToAttachment);
MVector translation = constraintLocalToAttachmentTM.getTranslation(MSpace::kTransform);
double angles[3];
MTransformationMatrix::RotationOrder rotationOrder;
constraintLocalToAttachmentTM.getRotation(angles, rotationOrder);
MEulerRotation rotation;
rotation.x = angles[0];
rotation.y = angles[1];
rotation.z = angles[2];
rotation.order = static_cast<MEulerRotation::RotationOrder>(
static_cast<int>(rotationOrder)-MTransformationMatrix::kXYZ + MEulerRotation::kXYZ
);
getPhysXExporter().exportTranslation(translation, ATTR_TRANSLATE);
getPhysXExporter().exportRotation(rotation, ATTR_ROTATE);
}
else if (orientationMode == CENTERED)
{
// TODO
}
getPhysXExporter().exportRotation(rotation, ATTR_ROTATE);
getPhysXExporter().exportTranslationWithoutConversion(translation, ATTR_TRANSLATE);
}
};
......@@ -2359,8 +2321,23 @@ namespace COLLADAMaya
private:
void exportRefAttachment(const MObject & rigidConstraint)
{
MObject rigidBody;
PhysXExporter::GetPluggedObject(rigidConstraint, ATTR_RIGID_BODY_1, rigidBody);
PhysXXML::PxD6Joint* pxJoint = getPhysXExporter().findPxD6Joint(rigidConstraint);
if (!pxJoint)
return;
PhysXXML::PxRigidDynamic* pxRigidDynamic = getPhysXExporter().findPxRigidDynamic(pxJoint->actors.actor0.actor0);
PhysXXML::PxRigidStatic* pxRigidStatic = getPhysXExporter().findPxRigidStatic(pxJoint->actors.actor0.actor0);
MObject target;
if (pxRigidDynamic)
{
target = DagHelper::getNode(pxRigidDynamic->name.name.c_str());
}
else if (pxRigidStatic)
{
target = DagHelper::getNode(pxRigidStatic->name.name.c_str());
}
MObject rigidBody = getPhysXExporter().getNodeRigidBody(target);
URI rigidBodyURI;
if (rigidBody.isNull())
......@@ -2381,8 +2358,23 @@ namespace COLLADAMaya
void exportAttachment(const MObject & rigidConstraint)
{
MObject rigidBody;
PhysXExporter::GetPluggedObject(rigidConstraint, ATTR_RIGID_BODY_2, rigidBody);
PhysXXML::PxD6Joint* pxJoint = getPhysXExporter().findPxD6Joint(rigidConstraint);
if (!pxJoint)
return;
PhysXXML::PxRigidDynamic* pxRigidDynamic = getPhysXExporter().findPxRigidDynamic(pxJoint->actors.actor1.actor1);
PhysXXML::PxRigidStatic* pxRigidStatic = getPhysXExporter().findPxRigidStatic(pxJoint->actors.actor1.actor1);
MObject target;
if (pxRigidDynamic)
{
target = DagHelper::getNode(pxRigidDynamic->name.name.c_str());
}
else if (pxRigidStatic)
{
target = DagHelper::getNode(pxRigidStatic->name.name.c_str());
}
MObject rigidBody = getPhysXExporter().getNodeRigidBody(target);
MDagPath rigidBodyDagPath;
MDagPath::getAPathTo(rigidBody, rigidBodyDagPath);
......@@ -3404,6 +3396,16 @@ namespace COLLADAMaya
return mDocumentExporter;
}
void PhysXExporter::exportTranslationWithoutConversion(const MVector & translation, const String & sid)
{
if (!(COLLADABU::Math::Utils::equalsZero(translation.x, mDocumentExporter.getTolerance()) &&
COLLADABU::Math::Utils::equalsZero(translation.y, mDocumentExporter.getTolerance()) &&
COLLADABU::Math::Utils::equalsZero(translation.z, mDocumentExporter.getTolerance())))
{
Translate(*this, translation, sid);
}
}
void PhysXExporter::exportTranslation(const MVector & translation, const String & sid)
{
if (!(COLLADABU::Math::Utils::equalsZero(translation.x, mDocumentExporter.getTolerance()) &&
......
......@@ -2308,6 +2308,17 @@ namespace COLLADAMaya
return NULL;
}
PxRigidStatic* PhysXDoc::findRigidStatic(uint64_t id)
{
for (size_t i = 0; i < physX30Collection.rigidStatics.size(); ++i) {
PxRigidStatic& rigid = physX30Collection.rigidStatics[i];
if (rigid.id.id == id) {
return &rigid;
}
}
return NULL;
}
PxRigidStatic* PhysXDoc::findRigidStatic(const String& bodyName)
{
for (size_t i = 0; i < physX30Collection.rigidStatics.size(); ++i) {
......@@ -2319,6 +2330,17 @@ namespace COLLADAMaya
return NULL;
}
PxRigidDynamic* PhysXDoc::findRigidDynamic(uint64_t id)
{
for (size_t i = 0; i < physX30Collection.rigidDynamics.size(); ++i) {
PxRigidDynamic& rigid = physX30Collection.rigidDynamics[i];
if (rigid.id.id == id) {
return &rigid;
}
}
return NULL;
}
PxRigidDynamic* PhysXDoc::findRigidDynamic(const String& bodyName)
{
for (size_t i = 0; i < physX30Collection.rigidDynamics.size(); ++i) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册