private void LoadTrianglesFromDZB(EndianBinaryReader reader, List <Vector3> vertices, int offset, int count) { reader.BaseStream.Position = offset; for (int i = 0; i < count; i++) { CollisionTriangle new_tri = new CollisionTriangle(reader, vertices, m_Nodes, m_Properties); Triangles.Add(new_tri); } }
private void LoadGeometryFromCollada(CollisionGroupNode parent, geometry geo) { mesh m = geo.Item as mesh; // For safety, read the model's definition of where the position data is // and grab it from there. We could just do a search for "position" in the // source list names, but this makes sure there are no errors. InputLocal pos_input = Array.Find(m.vertices.input, x => x.semantic == "POSITION"); source pos_src = Array.Find(m.source, x => x.id == pos_input.source.Trim('#')); float_array pos_arr = pos_src.Item as float_array; // For some reason Maya puts a leading space in the face index data, // so we need to trim that out before trying to parse the index string. triangles tris = m.Items[0] as triangles; string[] indices = tris.p.Trim(' ').Split(' '); int stride = tris.input.Length; // Make sure this tool can support meshes with multiple vertex attributes. for (int i = 0; i < indices.Length; i += stride * 3) { int vec1_index = Convert.ToInt32(indices[i]); int vec2_index = Convert.ToInt32(indices[i + stride]); int vec3_index = Convert.ToInt32(indices[i + (stride * 2)]); Vector3 vec1 = new Vector3((float)pos_arr.Values[vec1_index * 3], (float)pos_arr.Values[(vec1_index * 3) + 1], (float)pos_arr.Values[(vec1_index * 3) + 2]); Vector3 vec2 = new Vector3((float)pos_arr.Values[vec2_index * 3], (float)pos_arr.Values[(vec2_index * 3) + 1], (float)pos_arr.Values[(vec2_index * 3) + 2]); Vector3 vec3 = new Vector3((float)pos_arr.Values[vec3_index * 3], (float)pos_arr.Values[(vec3_index * 3) + 1], (float)pos_arr.Values[(vec3_index * 3) + 2]); // The benefit of using this library is that we easily got the up-axis // info from the file. If the up-axis was defined as Z-up, we need to // swap the Y and Z components of our vectors so the mesh isn't sideways. // (The Wind Waker is Y-up.) if (m_UpAxis == UpAxisType.Z_UP) { vec1 = SwapYZ(vec1); vec2 = SwapYZ(vec2); vec3 = SwapYZ(vec3); } CollisionTriangle new_tri = new CollisionTriangle(vec1, vec2, vec3, parent); parent.Triangles.Add(new_tri); Triangles.Add(new_tri); } }
private void LoadFromObj(string[] lines, int roomIndex, int roomTableIndex) { RootNode = new CollisionGroupNode(null, string.Format("R{0}", roomTableIndex.ToString("D2"))); m_Nodes.Add(RootNode); CollisionGroupNode CurrentCategory = null; CollisionGroupNode CurrentGroup = null; List <Vector3> Vertices = new List <Vector3>(); for (int i = 0; i < lines.Length; i++) { string[] SplitLine = lines[i].Split(' '); switch (SplitLine[0]) { case "o": CurrentCategory = new CollisionGroupNode(RootNode, $"C_{ SplitLine[1] }"); CurrentGroup = new CollisionGroupNode(CurrentCategory, $"G_{ SplitLine[1] }"); RootNode.Children.Add(CurrentCategory); CurrentCategory.Children.Add(CurrentGroup); m_Nodes.Add(CurrentCategory); m_Nodes.Add(CurrentGroup); break; case "v": // We've been burned by Europe before since they use , instead of . for marking decimal places. So this just makes sure that's not an issue. float XCoord = Convert.ToSingle(SplitLine[1].Replace(',', '.')); float YCoord = Convert.ToSingle(SplitLine[2].Replace(',', '.')); float ZCoord = Convert.ToSingle(SplitLine[3].Replace(',', '.')); Vertices.Add(new Vector3(XCoord, YCoord, ZCoord)); break; case "f": int V1 = Convert.ToInt32(SplitLine[1].Split('/')[0]) - 1; int V2 = Convert.ToInt32(SplitLine[2].Split('/')[0]) - 1; int V3 = Convert.ToInt32(SplitLine[3].Split('/')[0]) - 1; CollisionTriangle NewTri = new CollisionTriangle(Vertices[V1], Vertices[V2], Vertices[V3], CurrentGroup); Triangles.Add(NewTri); CurrentGroup.Triangles.Add(NewTri); break; default: break; } } FinalizeLoad(); // Automatically set the room number. RootNode.RoomNumber = roomIndex; // Copy the room table index used by the original collision mesh's root node to all of the groups loaded from the dae. // This isn't perfect because some rooms (like dungeon hub rooms) have different collision groups using different room tables, and this method doesn't preserve that. // But this does work much better than not setting the room table index at all. foreach (CollisionGroupNode node in m_Nodes) { node.RoomTableIndex = roomTableIndex; } }