public static geometry MeshToGeometry(CPUMesh inputMesh, string id) { geometry outputGeometry = new geometry(); mesh outputMesh = new mesh(); outputGeometry.id = id + "-lib"; outputGeometry.name = inputMesh.name + "-mesh"; outputGeometry.Item = outputMesh; //vertex Positions List <source> sourceList = new List <source>(); var inputVertices = inputMesh.vertices; if (inputVertices.Length == 0) { return(null); } sourceList.Add(ArrayToSource(inputMesh.vertices, id + "-POSITION")); vertices vertexList = new vertices(); vertexList.id = id + "-VERTEX"; vertexList.input = new InputLocal[1]; vertexList.input[0] = new InputLocal(); vertexList.input[0].semantic = "POSITION"; vertexList.input[0].source = "#" + sourceList[0].id; outputMesh.vertices = vertexList; List <InputLocalOffset> offsetList = new List <InputLocalOffset>(); { InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "VERTEX"; offset.offset = 0; offset.source = "#" + vertexList.id; offsetList.Add(offset); } var inputNormals = inputMesh.normals; if (inputNormals.Length > 0) { var array = ArrayToSource(inputNormals, id + "-Normal0"); InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "NORMAL"; offset.offset = (ulong)sourceList.Count; offset.source = "#" + array.id; sourceList.Add(array); offsetList.Add(offset); } var inputUV1s = inputMesh.uv; if (inputUV1s.Length > 0) { var array = ArrayToSource(inputUV1s, id + "-UV0"); InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "TEXCOORD"; offset.offset = (ulong)sourceList.Count; offset.source = "#" + array.id; offset.set = 0; offset.setSpecified = true; sourceList.Add(array); offsetList.Add(offset); } var inputUV2s = inputMesh.uv2; if (inputUV2s.Length > 0) { var array = ArrayToSource(inputUV2s, id + "-UV1"); InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "TEXCOORD"; offset.offset = (ulong)sourceList.Count; offset.source = "#" + array.id; offset.set = 1; offset.setSpecified = true; sourceList.Add(array); offsetList.Add(offset); } var inputColors = inputMesh.colors; if (inputColors.Length > 0) { var array = ArrayToSource(inputColors, id + "-VERTEX_COLOR0"); InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "COLOR"; offset.offset = (ulong)sourceList.Count; offset.source = "#" + array.id; offset.set = 0; offset.setSpecified = true; sourceList.Add(array); offsetList.Add(offset); } outputMesh.source = sourceList.ToArray(); triangles triangleList = new triangles(); triangleList.input = offsetList.ToArray(); var inputTriangles = inputMesh.triangles; triangleList.count = (ulong)inputTriangles.Length / 3; if (triangleList.count == 0) { return(null); } StringBuilder pString = new StringBuilder(); for (int i = 0; i < inputTriangles.Length; i++) { for (int j = 0; j < triangleList.input.Length; j++) { pString.Append(inputTriangles[i]).Append(" "); } if (i % 3 == 2) { pString.AppendLine(); } else { pString.Append(" "); } } triangleList.p = pString.ToString(); outputMesh.Items = new object[1]; outputMesh.Items[0] = triangleList; return(outputGeometry); }
private ModelBase.GeometryDef ReadGeometry(string id, string boneID, Dictionary<string, string> bindMaterials, int[] vertexBoneIDs) { ModelBase.GeometryDef geomDef = new ModelBase.GeometryDef(id); int boneIndex = m_Model.m_BoneTree.GetBoneIndex(boneID); geometry geom = library_geometries.geometry.Where(geom0 => geom0.id.Equals(id)).ElementAt(0); Dictionary<string, source> sources = new Dictionary<string, source>(); if (geom.Item as mesh != null) { mesh geomMesh = geom.Item as mesh; Dictionary<string, string> geometryVertices = new Dictionary<string,string>(); geometryVertices.Add(geomMesh.vertices.id, geomMesh.vertices.input.Where(input0 => input0.semantic.Equals("POSITION")).ElementAt(0).source.Replace("#", "")); foreach (source src in geomMesh.source) { string sourceID = src.id; if (src.Item as float_array != null) sources.Add(sourceID, src); } foreach (var item in geomMesh.Items) { if ((item as triangles != null) || (item as polylist != null) || (item as polygons != null) || (item as tristrips != null)) { ModelBase.PolyListDef polyListDef; string material = null; ulong count; InputLocalOffset[] inputs = new InputLocalOffset[0]; int[] vcount = new int[0]; List<int[]> p = new List<int[]>(); ModelBase.PolyListType polyListType = ModelBase.PolyListType.Polygons; if (item as triangles != null) { triangles tris = item as triangles; polyListType = ModelBase.PolyListType.Triangles; string matAttr = (tris.material != null) ? tris.material : "default_white"; material = (bindMaterials != null && bindMaterials.Count > 0 && bindMaterials.ContainsKey(matAttr)) ? bindMaterials[matAttr] : matAttr; count = tris.count; inputs = tris.input; vcount = new int[] { 3 }; p.Add(Array.ConvertAll<string, int> (tris.p.Split(new string[] { " ", "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries), Convert.ToInt32)); } else if (item as polylist != null) { polylist plist = item as polylist; polyListType = ModelBase.PolyListType.Polygons; string matAttr = (plist.material != null) ? plist.material : "default_white"; material = (bindMaterials != null && bindMaterials.Count > 0 && bindMaterials.ContainsKey(matAttr)) ? bindMaterials[matAttr] : matAttr; count = plist.count; inputs = plist.input; vcount = Array.ConvertAll<string, int> (plist.vcount.Split(new string[] { " ", "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries), Convert.ToInt32); p.Add(Array.ConvertAll<string, int> (plist.p.Split(new string[] { " ", "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries), Convert.ToInt32)); } else if (item as polygons != null) { polygons pgons = item as polygons; polyListType = ModelBase.PolyListType.Polygons; string matAttr = (pgons.material != null) ? pgons.material : "default_white"; material = (bindMaterials != null && bindMaterials.Count > 0 && bindMaterials.ContainsKey(matAttr)) ? bindMaterials[matAttr] : matAttr; count = pgons.count; inputs = pgons.input; vcount = new int[count]; int[] pTmp = new int[0]; int counter = 0; for (int i = 0; i < pgons.Items.Length; i++) { var element = pgons.Items[i]; if (element as string != null) { int[] tmp = Array.ConvertAll<string, int> ((element as string).Split(new string[] { " ", "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries), Convert.ToInt32); vcount[i] = tmp.Length / inputs.Length; Array.Resize(ref pTmp, pTmp.Length + (vcount[i] * inputs.Length)); Array.Copy(tmp, 0, pTmp, counter, tmp.Length); counter += tmp.Length; } } p.Add(pTmp); } else if (item as tristrips != null) { tristrips tristrips = item as tristrips; polyListType = ModelBase.PolyListType.TriangleStrip; string matAttr = (tristrips.material != null) ? tristrips.material : "default_white"; material = (bindMaterials != null && bindMaterials.Count > 0 && bindMaterials.ContainsKey(matAttr)) ? bindMaterials[matAttr] : matAttr; count = tristrips.count; inputs = tristrips.input; vcount = new int[] { 3 }; // Go through <p> elements and convert it so the format is similar to <polylist> for parsing below // Eg. given: (0,(1,(2),(3),4),5) // convert to separate triangles: (0,1,2),(1,2,3),(2,3,4),(3,4,5) // These will be converted back to triangle strips when writing the BMD model for (int i = 0; i < tristrips.p.Length; i++) { var element = tristrips.p[i]; if (element as string != null) { int[] tmp = Array.ConvertAll<string, int> ((element as string).Split(new string[] { " ", "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries), Convert.ToInt32); int numTris = ((tmp.Length / inputs.Length) - 3) + 1; int numVertsToTris = numTris * 3; int[] tmpConv = new int[numVertsToTris * inputs.Length]; Array.Copy(tmp, tmpConv, (3 * inputs.Length)); if (tmp.Length > (3 * inputs.Length)) { int startInd = 3 * inputs.Length; for (int sourceInd = startInd, destInd = startInd; sourceInd < tmp.Length; sourceInd += inputs.Length, destInd += (3 * inputs.Length)) { Array.Copy(tmp, sourceInd - (2 * inputs.Length), tmpConv, destInd, (3 * inputs.Length)); } } p.Add(tmpConv); } } } polyListDef = new ModelBase.PolyListDef(id + "." + material, material); // The parent (root) bone should have a list of all materials used by itself and its children if (!m_Model.m_BoneTree.GetBoneByID(boneID).GetRoot().m_MaterialsInBranch.Contains(material)) m_Model.m_BoneTree.GetBoneByID(boneID).GetRoot().m_MaterialsInBranch.Add(material); if (!m_Model.m_BoneTree.GetBoneByID(boneID).m_MaterialsInBranch.Contains(material)) m_Model.m_BoneTree.GetBoneByID(boneID).m_MaterialsInBranch.Add(material); int inputCount = inputs.Length; int vertexOffset = -1, normalOffset = -1, texCoordOffset = -1, colourOffset = -1; string vertexSource = "", normalSource = "", texCoordSource = "", colourSource = ""; foreach (InputLocalOffset input in inputs) { if (input.semantic.Equals("VERTEX")) { vertexOffset = (int)input.offset; vertexSource = geometryVertices[input.source.Replace("#", "")]; } else if (input.semantic.Equals("NORMAL")) { normalOffset = (int)input.offset; normalSource = input.source.Replace("#", ""); } else if (input.semantic.Equals("TEXCOORD")) { texCoordOffset = (int)input.offset; texCoordSource = input.source.Replace("#", ""); } else if (input.semantic.Equals("COLOR")) { colourOffset = (int)input.offset; colourSource = input.source.Replace("#", ""); } } foreach (int[] pArr in p) { ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(polyListType); bool even = true; for (ulong pIndex = 0, vcountInd = 0; pIndex < (ulong)pArr.Length; vcountInd++) { ModelBase.FaceDef faceDef = new ModelBase.FaceDef( vcount[(polyListType.Equals(ModelBase.PolyListType.Triangles) || polyListType.Equals(ModelBase.PolyListType.TriangleStrip)) ? 0 : vcountInd]); List<ModelBase.VertexDef> vertices = new List<ModelBase.VertexDef>(); for (int i = 0; i < faceDef.m_NumVertices; i++) { ModelBase.VertexDef vert = ModelBase.EMPTY_VERTEX; int vertexIndex = pArr[pIndex + (ulong)vertexOffset]; float[] tmp = GetValueFromFloatArraySource(sources[vertexSource], vertexIndex); vert.m_Position = new Vector3(tmp[0], tmp[1], tmp[2]); /*if (normalOffset != -1) { tmp = GetValueFromFloatArraySource(sources[normalSource], pArr[pIndex + (ulong)normalOffset]); vert.m_Normal = new Vector3(tmp[0], tmp[1], tmp[2]); ((Vector3)vert.m_Normal).Normalize(); } else*/ { vert.m_Normal = null; } if (texCoordOffset != -1 && m_Model.m_Materials[material].m_TextureDefID != null) { tmp = GetValueFromFloatArraySource(sources[texCoordSource], pArr[pIndex + (ulong)texCoordOffset]); if (m_Model.m_Materials[material].m_TexGenMode != ModelBase.TexGenMode.Normal) { vert.m_TextureCoordinate = new Vector2(tmp[0], tmp[1]); } else { vert.m_Normal = new Vector3( tmp[0] * m_Model.m_Textures[m_Model.m_Materials[material].m_TextureDefID].GetWidth(), tmp[1] * m_Model.m_Textures[m_Model.m_Materials[material].m_TextureDefID].GetHeight(), 0.0f); vert.m_TextureCoordinate = null; } } else { vert.m_TextureCoordinate = null; } if (colourOffset != -1) { tmp = GetValueFromFloatArraySource(sources[colourSource], pArr[pIndex + (ulong)colourOffset]); vert.m_VertexColour = Color.FromArgb((int)(tmp[0] * 255f), (int)(tmp[1] * 255f), (int)(tmp[2] * 255f)); } else { vert.m_VertexColour = Color.White; } vert.m_VertexBoneID = (vertexBoneIDs != null) ? vertexBoneIDs[vertexIndex] : boneIndex; vertices.Add(vert); pIndex += (ulong)inputCount; } if (polyListType.Equals(ModelBase.PolyListType.TriangleStrip)) { if (even) { for (int v = 0; v < vertices.Count; v++) faceDef.m_Vertices[v] = vertices[v]; } else { for (int v = 0; v < vertices.Count; v++) faceDef.m_Vertices[2 - v] = vertices[v]; } even = !even; } else { for (int v = 0; v < vertices.Count; v++) faceDef.m_Vertices[v] = vertices[v]; } faceList.m_Faces.Add(faceDef); } polyListDef.m_FaceLists.Add(faceList); } geomDef.m_PolyLists.Add(boneID + "." + material, polyListDef); } } } return geomDef; }
public static geometry MeshToGeometry(Mesh inputMesh) { string meshName = "Mesh-" + inputMesh.GetInstanceID(); geometry outputGeometry = new geometry(); mesh outputMesh = new mesh(); outputGeometry.id = meshName + "-lib"; outputGeometry.name = inputMesh.name + "-mesh"; outputGeometry.Item = outputMesh; //vertex Positions List<source> sourceList = new List<source>(); var inputVertices = inputMesh.vertices; if (inputVertices.Length == 0) return null; sourceList.Add(ArrayToSource(inputMesh.vertices, meshName + "-POSITION")); vertices vertexList = new vertices(); vertexList.id = meshName + "-VERTEX"; vertexList.input = new InputLocal[1]; vertexList.input[0] = new InputLocal(); vertexList.input[0].semantic = "POSITION"; vertexList.input[0].source = "#" + sourceList[0].id; outputMesh.vertices = vertexList; List<InputLocalOffset> offsetList = new List<InputLocalOffset>(); { InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "VERTEX"; offset.offset = 0; offset.source = "#" + vertexList.id; offsetList.Add(offset); } var inputNormals = inputMesh.normals; if(inputNormals.Length > 0) { var array = ArrayToSource(inputNormals, meshName + "-Normal0"); InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "NORMAL"; offset.offset = (ulong)sourceList.Count; offset.source = "#" + array.id; sourceList.Add(array); offsetList.Add(offset); } var inputUV1s = inputMesh.uv; if (inputUV1s.Length > 0) { var array = ArrayToSource(inputUV1s, meshName + "-UV0"); InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "TEXCOORD"; offset.offset = (ulong)sourceList.Count; offset.source = "#" + array.id; offset.set = 0; offset.setSpecified = true; sourceList.Add(array); offsetList.Add(offset); } var inputUV2s = inputMesh.uv2; if (inputUV2s.Length > 0) { var array = ArrayToSource(inputUV2s, meshName + "-UV1"); InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "TEXCOORD"; offset.offset = (ulong)sourceList.Count; offset.source = "#" + array.id; offset.set = 1; offset.setSpecified = true; sourceList.Add(array); offsetList.Add(offset); } var inputColors = inputMesh.colors; if (inputColors.Length > 0) { var array = ArrayToSource(inputColors, meshName + "-VERTEX_COLOR0"); InputLocalOffset offset = new InputLocalOffset(); offset.semantic = "COLOR"; offset.offset = (ulong)sourceList.Count; offset.source = "#" + array.id; offset.set = 0; offset.setSpecified = true; sourceList.Add(array); offsetList.Add(offset); } outputMesh.source = sourceList.ToArray(); triangles triangleList = new triangles(); triangleList.input = offsetList.ToArray(); var inputTriangles = inputMesh.triangles; triangleList.count = (ulong)inputTriangles.Length / 3; if (triangleList.count == 0) return null; StringBuilder pString = new StringBuilder(); for(int i = 0; i < inputTriangles.Length; i++) { for(int j = 0; j < triangleList.input.Length; j++) { pString.Append(inputTriangles[i]).Append(" "); } if (i % 3 == 2) pString.AppendLine(); else pString.Append(" "); } triangleList.p = pString.ToString(); outputMesh.Items = new object[1]; outputMesh.Items[0] = triangleList; return outputGeometry; }