protected static void AddVertexToList(int boneID, Vector2?tex, Vector3?nrm, AccurateVertex pos, int pos_scale, Color clr, List <ModelBase.VertexDef> vertexList) { AccurateVertex scaledPos = new AccurateVertex( BasicBigFloat.IntMultiply(pos.x, (1 << pos_scale)), BasicBigFloat.IntMultiply(pos.y, (1 << pos_scale)), BasicBigFloat.IntMultiply(pos.z, (1 << pos_scale))); AddVertexToList(boneID, tex, nrm, new Vector3(scaledPos.x.ToFloat(), scaledPos.y.ToFloat(), scaledPos.z.ToFloat()), 0, clr, vertexList); }
public AccurateVertex(string x, string y, string z) { this.x = new BasicBigFloat(x); this.y = new BasicBigFloat(y); this.z = new BasicBigFloat(z); }
public AccurateVertex(BasicBigFloat x, BasicBigFloat y, BasicBigFloat z) { this.x = x; this.y = y; this.z = z; }
protected void ReadPolygon(int polygonIndex, XmlNode polygon_array, string materialID, ModelBase.GeometryDef geometryDef) { if (polygon_array == null) { return; } int polygonArray_size = int.Parse(polygon_array.Attributes["size"].Value); if (polygonArray_size < 1) { return; } XmlNodeList polygons = polygon_array.SelectNodes("polygon"); XmlNode polygon = polygons[polygonIndex]; int index = int.Parse(polygon.Attributes["index"].Value); string name = polygon.Attributes["name"].Value; int vertex_size = int.Parse(polygon.Attributes["vertex_size"].Value); int polygon_size = int.Parse(polygon.Attributes["polygon_size"].Value); int triangle_size = int.Parse(polygon.Attributes["triangle_size"].Value); int quad_size = int.Parse(polygon.Attributes["quad_size"].Value); float[] volume_min = Array.ConvertAll( polygon.Attributes["volume_min"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToSingle); float[] volume_max = Array.ConvertAll( polygon.Attributes["volume_max"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToSingle); float volume_r = Helper.ParseFloat(polygon.Attributes["volume_r"].Value); int mtx_prim_size = int.Parse(polygon.Attributes["mtx_prim_size"].Value); bool nrm_flag = polygon.Attributes["nrm_flag"].Value.Equals("on"); bool clr_flag = polygon.Attributes["clr_flag"].Value.Equals("on"); bool tex_flag = polygon.Attributes["tex_flag"].Value.Equals("on"); XmlNodeList mtx_prims = polygon.SelectNodes("mtx_prim"); foreach (XmlNode mtx_prim in mtx_prims) { int mtxPrim_index = int.Parse(mtx_prim.Attributes["index"].Value); ModelBase.PolyListDef polyListDef = new ModelBase.PolyListDef(name + mtxPrim_index, materialID); XmlNode mtx_list = mtx_prim.SelectSingleNode("mtx_list"); int mtxList_size = int.Parse(mtx_list.Attributes["size"].Value); Dictionary <int, int> localToGlobalMatrixIDMap = new Dictionary <int, int>(); int[] mtxList_data = Array.ConvertAll( mtx_list.InnerText.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToInt32); for (int i = 0; i < mtxList_size; i++) { localToGlobalMatrixIDMap.Add(i, mtxList_data[i]); } XmlNode primitive_array = mtx_prim.SelectSingleNode("primitive_array"); int primitiveArray_size = int.Parse(primitive_array.Attributes["size"].Value); XmlNodeList primitives = primitive_array.SelectNodes("primitive"); int mtx = -1; int boneID = -1; Vector2? tex = null; Vector3? nrm = null; AccurateVertex pos = new AccurateVertex("0", "0", "0"); Color clr = Color.White; foreach (XmlNode primitive in primitives) { int primitive_index = int.Parse(primitive.Attributes["index"].Value); string primitive_type = primitive.Attributes["type"].Value; int primitive_vertex_size = int.Parse(primitive.Attributes["vertex_size"].Value); ModelBase.PolyListType polyListType; switch (primitive_type) { case "triangles": polyListType = ModelBase.PolyListType.Triangles; break; case "quads": polyListType = ModelBase.PolyListType.Polygons; break; case "triangle_strip": polyListType = ModelBase.PolyListType.TriangleStrip; break; case "quad_strip": polyListType = ModelBase.PolyListType.QuadrilateralStrip; break; default: goto case "triangles"; } ModelBase.FaceListDef faceListDef = new ModelBase.FaceListDef(polyListType); List <ModelBase.VertexDef> vertexList = new List <ModelBase.VertexDef>(); foreach (XmlNode child in primitive.ChildNodes) { switch (child.LocalName) { case "mtx": { mtx = int.Parse(child.Attributes["idx"].Value); boneID = m_Model.m_BoneTree.GetBoneIndex( m_Model.m_BoneTransformsMap.GetBySecond(localToGlobalMatrixIDMap[mtx])); } break; case "tex": { float[] texArr = Array.ConvertAll( child.Attributes["st"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToSingle); ModelBase.TextureDefBase texture = m_Model.m_Textures[m_Model.m_Materials[materialID].m_TextureDefID]; tex = new Vector2((float)(texArr[0] / texture.GetWidth()), (float)(texArr[1] / texture.GetHeight())); } break; case "nrm": { float[] nrmArr = Array.ConvertAll( child.Attributes["xyz"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToSingle); nrm = new Vector3(nrmArr[0], nrmArr[1], nrmArr[2]); } break; case "clr": { int[] clrArr = Array.ConvertAll( child.Attributes["rgb"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToInt32); clr = Color.FromArgb( (int)(clrArr[0] / 31f * 255f), (int)(clrArr[1] / 31f * 255f), (int)(clrArr[2] / 31f * 255f)); } break; case "clr_idx": { int idx = int.Parse(child.Attributes["idx"].Value); clr = vtx_color_data[idx]; } break; case "pos_xyz": { string[] pos_xyz = child.Attributes["xyz"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); pos.x = new BasicBigFloat(pos_xyz[0]); pos.y = new BasicBigFloat(pos_xyz[1]); pos.z = new BasicBigFloat(pos_xyz[2]); AddVertexToList(boneID, tex, nrm, pos, this.model_info.pos_scale, clr, vertexList); } break; case "pos_s": goto case "pos_xyz"; case "pos_xy": { string[] pos_xy = child.Attributes["xy"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); pos.x = new BasicBigFloat(pos_xy[0]); pos.y = new BasicBigFloat(pos_xy[1]); AddVertexToList(boneID, tex, nrm, pos, this.model_info.pos_scale, clr, vertexList); } break; case "pos_xz": { string[] pos_xz = child.Attributes["xz"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); pos.x = new BasicBigFloat(pos_xz[0]); pos.z = new BasicBigFloat(pos_xz[1]); AddVertexToList(boneID, tex, nrm, pos, this.model_info.pos_scale, clr, vertexList); } break; case "pos_yz": { string[] pos_yz = child.Attributes["yz"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); pos.y = new BasicBigFloat(pos_yz[0]); pos.z = new BasicBigFloat(pos_yz[1]); AddVertexToList(boneID, tex, nrm, pos, this.model_info.pos_scale, clr, vertexList); } break; case "pos_diff": { // (-0.125 ≤ real numbers ≤ 0.125) (x3) string[] pos_diff = child.Attributes["xyz"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); pos.x = BasicBigFloat.Add(pos.x, new BasicBigFloat(pos_diff[0])); pos.y = BasicBigFloat.Add(pos.y, new BasicBigFloat(pos_diff[1])); pos.z = BasicBigFloat.Add(pos.z, new BasicBigFloat(pos_diff[2])); AddVertexToList(boneID, tex, nrm, pos, this.model_info.pos_scale, clr, vertexList); } break; case "pos_idx": { int idx = int.Parse(child.Attributes["idx"].Value); pos = this.vtx_pos_data[idx]; AddVertexToList(boneID, tex, nrm, pos, this.model_info.pos_scale, clr, vertexList); } break; } } switch (polyListType) { case ModelBase.PolyListType.Triangles: { int numVertsPerFace = 3; int numFaces = primitive_vertex_size / numVertsPerFace; for (int i = 0; i < numFaces; i++) { ModelBase.FaceDef face = new ModelBase.FaceDef(numVertsPerFace); for (int j = 0; j < numVertsPerFace; j++) { face.m_Vertices[j] = vertexList[(i * numVertsPerFace) + j]; } faceListDef.m_Faces.Add(face); } } break; case ModelBase.PolyListType.Polygons: { int numVertsPerFace = 4; int numFaces = primitive_vertex_size / numVertsPerFace; for (int i = 0; i < numFaces; i++) { ModelBase.FaceDef face = new ModelBase.FaceDef(numVertsPerFace); for (int j = 0; j < numVertsPerFace; j++) { face.m_Vertices[j] = vertexList[(i * numVertsPerFace) + j]; } faceListDef.m_Faces.Add(face); } } break; case ModelBase.PolyListType.TriangleStrip: { //3+(N-1) vertices per N triangles //(N-3)+1 Triangles per N Vertices int numFaces = primitive_vertex_size - 2; for (int i = 0; i < numFaces; i++) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); if ((i & 1) == 0) { face.m_Vertices[0] = vertexList[i + 0]; face.m_Vertices[1] = vertexList[i + 1]; face.m_Vertices[2] = vertexList[i + 2]; } else { face.m_Vertices[0] = vertexList[i + 2]; face.m_Vertices[1] = vertexList[i + 1]; face.m_Vertices[2] = vertexList[i + 0]; } faceListDef.m_Faces.Add(face); //Because of how normals are defined in triangle strips, every 2nd triangle is clockwise, whereas all others are anti-clockwise } } break; case ModelBase.PolyListType.QuadrilateralStrip: { //4+(N-1)*2 vertices per N quads //((N-4)/2) + 1 Quads. per N Vertices int numFaces = ((primitive_vertex_size - 4) / 2) + 1; int numVertsPerFace = 4; for (int n = 0, p = 0; n < numFaces; n++, p = p + 2) { ModelBase.FaceDef face = new ModelBase.FaceDef(numVertsPerFace); face.m_Vertices[0] = vertexList[p + 0]; face.m_Vertices[1] = vertexList[p + 1]; face.m_Vertices[2] = vertexList[p + 3]; face.m_Vertices[3] = vertexList[p + 2]; faceListDef.m_Faces.Add(face); } } break; } polyListDef.m_FaceLists.Add(faceListDef); } geometryDef.m_PolyLists.Add("PolyList-" + geometryDef.m_PolyLists.Count, polyListDef); } }