private WalkResult JoinResult(WalkResult left, WalkResult right) { var groupChildren = new List <int>(); if (left.mesh != null) { groupChildren.Add(coct.CollisionMeshGroupList.Count); coct.CompleteAndAdd( new CollisionMeshGroup { Meshes = new List <CollisionMesh> { left.mesh } } ); } else if (left.groupIndex.HasValue) { groupChildren.Add(left.groupIndex.Value); } if (right == null) { // skip } else if (right.mesh != null) { groupChildren.Add(coct.CollisionMeshGroupList.Count); coct.CompleteAndAdd( new CollisionMeshGroup { Meshes = new List <CollisionMesh> { right.mesh } } ); } else if (right.groupIndex.HasValue) { groupChildren.Add(right.groupIndex.Value); } var firstIdx1 = coct.CollisionMeshGroupList.Count; coct.CompleteAndAdd( new CollisionMeshGroup { Meshes = new List <CollisionMesh>(), Child1 = Convert.ToInt16((groupChildren.Count >= 1) ? groupChildren[0] : -1), Child2 = Convert.ToInt16((groupChildren.Count >= 2) ? groupChildren[1] : -1), } ); return(new WalkResult { groupIndex = firstIdx1, }); }
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); }
private void PerMeshClipRendering(IEnumerable <BigMesh> bigMeshes) { var firstIdx2 = coct.CollisionMeshList.Count; var helper = new BuildHelper(coct); foreach (var mesh in bigMeshes .Where(it => !it.matDef.noclip) ) { var firstIdx3 = coct.CollisionList.Count; var vifPacketIndices = new List <ushort>(mesh.vifPacketIndices); foreach (var set in TriangleStripsToTriangleFans(mesh.triangleStripList)) { var quad = set.Count == 4; var v1 = mesh.vertexList[set[0]]; var v2 = mesh.vertexList[set[1]]; var v3 = mesh.vertexList[set[2]]; var v4 = quad ? mesh.vertexList[set[3]] : Vector3.Zero; coct.CompleteAndAdd( new Collision { Vertex1 = helper.AllocateVertex(v1.X, -v1.Y, -v1.Z), // why -Y and -Z ? Vertex2 = helper.AllocateVertex(v2.X, -v2.Y, -v2.Z), Vertex3 = helper.AllocateVertex(v3.X, -v3.Y, -v3.Z), Vertex4 = Convert.ToInt16(quad ? helper.AllocateVertex(v4.X, -v4.Y, -v4.Z) : -1), SurfaceFlagsIndex = helper.AllocateSurfaceFlags(mesh.matDef.surfaceFlags), }, inflate: 1 ); } var lastIdx3 = coct.CollisionList.Count; vifPacketRenderingGroup.Add( vifPacketIndices .Distinct() .ToArray() ); var collisionMesh = coct.CompleteAndAdd( new CollisionMesh { CollisionStart = Convert.ToUInt16(firstIdx3), CollisionEnd = Convert.ToUInt16(lastIdx3), } ); } var lastIdx2 = coct.CollisionMeshList.Count; coct.CompleteAndAdd( new CollisionMeshGroup { CollisionMeshStart = Convert.ToUInt16(firstIdx2), CollisionMeshEnd = Convert.ToUInt16(lastIdx2), } ); // Entry2 index is tightly coupled to vifPacketRenderingGroup's index. // Thus do not add Entry2 unplanned. CreateDoctFromCoct(); }
private WalkResult Walk(BSP bsp) { var pair = bsp.Split(); if (pair.Length == 2) { return(JoinResult( Walk(pair[0]), Walk(pair[1]) )); } else { var firstIdx3 = coct.CollisionList.Count; var vifPacketIndices = new List <ushort>(); foreach (var point in pair[0].Points) { var mesh = point.bigMesh; vifPacketIndices.AddRange(mesh.vifPacketIndices); foreach (var set in TriangleStripsToTriangleFans(mesh.triangleStripList)) { var quad = set.Count == 4; var v1 = mesh.vertexList[set[0]]; var v2 = mesh.vertexList[set[1]]; var v3 = mesh.vertexList[set[2]]; var v4 = quad ? mesh.vertexList[set[3]] : Vector3.Zero; coct.CompleteAndAdd( new Collision { Vertex1 = helper.AllocateVertex(v1.X, -v1.Y, -v1.Z), // why -Y and -Z ? Vertex2 = helper.AllocateVertex(v2.X, -v2.Y, -v2.Z), Vertex3 = helper.AllocateVertex(v3.X, -v3.Y, -v3.Z), Vertex4 = Convert.ToInt16(quad ? helper.AllocateVertex(v4.X, -v4.Y, -v4.Z) : -1), SurfaceFlagsIndex = helper.AllocateSurfaceFlags(mesh.matDef.surfaceFlags), }, inflate: 1 ); } } var lastIdx3 = coct.CollisionList.Count; var firstIdx2 = coct.CollisionMeshList.Count; var collisionMesh = coct.CompleteAndAdd( new CollisionMesh { CollisionStart = Convert.ToUInt16(firstIdx3), CollisionEnd = Convert.ToUInt16(lastIdx3), } ); vifPacketRenderingGroup.Add( vifPacketIndices .Distinct() .ToArray() ); return(new WalkResult { meshIndex = firstIdx2, }); } }
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++) { coct.CompleteAndAdd( 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, } ); } var table3LastIdx = coct.CollisionList.Count; var table2FirstIdx = coct.CollisionMeshList.Count; coct.CompleteAndAdd( new Coct.CollisionMesh { CollisionStart = Convert.ToUInt16(table3FirstIdx), CollisionEnd = Convert.ToUInt16(table3LastIdx), v10 = 0, v12 = 0, } ); var table2LastIdx = coct.CollisionMeshList.Count; coct.CompleteAndAdd( new Coct.CollisionMeshGroup { CollisionMeshStart = Convert.ToUInt16(table2FirstIdx), CollisionMeshEnd = Convert.ToUInt16(table2LastIdx), } ); var buff = new MemoryStream(); coct.Write(buff); buff.Position = 0; File.WriteAllBytes(CoctOut, buff.ToArray()); return(0); }