public void ReadCollision() => File.OpenRead(FileName).Using(stream => { var collision = new CoctLogical(Coct.Read(stream)); Assert.Equal(188, collision.CollisionMeshGroupList.Count); Assert.Equal(7, collision.CollisionMeshGroupList[5].Child1); Assert.Equal(6, collision.CollisionMeshGroupList[5].Child2); Assert.Equal(6, collision.CollisionMeshGroupList[5].Child2); Assert.Equal(-4551, collision.CollisionMeshGroupList[5].MinX); Assert.Equal(1, collision.CollisionMeshGroupList[5].Meshes.Count); Assert.Equal(99, collision.CollisionMeshGroupList[6].Meshes[0].MinY); Assert.Equal(-3449, collision.CollisionMeshGroupList[6].Meshes[0].MaxX); Assert.Equal(1, collision.CollisionMeshGroupList[6].Meshes[0].Items.Count); Assert.Equal(24, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Vertex1); Assert.Equal(25, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Vertex2); Assert.Equal(14, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Vertex3); Assert.Equal(18, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Vertex4); Assert.Equal(6, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Co5Index); Assert.Equal(4, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Co6Index); Assert.Equal(2, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Co7Index); Assert.Equal(549, collision.VertexList.Count); Assert.Equal(233, collision.PlaneList.Count); Assert.Equal(240, collision.BoundingBoxList.Count); Assert.Equal(9, collision.SurfaceFlagsList.Count); });
protected int OnExecute(CommandLineApplication app) { var isMap = Path.GetExtension(InputFile).ToLowerInvariant() == ".map"; if (isMap) { foreach (var entry in File.OpenRead(InputFile).Using(Bar.Read) .Where(entry => false || entry.Type == Bar.EntryType.CollisionOctalTree || entry.Type == Bar.EntryType.CameraOctalTree || entry.Type == Bar.EntryType.ColorOctalTree || entry.Type == Bar.EntryType.MapCollision2 || entry.Type == Bar.EntryType.ModelCollision ) ) { Console.WriteLine($"# {entry.Name}:{entry.Index} ({entry.Type})"); PrintSummary(Coct.Read(entry.Stream)); Console.WriteLine(); } } else { PrintSummary(File.OpenRead(InputFile).Using(Coct.Read)); } return(0); }
public void WriteCollision() => File.OpenRead(FileName).Using(x => Helpers.AssertStream(x, inStream => { var outStream = new MemoryStream(); Coct.Read(inStream).Write(outStream); return(outStream); }));
public BSPWalker(BSP bsp, Coct coct, BuildHelper helper) { this.coct = coct; this.helper = helper; JoinResult( Walk(bsp), null ); }
public DumpCoctUtil(Coct coct, TextWriter writer) { this.coct = coct; this.writer = writer; if (coct.CollisionMeshGroupList.Any()) { DumpEntry1(0, 0); } }
public DumpCoctUtil(Coct coct, TextWriter writer) { this.coct = coct; this.writer = writer; if (coct.Nodes.Any()) { DumpNode(0, 0); } }
private void PrintSummary(Coct coct) { Console.WriteLine($"{coct.CollisionMeshGroupList.Count,8:#,##0} collision mesh groups."); Console.WriteLine($"{coct.CollisionMeshList.Count,8:#,##0} collision meshes."); Console.WriteLine($"{coct.CollisionList.Count,8:#,##0} collisions."); Console.WriteLine($"{coct.VertexList.Count,8:#,##0} vertices."); Console.WriteLine($"{coct.PlaneList.Count,8:#,##0} planes."); Console.WriteLine($"{coct.BoundingBoxList.Count,8:#,##0} bounding boxes."); Console.WriteLine($"{coct.SurfaceFlagsList.Count,8:#,##0} surface flags."); }
private void PrintSummary(Coct coct) { var report = new Report(); GenerateReport(coct, 1, 0, report); Console.WriteLine($"Node count: {report.NodeCount,8:#,##0}"); Console.WriteLine($"Leaf count: {report.LeafCount,8:#,##0}"); Console.WriteLine($"Tree depth: {report.TreeDepth,8:#,##0}"); Console.WriteLine($"Mesh count: {report.MeshCount,8:#,##0}"); Console.WriteLine($"Coll count: {report.CollisionCount,8:#,##0}"); Console.WriteLine($"Vert count: {report.VertexCount,8:#,##0}"); }
public void TestLogicalReadWrite() { File.OpenRead(FileName).Using( inStream => { var outStream = new MemoryStream(); var coct = Coct.Read(inStream); var coctLogical = new CoctLogical(coct); var coctBack = coctLogical.CreateCoct(); coctBack.Write(outStream); outStream.Position = 0; { var collision = new CoctLogical(Coct.Read(outStream)); Assert.Equal(188, collision.CollisionMeshGroupList.Count); Assert.Equal(7, collision.CollisionMeshGroupList[5].Child1); Assert.Equal(6, collision.CollisionMeshGroupList[5].Child2); Assert.Equal(6, collision.CollisionMeshGroupList[5].Child2); Assert.Equal(-4551, collision.CollisionMeshGroupList[5].MinX); Assert.Equal(1, collision.CollisionMeshGroupList[5].Meshes.Count); Assert.Equal(99, collision.CollisionMeshGroupList[6].Meshes[0].MinY); Assert.Equal(-3449, collision.CollisionMeshGroupList[6].Meshes[0].MaxX); Assert.Equal(1, collision.CollisionMeshGroupList[6].Meshes[0].Items.Count); Assert.Equal(24, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Vertex1); Assert.Equal(25, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Vertex2); Assert.Equal(14, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Vertex3); Assert.Equal(18, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Vertex4); Assert.Equal(6, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Co5Index); Assert.Equal(4, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Co6Index); Assert.Equal(2, collision.CollisionMeshGroupList[7].Meshes[0].Items[0].Co7Index); Assert.Equal(549, collision.VertexList.Count); Assert.Equal(233, collision.PlaneList.Count); Assert.Equal(240, collision.BoundingBoxList.Count); Assert.Equal(9, collision.SurfaceFlagsList.Count); } } ); }
private static void GenerateReport(Coct coct, int depth, int index, Report report) { if (index == -1) { return; } report.NodeCount++; report.TreeDepth = Math.Max(report.TreeDepth, depth); var node = coct.Nodes[index]; if (node.Child1 >= 0) { var childDepth = depth + 1; GenerateReport(coct, childDepth, node.Child1, report); GenerateReport(coct, childDepth, node.Child2, report); GenerateReport(coct, childDepth, node.Child3, report); GenerateReport(coct, childDepth, node.Child4, report); GenerateReport(coct, childDepth, node.Child5, report); GenerateReport(coct, childDepth, node.Child6, report); GenerateReport(coct, childDepth, node.Child7, report); GenerateReport(coct, childDepth, node.Child8, report); } else { report.LeafCount++; } foreach (var mesh in node.Meshes) { report.MeshCount++; foreach (var collision in mesh.Collisions) { report.CollisionCount++; report.VertexCount += 3; if (collision.Vertex4 >= 0) { report.VertexCount++; } } } }
private static void Node(Coct coct, int index) { if (index == -1) { return; } ForTreeNode($"Node {index}", () => { var node = coct.Nodes[index]; ImGui.Text($"Box {node.BoundingBox}"); Node(coct, node.Child1); Node(coct, node.Child2); Node(coct, node.Child3); Node(coct, node.Child4); Node(coct, node.Child5); Node(coct, node.Child6); Node(coct, node.Child7); Node(coct, node.Child8); foreach (var mesh in node.Meshes) { ForTreeNode($"Mesh {mesh.GetHashCode()}", () => { ImGui.Text($"Box {mesh.BoundingBox}"); ImGui.Text($"Visibility {mesh.Visibility}"); ImGui.Text($"Group {mesh.Group}"); foreach (var collision in mesh.Collisions) { ForTreeNode($"Collision {collision.GetHashCode()}", () => { ImGui.Text($"Ground {collision.Ground}"); ImGui.Text($"Floor Level {collision.FloorLevel}"); ImGui.Text($"Plane {collision.Plane}"); ImGui.Text($"Bound Box {collision.BoundingBox}"); ImGui.Text($"Flags {collision.Attributes:X08}"); }); } }); } }); }
private static void Node(Coct coct, int index) { if (index == -1) { return; } ForTreeNode($"Node {index}", () => { var node = coct.CollisionMeshGroupList[index]; ImGui.Text($"Box {node.BoundingBox}"); Node(coct, node.Child1); Node(coct, node.Child2); Node(coct, node.Child3); Node(coct, node.Child4); Node(coct, node.Child5); Node(coct, node.Child6); Node(coct, node.Child7); Node(coct, node.Child8); foreach (var mesh in node.Meshes) { ForTreeNode($"Mesh {mesh.GetHashCode()}", () => { ImGui.Text($"Box {mesh.BoundingBox}"); ImGui.Text($"Unk10 {mesh.v10}"); ImGui.Text($"Unk12 {mesh.v12}"); foreach (var collision in mesh.Collisions) { ForTreeNode($"Collision {collision.GetHashCode()}", () => { ImGui.Text($"Unk00 {collision.v00}"); ImGui.Text($"Plane {collision.Plane}"); ImGui.Text($"Bound Box {collision.BoundingBox}"); ImGui.Text($"Flags {collision.SurfaceFlags:X08}"); }); } }); } }); }
public void TestMapGenUtil(string inputModel) { var outMap = Path.ChangeExtension(inputModel, ".map"); using var disposer = new FileDisposer(outMap); new MapGenUtil().Run(inputModel, outMap); var barEntries = File.OpenRead(outMap).Using(Bar.Read); { var doct = Doct.Read(barEntries.Single(it => it.Type == Bar.EntryType.DrawOctalTree).Stream); var writer = new StringWriter(); new DumpDoctUtil(doct, writer); var doctDumpFile = Path.ChangeExtension(inputModel, ".doct.dump"); Assert.Equal( expected: File.ReadAllText(doctDumpFile), actual: writer.ToString(), ignoreLineEndingDifferences: true ); } { var coct = Coct.Read(barEntries.Single(it => it.Type == Bar.EntryType.CollisionOctalTree).Stream); var writer = new StringWriter(); new DumpCoctUtil(coct, writer); var coctDumpFile = Path.ChangeExtension(inputModel, ".coct.dump"); Assert.Equal( expected: File.ReadAllText(coctDumpFile), actual: writer.ToString(), ignoreLineEndingDifferences: true ); } }
public void ReadCollision() => File.OpenRead(FileName).Using(stream => { var collision = Coct.Read(stream); Assert.Equal(188, collision.Nodes.Count); Assert.Equal(7, collision.Nodes[5].Child1); Assert.Equal(6, collision.Nodes[5].Child2); Assert.Equal(6, collision.Nodes[5].Child2); Assert.Equal(-4551, collision.Nodes[5].BoundingBox.Minimum.X); Assert.Equal(1, collision.Nodes[5].Meshes.Count); Assert.Equal(99, collision.Nodes[6].Meshes[0].BoundingBox.Minimum.Y); Assert.Equal(-3449, collision.Nodes[6].Meshes[0].BoundingBox.Maximum.X); Assert.Equal(1, collision.Nodes[6].Meshes[0].Collisions.Count); Assert.Equal(24, collision.Nodes[7].Meshes[0].Collisions[0].Vertex1); Assert.Equal(25, collision.Nodes[7].Meshes[0].Collisions[0].Vertex2); Assert.Equal(14, collision.Nodes[7].Meshes[0].Collisions[0].Vertex3); Assert.Equal(18, collision.Nodes[7].Meshes[0].Collisions[0].Vertex4); Assert.Equal(549, collision.VertexList.Count); });
public void IsValid() => File.OpenRead(FileName).Using(stream => Coct.IsValid(stream));
protected int OnExecute(CommandLineApplication app) { var coct = new Coct(); var bbox = BBox.Split(',') .Select(one => short.Parse(one)) .ToArray(); var invMinX = bbox[0]; var invMinY = bbox[1]; var invMinZ = bbox[2]; var invMaxX = bbox[3]; var invMaxY = bbox[4]; var invMaxZ = bbox[5]; var minX = -invMinX; var minY = -invMinY; var minZ = -invMinZ; var maxX = -invMaxX; var maxY = -invMaxY; var maxZ = -invMaxZ; var builder = new Coct.BuildHelper(coct); // (forwardVec) // +Z // A / +Y (upVec) // | / // |/ // +--> +X (rightVec) // 7 == 6 top // | | top // 4 == 5 top // // 3 == 2 bottom // | | bottom // 0 == 1 bottom var table4Idxes = new short[] { builder.AllocateVertex(minX, minY, minZ, 1), builder.AllocateVertex(maxX, minY, minZ, 1), builder.AllocateVertex(maxX, minY, maxZ, 1), builder.AllocateVertex(minX, minY, maxZ, 1), builder.AllocateVertex(minX, maxY, minZ, 1), builder.AllocateVertex(maxX, maxY, minZ, 1), builder.AllocateVertex(maxX, maxY, maxZ, 1), builder.AllocateVertex(minX, maxY, maxZ, 1), }; // side: // 0 bottom // 1 top // 2 west // 3 east // 4 south // 5 north var planes = new Plane[] { new Plane(0, -1, 0, +minY), //bottom new Plane(0, +1, 0, -maxY), //up new Plane(-1, 0, 0, +minX), //west new Plane(+1, 0, 0, -maxX), //east new Plane(0, 0, -1, +minZ), //south new Plane(0, 0, +1, -maxZ), //north }; var faceVertexOrders = new int[, ] { { 0, 1, 2, 3 }, //bottom { 4, 7, 6, 5 }, //top { 3, 7, 4, 0 }, //west { 1, 5, 6, 2 }, //east { 2, 6, 7, 3 }, //south { 0, 4, 5, 1 }, //north }; var collisionMesh = new Coct.CollisionMesh { Collisions = new List <Coct.Collision>() }; for (var side = 0; side < 6; side++) { var collision = new Coct.Collision { Ground = 0, FloorLevel = 0, Vertex1 = table4Idxes[faceVertexOrders[side, 0]], Vertex2 = table4Idxes[faceVertexOrders[side, 1]], Vertex3 = table4Idxes[faceVertexOrders[side, 2]], Vertex4 = table4Idxes[faceVertexOrders[side, 3]], Plane = planes[side], BoundingBox = BoundingBoxInt16.Invalid, Attributes = new Coct.Attributes() { Flags = 0x3F1 }, }; coct.Complete(collision); collisionMesh.Collisions.Add(collision); } coct.Complete(collisionMesh); coct.CompleteAndAdd( new Coct.CollisionNode { Meshes = new List <Coct.CollisionMesh>() { collisionMesh } } ); var buff = new MemoryStream(); coct.Write(buff); buff.Position = 0; File.WriteAllBytes(CoctOut, buff.ToArray()); return(0); }
protected int OnExecute(CommandLineApplication app) { var coct = new Coct(); var bbox = BBox.Split(',') .Select(one => short.Parse(one)) .ToArray(); var invMinX = bbox[0]; var invMinY = bbox[1]; var invMinZ = bbox[2]; var invMaxX = bbox[3]; var invMaxY = bbox[4]; var invMaxZ = bbox[5]; var minX = -invMinX; var minY = -invMinY; var minZ = -invMinZ; var maxX = -invMaxX; var maxY = -invMaxY; var maxZ = -invMaxZ; var builder = new Coct.BuildHelper(coct); var table7Idx = builder.AllocateSurfaceFlags(0x3F1); // (forwardVec) // +Z // A / +Y (upVec) // | / // |/ // +--> +X (rightVec) // 7 == 6 top // | | top // 4 == 5 top // // 3 == 2 bottom // | | bottom // 0 == 1 bottom var table4Idxes = new short[] { builder.AllocateVertex(minX, minY, minZ, 1), builder.AllocateVertex(maxX, minY, minZ, 1), builder.AllocateVertex(maxX, minY, maxZ, 1), builder.AllocateVertex(minX, minY, maxZ, 1), builder.AllocateVertex(minX, maxY, minZ, 1), builder.AllocateVertex(maxX, maxY, minZ, 1), builder.AllocateVertex(maxX, maxY, maxZ, 1), builder.AllocateVertex(minX, maxY, maxZ, 1), }; // side: // 0 bottom // 1 top // 2 west // 3 east // 4 south // 5 north var table5Idxes = new short[] { builder.AllocatePlane(0, -1, 0, +minY), //bottom builder.AllocatePlane(0, +1, 0, -maxY), //up builder.AllocatePlane(-1, 0, 0, +minX), //west builder.AllocatePlane(+1, 0, 0, -maxX), //east builder.AllocatePlane(0, 0, -1, +minZ), //south builder.AllocatePlane(0, 0, +1, -maxZ), //north }; var faceVertexOrders = new int[, ] { { 0, 1, 2, 3 }, //bottom { 4, 7, 6, 5 }, //top { 3, 7, 4, 0 }, //west { 1, 5, 6, 2 }, //east { 2, 6, 7, 3 }, //south { 0, 4, 5, 1 }, //north }; var table3FirstIdx = coct.CollisionList.Count; for (var side = 0; side < 6; side++) { var ent3 = new Coct.Collision { v00 = 0, Vertex1 = table4Idxes[faceVertexOrders[side, 0]], Vertex2 = table4Idxes[faceVertexOrders[side, 1]], Vertex3 = table4Idxes[faceVertexOrders[side, 2]], Vertex4 = table4Idxes[faceVertexOrders[side, 3]], PlaneIndex = table5Idxes[side], BoundingBoxIndex = -1, // set later SurfaceFlagsIndex = table7Idx, }; builder.CompletePlane(ent3); builder.CompleteBBox(ent3); coct.CollisionList.Add(ent3); } var table3LastIdx = coct.CollisionList.Count; var table2FirstIdx = coct.CollisionMeshList.Count; var ent2 = new Coct.CollisionMesh { CollisionStart = Convert.ToUInt16(table3FirstIdx), CollisionEnd = Convert.ToUInt16(table3LastIdx), v10 = 0, v12 = 0, }; builder.CompleteBBox(ent2); coct.CollisionMeshList.Add(ent2); var table2LastIdx = coct.CollisionMeshList.Count; var ent1 = new Coct.CollisionMeshGroup { CollisionMeshStart = Convert.ToUInt16(table2FirstIdx), CollisionMeshEnd = Convert.ToUInt16(table2LastIdx), }; builder.CompleteBBox(ent1); coct.CollisionMeshGroupList.Add(ent1); var buff = new MemoryStream(); coct.Write(buff); buff.Position = 0; File.WriteAllBytes(CoctOut, buff.ToArray()); return(0); }
public static void Run(Coct coct) => ForHeader("Collision", () => { Node(coct, 0); });