示例#1
0
        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);
        });
示例#2
0
            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);
            }
示例#3
0
        public void WriteCollision() => File.OpenRead(FileName).Using(x =>
                                                                      Helpers.AssertStream(x, inStream =>
        {
            var outStream = new MemoryStream();
            Coct.Read(inStream).Write(outStream);

            return(outStream);
        }));
示例#4
0
            public BSPWalker(BSP bsp, Coct coct, BuildHelper helper)
            {
                this.coct   = coct;
                this.helper = helper;

                JoinResult(
                    Walk(bsp),
                    null
                    );
            }
示例#5
0
        public DumpCoctUtil(Coct coct, TextWriter writer)
        {
            this.coct   = coct;
            this.writer = writer;

            if (coct.CollisionMeshGroupList.Any())
            {
                DumpEntry1(0, 0);
            }
        }
示例#6
0
        public DumpCoctUtil(Coct coct, TextWriter writer)
        {
            this.coct   = coct;
            this.writer = writer;

            if (coct.Nodes.Any())
            {
                DumpNode(0, 0);
            }
        }
示例#7
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.");
 }
示例#8
0
            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}");
            }
示例#9
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);
                }
            }
                );
        }
示例#10
0
            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++;
                        }
                    }
                }
            }
示例#11
0
        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}");
                            });
                        }
                    });
                }
            });
        }
示例#12
0
        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}");
                            });
                        }
                    });
                }
            });
        }
示例#13
0
        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
                    );
            }
        }
示例#14
0
        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);
        });
示例#15
0
 public void IsValid() => File.OpenRead(FileName).Using(stream =>
                                                        Coct.IsValid(stream));
示例#16
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);

                // (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);
            }
示例#17
0
文件: Program.cs 项目: xorllc/OpenKh
            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);
            }
示例#18
0
 public static void Run(Coct coct) => ForHeader("Collision", () =>
 {
     Node(coct, 0);
 });