1 /* 2 Copyright (c) 2015 Starbreeze 3 4 This file is part of COLLADAMaya. 5 6 Portions of the code are: 7 Copyright (c) 2005-2007 Feeling Software Inc. 8 Copyright (c) 2005-2007 Sony Computer Entertainment America 9 Copyright (c) 2004-2005 Alias Systems Corp. 10 11 Licensed under the MIT Open Source License, 12 for details please see LICENSE file or the website 13 http://www.opensource.org/licenses/mit-license.php 14 */ 15 #ifndef __COLLADA_MAYA_PHYSX_EXPORTER_H__ 16 #define __COLLADA_MAYA_PHYSX_EXPORTER_H__ 17 18 #include "COLLADAMayaDocumentExporter.h" 19 #include "COLLADAMayaPhysXXML.h" 20 #include "COLLADAMayaSceneElement.h" 21 #include "COLLADAMayaSceneGraph.h" 22 #include "COLLADASWLibraryPhysicsModels.h" 23 24 template<> 25 class std::less <MObject> 26 { 27 public: operator()28 bool operator()(const MObject & l, const MObject & r) const 29 { 30 const int* pl = *reinterpret_cast<const int* const*>(&l); 31 const int* pr = *reinterpret_cast<const int* const*>(&r); 32 return pl < pr; 33 } 34 }; 35 36 namespace COLLADAMaya 37 { 38 // Unit for mass: kg 39 // Unit for density: g/cm3 40 41 class MStringComp 42 { 43 public: operator()44 bool operator()(const MString & a, const MString & b) const 45 { 46 return strcmp(a.asChar(), b.asChar()) < 0; 47 } 48 }; 49 50 class PhysXShape 51 { 52 public: 53 static void GetType(const MObject & shape, MString & type); 54 static void GetInMesh(const MObject & shape, MObject & mesh); 55 static void GetConnectedInMesh(const MObject & shape, MObject & mesh); 56 }; 57 58 class PhysXExporter 59 { 60 public: 61 PhysXExporter(COLLADASW::StreamWriter& streamWriter, DocumentExporter& documentExporter); 62 63 static bool CheckPhysXPluginVersion(); 64 static MString GetRequiredPhysXPluginVersion(); 65 static MString GetInstalledPhysXPluginVersion(); 66 67 bool generatePhysXXML(); 68 bool needsConvexHullOf(const SceneElement & element, MObject & shape); 69 bool exportPhysicsLibraries(); 70 71 COLLADASW::StreamWriter& getStreamWriter(); 72 DocumentExporter& getDocumentExporter(); 73 74 void exportTranslationWithoutConversion(const MVector & translation, const String & sid = ""); 75 void exportTranslation(const MVector & translation, const String & sid = ""); 76 void exportRotation(const MEulerRotation & rotation, const String & sid = ""); 77 void exportAttributes(const MObject & object, const std::set<MString, MStringComp> & attributes); 78 void exportExtraAttributes(const MObject & object); 79 80 const MObject & getNodeRigidBody(const MObject& node) const; 81 void getShapeLocalPose(const MObject& shape, MMatrix& localPose) const; 82 bool getShapeVertices(const MObject& shape, std::vector<PhysXXML::Point> & vertices, MString & meshId); 83 bool getShapeTriangles(const MObject& shape, std::vector<PhysXXML::Triangle> & triangles); 84 void getRigidBodyGlobalPose(const MObject& rigidBody, MMatrix& globalPose); 85 const MObject & getRigidSolver() const; 86 87 MStatus getMeshURI(const MObject & mesh, URI & meshURI); 88 89 String generateColladaId(const MDagPath & dagPath); 90 String generateColladaName(const MDagPath & dagPath); 91 92 // Stop parsing if callback returns false 93 template<class T> parseSceneElements(T & callbackObject)94 void parseSceneElements(T & callbackObject) 95 { 96 SceneGraph& sceneGraph = *mDocumentExporter.getSceneGraph(); 97 SceneElementsList& exportNodesTree = *sceneGraph.getExportNodesTree(); 98 99 // Export all/selected DAG nodes 100 for (size_t i = 0; i < exportNodesTree.size(); ++i) 101 { 102 SceneElement& sceneElement = *exportNodesTree[i]; 103 if (!parseSceneElement(sceneElement, callbackObject)) 104 { 105 return; 106 } 107 } 108 } 109 110 // in kg 111 static double GetRigidBodyMass(const MObject & rigidBody); 112 static double GetShapeMass(const MObject & shape); 113 114 // in cm3 115 static double GetRigidBodyVolume(const MObject & rigidBody); 116 static double GetShapeVolume(const MObject & shape); 117 118 static MMatrix GetRigidBodyTargetTM(const MObject& rigidBody); 119 static MObject GetRigidBodyTarget(const MObject& rigidBody); 120 static void GetRigidBodyShapes(const MObject & rigidBody, std::vector<MObject> & shapes); 121 static MStatus GetPluggedObject(const MObject & object, const MString & attribute, MObject & pluggedObject); 122 123 static const String& GetDefaultPhysicsModelId(); 124 static const String& GetDefaultPhysicsSceneId(); 125 static const String& GetDefaultInstancePhysicsModelSid(); 126 static const String& GetPhysXProfile(); 127 static const String& GetXMLNS(); 128 static String GetXSISchemaLocation(); 129 130 static bool HasExtraAttributes(const MObject & object); 131 132 // Convert PhysX enum to COLLADA string 133 static String CombineModeToCOLLADA(PhysXXML::CombineMode::FlagEnum flag); 134 static String ShapeFlagsToCOLLADA(const Flags<PhysXXML::ShapeFlags::FlagEnum> & flags); 135 static String ActorFlagsToCOLLADA(const Flags<PhysXXML::ActorFlags::FlagEnum> & flags); 136 static String RigidBodyFlagsToCOLLADA(const Flags<PhysXXML::RigidBodyFlags::FlagEnum> & flags); 137 static String ConstraintFlagsToCOLLADA(const Flags<PhysXXML::ConstraintFlags::FlagEnum> & flags); 138 static String DriveFlagsToCOLLADA(const Flags<PhysXXML::DriveFlags::FlagEnum> & flags); 139 140 enum Filter 141 { 142 All, 143 Local, 144 Reference 145 }; 146 bool sceneHas(SceneElement::Type type, Filter filter = All); 147 148 const PhysXXML::PxRigidBody* findPxRigidBody(const MObject & rigidBody) const; 149 const PhysXXML::PxRigidBody* findPxRigidBody(const String & name) const; 150 const PhysXXML::PxRigidBody* findPxRigidBody(uint64_t id) const; 151 const PhysXXML::PxMaterial* findPxMaterial(uint64_t ref) const; 152 const PhysXXML::PxMaterial* findPxMaterial(const PhysXXML::PxRigidBody & rigidBody) const; 153 const PhysXXML::PxMaterial* findPxMaterial(const MObject & rigidBody) const; 154 const PhysXXML::PxShape* findPxShape(const MObject & shape) const; 155 const PhysXXML::PxD6Joint* findPxD6Joint(const MObject & rigidConstraint) const; 156 157 const MObject & findMObject(const PhysXXML::PxRigidBody & rigidBody) const; 158 const MObject & findMObject(const PhysXXML::PxShape & shape) const; 159 const MObject & findMObject(const PhysXXML::PxD6Joint & joint) const; 160 161 private: 162 void exportRotate(const MVector & axis, double angle, const String & sid = ""); 163 164 static bool ElementHas(const SceneElement & element, SceneElement::Type type, Filter filter); 165 166 const String & findColladaId(const String & mayaId); 167 168 template<class T> parseSceneElement(SceneElement & element,T & callbackObject)169 bool parseSceneElement(SceneElement& element, T & callbackObject) 170 { 171 if (!callbackObject(element)) 172 { 173 return false; 174 } 175 176 // Recursive call for all the child elements 177 for (uint i = 0; i<element.getChildCount(); ++i) 178 { 179 SceneElement& childElement = *element.getChild(i); 180 if (!parseSceneElement(childElement, callbackObject)) 181 { 182 return false; 183 } 184 } 185 186 return true; 187 } 188 189 template<typename E> FlagsToCOLLADA(const Flags<E> & flags,const std::map<E,String> & flagToStringMap)190 static String FlagsToCOLLADA(const Flags<E> & flags, const std::map<E, String> & flagToStringMap) 191 { 192 String colladaFlags; 193 for (int i = 0; i < 32; ++i) 194 { 195 E flag = static_cast<E>(1 << i); 196 if (flags & flag) 197 { 198 typename std::map<E, String>::const_iterator it = flagToStringMap.find(flag); 199 if (!colladaFlags.empty()) 200 colladaFlags += ' '; 201 colladaFlags += it->second.substr(1); 202 } 203 } 204 return colladaFlags; 205 } 206 207 private: 208 COLLADASW::StreamWriter& mStreamWriter; 209 DocumentExporter& mDocumentExporter; 210 COLLADABU::IDList mIdList; 211 StringToStringMap mMayaIdToColladaId; 212 PhysXXML::PhysXDocPtr mPhysXDoc; 213 214 std::map<MObject, const PhysXXML::PxMaterial*> mRigidBodyToPxMaterialMap; 215 std::map<const PhysXXML::PxRigidBody*, MObject> mPxRigidBodyToRigidBodyMap; 216 std::map<MObject, const PhysXXML::PxRigidBody*> mRigidBodyToPxRigidBodyMap; 217 std::map<const PhysXXML::PxShape*, MObject> mPxShapeToShapeMap; 218 std::map<MObject, const PhysXXML::PxShape*> mShapeToPxShapeMap; 219 std::map<const PhysXXML::PxD6Joint*, MObject> mPxD6JointToConstraintMap; 220 std::map<MObject, const PhysXXML::PxD6Joint*> mConstraintToPxD6JointMap; 221 std::map<MObject, MObject> mTargetToRigidBodyMap; 222 MObject mRigidSolver; 223 224 static String mDefaultPhysicsModelId; 225 static String mDefaultPhysicsSceneId; 226 static String mDefaultInstancePhysicsModelSid; 227 static String mPhysXProfile; 228 static String mXMLNS; 229 static String mSchemaLocation; 230 231 friend class PhysicsExportPrePass; 232 }; 233 } 234 235 #endif //__COLLADA_MAYA_PHYSX_EXPORTER_H__ 236