public override void writeFloatVectorArray(MFloatVectorArray array) { if (myCurrentChanelNode != null) { uint size = array.length; XmlNode sizeNode = myXmlDoc.CreateElement(sizeTag); sizeNode.InnerText = Convert.ToString(size); myCurrentChanelNode.AppendChild(sizeNode); XmlNode arrayNode = myXmlDoc.CreateElement(floatVectorArrayTag); myCurrentChanelNode.AppendChild(arrayNode); for (int i = 0; i < size; i++) { MFloatVector value = array[i]; XmlNode valueNode = myXmlDoc.CreateElement("value"); arrayNode.AppendChild(valueNode); XmlNode xValueNode = myXmlDoc.CreateElement("x"); xValueNode.InnerText = Convert.ToString(value.x); valueNode.AppendChild(xValueNode); XmlNode yValueNode = myXmlDoc.CreateElement("y"); yValueNode.InnerText = Convert.ToString(value.y); valueNode.AppendChild(yValueNode); XmlNode zValueNode = myXmlDoc.CreateElement("z"); zValueNode.InnerText = Convert.ToString(value.z); valueNode.AppendChild(zValueNode); } } return; }
public override void readFloatVectorArray(MFloatVectorArray array, uint arraySize) { Trace.Assert(myCurrentChanelNode != null); XmlNode floatVectorArrayNode = myCurrentChanelNode.SelectSingleNode(floatVectorArrayTag); XmlNodeList valueNodeList = floatVectorArrayNode.SelectNodes("value"); uint i = 0; array.clear(); array.length = arraySize; foreach (XmlNode valueNode in valueNodeList) { XmlNode xNode = valueNode.SelectSingleNode("x"); double valueX = Convert.ToDouble(xNode.InnerText); XmlNode yNode = valueNode.SelectSingleNode("y"); double valuey = Convert.ToDouble(yNode.InnerText); XmlNode zNode = valueNode.SelectSingleNode("z"); double valuez = Convert.ToDouble(zNode.InnerText); MFloatVector v = new MFloatVector((float)valueX, (float)valuey, (float)valuez); array.set(v, i); i++; } return; }
/// <summary> /// Extract the vertices, normals and triangles of a mesh into the M2 collision data fields. /// </summary> /// <param name="wowModel"></param> private static void InjectCollisionMesh(M2 wowModel) { var collisionFound = false; for (var meshIter = new MItDag(MItDag.TraversalType.kDepthFirst, MFn.Type.kMesh); !meshIter.isDone; meshIter.next()) { var meshPath = new MDagPath(); meshIter.getPath(meshPath); var meshFn = new MFnMesh(meshPath); // only want non-history items if (meshFn.isIntermediateObject) { continue; } var name = meshFn.name; if (name != "Collision") { continue; //TODO use custom attribute } if (collisionFound) { throw new Exception("More than one collision box has been found. One supported."); } MGlobal.displayInfo("\t Collision mesh detected."); wowModel.CollisionBox = new CAaBox(AxisInvert(meshFn.boundingBox.min), AxisInvert(meshFn.boundingBox.max)); wowModel.CollisionSphereRadius = (float)Math.Max(meshFn.boundingBox.depth / 2, meshFn.boundingBox.width / 2); //TODO fixme better iterate through faces var collisionPoints = new MFloatPointArray(); meshFn.getPoints(collisionPoints, MSpace.Space.kWorld); var collisionNormals = new MFloatVectorArray(); meshFn.getNormals(collisionNormals, MSpace.Space.kWorld); var collisionTriangles = new MIntArray(); meshFn.getTriangles(new MIntArray(), collisionTriangles); for (var i = 0; i < collisionPoints.Count; i++) { wowModel.CollisionVertices.Add(AxisInvert(collisionPoints[i])); wowModel.CollisionNormals.Add(AxisInvert(collisionNormals[i])); } foreach (var vertIndex in collisionTriangles) { wowModel.CollisionTriangles.Add((ushort)vertIndex); } collisionFound = true; } }
public static List <Vector> getVertexNormals(MFnMesh mayaMesh, bool angleWeighted) { List <Vector> vecNormals = new List <Vector>(mayaMesh.numVertices); MFloatVectorArray norm = new MFloatVectorArray(); mayaMesh.getVertexNormals(angleWeighted, norm, MSpace.Space.kWorld); if (MGlobal.isZAxisUp) { vecNormals.AddRange(norm.Select(n => Vector.ByCoordinates(n.x, n.y, n.z))); } else { vecNormals.AddRange(norm.Select(n => Vector.ByCoordinates(n.x, -n.z, n.y))); } return(vecNormals); }
/// <summary> /// Faces and vertices UVs, positions and normals. /// </summary> private static void ExtractMeshGeometry(MayaM2Mesh mesh, MDagPath meshPath, Dictionary <string, MayaM2Bone> jointMap, List <MayaM2Vertex> globalVertexList) { // ***Data Tables*** // UV Sets var uvsets = new MStringArray(); var meshFunctions = new MFnMesh(meshPath); meshFunctions.getUVSetNames(uvsets); //Bone Weights var vertexWeights = new List <MDoubleArray>(); var influenceObjects = new MDagPathArray(); GetMeshWeightData(vertexWeights, influenceObjects, meshPath); //Positions var positions = new MFloatPointArray(); meshFunctions.getPoints(positions, MSpace.Space.kWorld); //Normals var normals = new MFloatVectorArray(); meshFunctions.getVertexNormals(false, normals, MSpace.Space.kWorld); var polygonIter = new MItMeshPolygon(meshPath); while (!polygonIter.isDone) { //Divide face into triangles var polyMeshRelative = new MIntArray(); polygonIter.getVertices(polyMeshRelative); int numTriangles; polygonIter.numTriangles(out numTriangles); for (var i = 0; i < numTriangles; i++) { var triangle = new MayaM2Triangle(); var triangleMeshRelative = new MIntArray(); polygonIter.getTriangle(i, new MPointArray(), triangleMeshRelative); var triangleFaceRelative = GetLocalTriangle(polyMeshRelative, triangleMeshRelative); for (var v = 0; v < 3; v++) { var meshIndex = triangleMeshRelative[v]; var faceIndex = triangleFaceRelative[v]; //Bone weights var weights = new List <Tuple <MayaM2Bone, double> >(); for (var b = 0; b < influenceObjects.length; b++) //for each joint { var kJointPath = influenceObjects[b]; if (!kJointPath.hasFn(MFn.Type.kJoint)) { continue; } Debug.Assert(b < vertexWeights[meshIndex].Count, "vertexWeights size : " + vertexWeights.Count + " " + "\njointWeights for this vertex : " + vertexWeights[meshIndex].Count); //Here are a joint&weight for this vertex if (vertexWeights[meshIndex][b] > Epsilon) { weights.Add(new Tuple <MayaM2Bone, double>(jointMap[kJointPath.fullPathName], vertexWeights[meshIndex][b])); } } //Position & normals var position = positions[(int)polygonIter.vertexIndex(faceIndex)]; var normal = normals[(int)polygonIter.normalIndex(faceIndex)]; //UV coordinates var uvCoordinates = new List <Tuple <float, float> >(); if (uvsets.length > 0 && meshFunctions.numUVs(uvsets[0]) > 0) { foreach (var uvset in uvsets) { var uvCoords = new float[2]; polygonIter.getUV(faceIndex, uvCoords, uvset); uvCoordinates.Add(new Tuple <float, float>(uvCoords[0], uvCoords[1])); } } var vert = VertexFactory.Create(position, normal, uvCoordinates, weights, globalVertexList); triangle.Vertices.Add(vert); } mesh.Faces.Add(triangle); } polygonIter.next(); } }