void AddFacesFromPolyList(polylist list, mesh mesh, ModelPrim prim, Matrix4 transform) { string material = list.material; source posSrc = null; source normalSrc = null; source uvSrc = null; ulong stride = 0; int posOffset = -1; int norOffset = -1; int uvOffset = -1; foreach (var inp in list.input) { stride = Math.Max(stride, inp.offset); switch (inp.semantic) { case "VERTEX": posSrc = FindSource(mesh.source, mesh.vertices.input[0].source); posOffset = (int)inp.offset; break; case "NORMAL": normalSrc = FindSource(mesh.source, inp.source); norOffset = (int)inp.offset; break; case "TEXCOORD": uvSrc = FindSource(mesh.source, inp.source); uvOffset = (int)inp.offset; break; } } stride += 1; if (posSrc == null) { return; } var vcount = StrToArray(list.vcount); var idx = StrToArray(list.p); Vector3[] normals = null; if (normalSrc != null) { var norVal = ((float_array)normalSrc.Item).Values; normals = new Vector3[norVal.Length / 3]; for (int i = 0; i < normals.Length; i++) { normals[i] = new Vector3((float)norVal[i * 3 + 0], (float)norVal[i * 3 + 1], (float)norVal[i * 3 + 2]); normals[i] = Vector3.TransformNormal(normals[i], transform); normals[i].Normalize(); } } Vector2[] uvs = null; if (uvSrc != null) { var uvVal = ((float_array)uvSrc.Item).Values; uvs = new Vector2[uvVal.Length / 2]; for (int i = 0; i < uvs.Length; i++) { uvs[i] = new Vector2((float)uvVal[i * 2 + 0], (float)uvVal[i * 2 + 1]); } } ModelFace face = new ModelFace { MaterialID = list.material }; if (face.MaterialID != null) { if (MatSymTarget.ContainsKey(list.material)) { ModelMaterial mat = Materials.Find(m => m.ID == MatSymTarget[list.material]); if (mat != null) { face.Material = mat; } } } int curIdx = 0; foreach (var nvert in vcount) { if (nvert < 3 || nvert > 4) { throw new InvalidDataException("Only triangles and quads supported"); } Vertex[] verts = new Vertex[nvert]; for (int j = 0; j < nvert; j++) { verts[j].Position = prim.Positions[idx[curIdx + posOffset + (int)stride * j]]; if (normals != null) { verts[j].Normal = normals[idx[curIdx + norOffset + (int)stride * j]]; } if (uvs != null) { verts[j].TexCoord = uvs[idx[curIdx + uvOffset + (int)stride * j]]; } } switch (nvert) { case 3: face.AddVertex(verts[0]); face.AddVertex(verts[1]); face.AddVertex(verts[2]); break; case 4: face.AddVertex(verts[0]); face.AddVertex(verts[1]); face.AddVertex(verts[2]); face.AddVertex(verts[0]); face.AddVertex(verts[2]); face.AddVertex(verts[3]); break; } curIdx += (int)stride * nvert; } prim.Faces.Add(face); }
void AddFacesFromPolyList(polylist list, mesh mesh, ModelPrim prim, Matrix4 transform) { string material = list.material; source posSrc = null; source normalSrc = null; source uvSrc = null; ulong stride = 0; int posOffset = -1; int norOffset = -1; int uvOffset = -1; foreach (var inp in list.input) { stride = Math.Max(stride, inp.offset); if (inp.semantic == "VERTEX") { posSrc = FindSource(mesh.source, mesh.vertices.input[0].source); posOffset = (int)inp.offset; } else if (inp.semantic == "NORMAL") { normalSrc = FindSource(mesh.source, inp.source); norOffset = (int)inp.offset; } else if (inp.semantic == "TEXCOORD") { uvSrc = FindSource(mesh.source, inp.source); uvOffset = (int)inp.offset; } } stride += 1; if (posSrc == null) return; var vcount = StrToArray(list.vcount); var idx = StrToArray(list.p); Vector3[] normals = null; if (normalSrc != null) { var norVal = ((float_array)normalSrc.Item).Values; normals = new Vector3[norVal.Length / 3]; for (int i = 0; i < normals.Length; i++) { normals[i] = new Vector3((float)norVal[i * 3 + 0], (float)norVal[i * 3 + 1], (float)norVal[i * 3 + 2]); normals[i] = Vector3.TransformNormal(normals[i], transform); normals[i].Normalize(); } } Vector2[] uvs = null; if (uvSrc != null) { var uvVal = ((float_array)uvSrc.Item).Values; uvs = new Vector2[uvVal.Length / 2]; for (int i = 0; i < uvs.Length; i++) { uvs[i] = new Vector2((float)uvVal[i * 2 + 0], (float)uvVal[i * 2 + 1]); } } ModelFace face = new ModelFace(); face.MaterialID = list.material; if (face.MaterialID != null) { if (MatSymTarget.ContainsKey(list.material)) { ModelMaterial mat = Materials.Find(m => m.ID == MatSymTarget[list.material]); if (mat != null) { face.Material = mat; } } } int curIdx = 0; for (int i = 0; i < vcount.Length; i++) { var nvert = vcount[i]; if (nvert < 3 || nvert > 4) { throw new InvalidDataException("Only triangles and quads supported"); } Vertex[] verts = new Vertex[nvert]; for (int j = 0; j < nvert; j++) { verts[j].Position = prim.Positions[idx[curIdx + posOffset + (int)stride * j]]; if (normals != null) { verts[j].Normal = normals[idx[curIdx + norOffset + (int)stride * j]]; } if (uvs != null) { verts[j].TexCoord = uvs[idx[curIdx + uvOffset + (int)stride * j]]; } } if (nvert == 3) // add the triangle { face.AddVertex(verts[0]); face.AddVertex(verts[1]); face.AddVertex(verts[2]); } else if (nvert == 4) // quad, add two triangles { face.AddVertex(verts[0]); face.AddVertex(verts[1]); face.AddVertex(verts[2]); face.AddVertex(verts[0]); face.AddVertex(verts[2]); face.AddVertex(verts[3]); } curIdx += (int)stride * nvert; } prim.Faces.Add(face); }