Vector3[] GetMeshPositions(DrawableGeometry Mesh) { Vector3[] Positions = new Vector3[Mesh.VerticesCount]; for (int i = 0; i < Mesh.VerticesCount; i++) { int StartIndex = Mesh.VertexStride * i; Positions[i] = new Vector3(BitConverter.ToSingle(Mesh.VertexData.VertexBytes, StartIndex), BitConverter.ToSingle(Mesh.VertexData.VertexBytes, StartIndex + 4), BitConverter.ToSingle(Mesh.VertexData.VertexBytes, StartIndex + 8)); } return(Positions); }
private void MeshFBX(DrawableGeometry Mesh, int MeshID, StringBuilder ob) { if (Mesh.VerticesCount > 0)//general failsafe { ob.AppendFormat("\n\tGeometry: 3{0}, \"Geometry::\", \"Mesh\" {{", MeshID); ob.Append("\n\t\tProperties70: {"); ob.AppendFormat("\n\t\t\tP: \"Color\", \"ColorRGB\", \"Color\", \"\",1.0,1.0,1.0"); ob.Append("\n\t\t}"); #region Vertices ob.AppendFormat("\n\t\tVertices: *{0} {{\n\t\t\ta: ", Mesh.VerticesCount * 3); int lineSplit = ob.Length; Vector3[] Positions = GetMeshPositions(Mesh); for (int v = 0; v < Positions.Length; v++) { ob.AppendFormat("{0},{1},{2},", Positions[v].X, Positions[v].Y, Positions[v].Z); if (ob.Length - lineSplit > 2000) { ob.Append("\n"); lineSplit = ob.Length; } } ob.Length--;//remove last comma ob.Append("\n\t\t}"); #endregion #region Indices //in order to test topology for triangles/quads we need to store submeshes and write each one as geometry, then link to Mesh Node ob.AppendFormat("\n\t\tPolygonVertexIndex: *{0} {{\n\t\t\ta: ", Mesh.IndicesCount); lineSplit = ob.Length; for (int f = 0; f < Mesh.IndicesCount / 3; f++) { ob.AppendFormat("{0},{1},{2},", Mesh.IndexBuffer.Indices[f * 3], Mesh.IndexBuffer.Indices[f * 3 + 2], (-Mesh.IndexBuffer.Indices[f * 3 + 1] - 1)); if (ob.Length - lineSplit > 2000) { ob.Append("\n"); lineSplit = ob.Length; } } ob.Length--;//remove last comma ob.Append("\n\t\t}"); ob.Append("\n\t\tGeometryVersion: 124"); #endregion #region Normals Vector3[] Normals = GetMeshNormals(Mesh); if (Normals != null) { ob.Append("\n\t\tLayerElementNormal: 0 {"); ob.Append("\n\t\t\tVersion: 101"); ob.Append("\n\t\t\tName: \"\""); ob.Append("\n\t\t\tMappingInformationType: \"ByVertice\""); ob.Append("\n\t\t\tReferenceInformationType: \"Direct\""); ob.AppendFormat("\n\t\t\tNormals: *{0} {{\n\t\t\ta: ", (Mesh.VerticesCount * 3)); lineSplit = ob.Length; for (int v = 0; v < Normals.Length; v++) { ob.AppendFormat("{0},{1},{2},", Normals[v].X, Normals[v].Y, Normals[v].Z); if (ob.Length - lineSplit > 2000) { ob.Append("\n"); lineSplit = ob.Length; } } ob.Length--;//remove last comma ob.Append("\n\t\t\t}\n\t\t}"); } #endregion #region Tangents Vector3[] Tangents = GetMeshTangents(Mesh); if (Tangents != null) { ob.Append("\n\t\tLayerElementTangent: 0 {"); ob.Append("\n\t\t\tVersion: 101"); ob.Append("\n\t\t\tName: \"\""); ob.Append("\n\t\t\tMappingInformationType: \"ByVertice\""); ob.Append("\n\t\t\tReferenceInformationType: \"Direct\""); ob.AppendFormat("\n\t\t\tTangents: *{0} {{\n\t\t\ta: ", Mesh.VerticesCount * 3); lineSplit = ob.Length; for (int v = 0; v < Tangents.Length; v++) { ob.AppendFormat("{0},{1},{2},", Tangents[v].X, Tangents[v].Y, Tangents[v].Z); if (ob.Length - lineSplit > 2000) { ob.Append("\n"); lineSplit = ob.Length; } } ob.Length--;//remove last comma ob.Append("\n\t\t\t}\n\t\t}"); } #endregion #region UV1 //does FBX support UVW coordinates? Vector2[] UVs = GetMeshUVs(Mesh); if (UVs != null) { ob.Append("\n\t\tLayerElementUV: 0 {"); ob.Append("\n\t\t\tVersion: 101"); ob.Append("\n\t\t\tName: \"UVChannel_1\""); ob.Append("\n\t\t\tMappingInformationType: \"ByVertice\""); ob.Append("\n\t\t\tReferenceInformationType: \"Direct\""); ob.AppendFormat("\n\t\t\tUV: *{0} {{\n\t\t\ta: ", Mesh.VerticesCount * 2); lineSplit = ob.Length; for (int v = 0; v < UVs.Length; v++) { ob.AppendFormat("{0},{1},", UVs[v].X, 1 - UVs[v].Y); if (ob.Length - lineSplit > 2000) { ob.Append("\n"); lineSplit = ob.Length; } } ob.Length--;//remove last comma ob.Append("\n\t\t\t}\n\t\t}"); } #endregion #region Material ob.Append("\n\t\tLayerElementMaterial: 0 {"); ob.Append("\n\t\t\tVersion: 101"); ob.Append("\n\t\t\tName: \"\""); ob.Append("\n\t\t\tMappingInformationType: \""); ob.Append("AllSame\""); ob.Append("\n\t\t\tReferenceInformationType: \"IndexToDirect\""); // ob.AppendFormat("\n\t\t\tMaterials: *{0} {{", Mesh.TrianglesCount); ob.AppendFormat("\n\t\t\tMaterials: *{0} {{", 1); ob.Append("\n\t\t\t\t"); // ob.Append("0"); ob.Append("a: 0"); ob.Append("\n\t\t\t}\n\t\t}"); #endregion #region Layers ob.Append("\n\t\tLayer: 0 {"); ob.Append("\n\t\t\tVersion: 100"); if (Normals != null) { ob.Append("\n\t\t\tLayerElement: {"); ob.Append("\n\t\t\t\tType: \"LayerElementNormal\""); ob.Append("\n\t\t\t\tTypedIndex: 0"); ob.Append("\n\t\t\t}"); } if (Tangents != null) { ob.Append("\n\t\t\tLayerElement: {"); ob.Append("\n\t\t\t\tType: \"LayerElementTangent\""); ob.Append("\n\t\t\t\tTypedIndex: 0"); ob.Append("\n\t\t\t}"); } ob.Append("\n\t\t\tLayerElement: {"); ob.Append("\n\t\t\t\tType: \"LayerElementMaterial\""); ob.Append("\n\t\t\t\tTypedIndex: 0"); ob.Append("\n\t\t\t}"); // /*ob.Append("\n\t\t\tLayerElement: {"); * ob.Append("\n\t\t\t\tType: \"LayerElementTexture\""); * ob.Append("\n\t\t\t\tTypedIndex: 0"); * ob.Append("\n\t\t\t}"); * ob.Append("\n\t\t\tLayerElement: {"); * ob.Append("\n\t\t\t\tType: \"LayerElementBumpTextures\""); * ob.Append("\n\t\t\t\tTypedIndex: 0"); * ob.Append("\n\t\t\t}");*/ if (UVs != null) { ob.Append("\n\t\t\tLayerElement: {"); ob.Append("\n\t\t\t\tType: \"LayerElementUV\""); ob.Append("\n\t\t\t\tTypedIndex: 0"); ob.Append("\n\t\t\t}"); } ob.Append("\n\t\t}"); //Layer 0 end #endregion ob.Append("\n\t}"); //Geometry end } }