public bool BuildQuadtree(ref CLFile data, ProgressBar bar) { QuadNode TempNode = new QuadNode(); TempNode.NodeSquare.X = data.quadCenterX - (data.quadLength / 2); TempNode.NodeSquare.Y = data.quadCenterZ - (data.quadLength / 2); TempNode.NodeSquare.Width = data.quadLength; TempNode.NodeSquare.Height = data.quadLength; TempNode.Child = 1; TempNode.NodeTriangleArray = Range((ushort)data.CLTriangleArray.Count()); data.CLQuadNodeList.Add(TempNode); bar.PerformStep(); int i = 0; while (i < data.CLQuadNodeList.Count) { if (data.CLQuadNodeList[i].Depth != data.MaxDepth & data.CLQuadNodeList[i].NodeTriangleArray.Count() > 0) { data.CLQuadNodeList[i].Child = (ushort)data.CLQuadNodeList.Count; data.CLQuadNodeList.Add(CreateNode(data.CLQuadNodeList[i], 0, (ushort)data.CLQuadNodeList.Count, data.basePower, data.CLTriangleArray)); bar.PerformStep(); data.CLQuadNodeList.Add(CreateNode(data.CLQuadNodeList[i], 1, (ushort)data.CLQuadNodeList.Count, data.basePower, data.CLTriangleArray)); bar.PerformStep(); data.CLQuadNodeList.Add(CreateNode(data.CLQuadNodeList[i], 2, (ushort)data.CLQuadNodeList.Count, data.basePower, data.CLTriangleArray)); bar.PerformStep(); data.CLQuadNodeList.Add(CreateNode(data.CLQuadNodeList[i], 3, (ushort)data.CLQuadNodeList.Count, data.basePower, data.CLTriangleArray)); bar.PerformStep(); data.CLQuadNodeList[i].NodeTriangleArray = null; data.CLQuadNodeList[i].NodeTriangleAmount = 0; } i += 1; } bar.Maximum = 2 * data.CLVertexArray.Count() + 2 * data.CLTriangleArray.Count() + 4 * data.CLQuadNodeList.Count(); return(true); }
public QuadNode CreateNode(QuadNode NodeParent, byte NodeOrient, ushort Count, int PowerFlag, Triangle[] CLTriangleArray) { QuadNode NodeChild = new QuadNode { Index = Count, Parent = NodeParent.Index, Child = 0, Depth = (byte)(NodeParent.Depth + 1), PosValueX = NodeParent.PosValueX, PosValueZ = NodeParent.PosValueZ, NodeSquare = new SharpDX.RectangleF(NodeParent.NodeSquare.X, NodeParent.NodeSquare.Y, NodeParent.NodeSquare.Width / 2f, NodeParent.NodeSquare.Height / 2f) }; ushort offsetValue = (ushort)Math.Pow(2, (PowerFlag - NodeChild.Depth)); if (NodeOrient == 1) { NodeChild.PosValueX += offsetValue; NodeChild.NodeSquare.X += NodeChild.NodeSquare.Width; } else if (NodeOrient == 2) { NodeChild.PosValueZ += offsetValue; NodeChild.NodeSquare.Y += NodeChild.NodeSquare.Height; } else if (NodeOrient == 3) { NodeChild.PosValueX += offsetValue; NodeChild.NodeSquare.X += NodeChild.NodeSquare.Width; NodeChild.PosValueZ += offsetValue; NodeChild.NodeSquare.Y += NodeChild.NodeSquare.Height; } NodeChild.NodeTriangleArray = GetTrianglesInsideNode(NodeChild, NodeParent.NodeTriangleArray, CLTriangleArray); NodeChild.NodeTriangleAmount = (ushort)NodeChild.NodeTriangleArray.Count(); return(NodeChild); }
public ushort[] GetTrianglesInsideNode(QuadNode Node, ushort[] TriangleList, Triangle[] CLTriangleArray) { List <ushort> NodeTriangleList = new List <ushort>(); foreach (ushort i in TriangleList) { if (Node.NodeSquare.Intersects(CLTriangleArray[i].TasRect)) { NodeTriangleList.Add(i); } } if (NodeTriangleList.Count != 0) { while (NodeTriangleList.Count < 3) { NodeTriangleList.Add(0); } } return(NodeTriangleList.ToArray()); }
public CLFile LoadCLFile(string FileName, SharpDevice device, ProgressBar bar) { CLFile data = new CLFile(0); BinaryReader CLReader = new BinaryReader(new FileStream(FileName, FileMode.Open)); CLReader.BaseStream.Position = 0; data.numBytes = Switch(CLReader.ReadUInt32()); //Get total number of bytes in file if (data.numBytes != CLReader.BaseStream.Length) { throw new ArgumentException("Not a valid CL file."); } //Get offset of structs data.pointQuadtree = Switch(CLReader.ReadUInt32()); data.pointTriangle = Switch(CLReader.ReadUInt32()); data.pointVertex = Switch(CLReader.ReadUInt32()); //Get quadtree center and radius data.quadCenterX = Switch(CLReader.ReadSingle()); data.quadCenterY = Switch(CLReader.ReadSingle()); data.quadCenterZ = Switch(CLReader.ReadSingle()); data.quadLength = Switch(CLReader.ReadSingle()); //Get amount of stuff data.basePower = Switch(CLReader.ReadUInt16()); data.numTriangles = Switch(CLReader.ReadUInt16()); data.numVertices = Switch(CLReader.ReadUInt16()); data.numQuadnodes = Switch(CLReader.ReadUInt16()); bar.Maximum = data.numTriangles + data.numVertices + 3 * data.numQuadnodes; List <Triangle> CLTriangleList = new List <Triangle>(data.numTriangles); List <CollisionVertex> CLVertexList = new List <CollisionVertex>(data.numVertices); data.MeshTypeList = new List <UInt64>(); for (int i = 0; i < data.numVertices; i++) { CLReader.BaseStream.Position = data.pointVertex + i * 0xC; CLVertexList.Add(new CollisionVertex(Switch(CLReader.ReadSingle()), Switch(CLReader.ReadSingle()), Switch(CLReader.ReadSingle()))); bar.PerformStep(); } for (int i = 0; i < data.numTriangles; i++) { CLReader.BaseStream.Position = data.pointTriangle + i * 0x20; CLTriangleList.Add(new Triangle(Switch(CLReader.ReadUInt16()), Switch(CLReader.ReadUInt16()), Switch(CLReader.ReadUInt16()))); CLReader.BaseStream.Position += 6; Vector3 Normals = new Vector3(Switch(CLReader.ReadSingle()), Switch(CLReader.ReadSingle()), Switch(CLReader.ReadSingle())); CLVertexList[CLTriangleList[i].Vertices[0]].NormalList.Add(Normals); CLVertexList[CLTriangleList[i].Vertices[1]].NormalList.Add(Normals); CLVertexList[CLTriangleList[i].Vertices[2]].NormalList.Add(Normals); UInt64 FlagsAsUint64 = CLReader.ReadUInt64(); CLTriangleList[i].ColFlags = BitConverter.GetBytes(FlagsAsUint64); if (!data.MeshTypeList.Contains(FlagsAsUint64)) { data.MeshTypeList.Add(FlagsAsUint64); } Color TempColor = new Color(CLTriangleList[i].ColFlags[1], CLTriangleList[i].ColFlags[2], CLTriangleList[i].ColFlags[3]); if (TempColor.R == 0) { TempColor.R = 255; } else { TempColor.R = (byte)(256 - (Math.Log(TempColor.R, 2) + 1) * 32); } if (TempColor.G == 0) { TempColor.G = 255; } else { TempColor.G = (byte)(256 - (Math.Log(TempColor.G, 2) + 1) * 32); } if (TempColor.B == 0) { TempColor.B = 255; } else { TempColor.B = (byte)(256 - (Math.Log(TempColor.B, 2) + 1) * 32); } CLVertexList[CLTriangleList[i].Vertices[0]].Color = TempColor; CLVertexList[CLTriangleList[i].Vertices[1]].Color = TempColor; CLVertexList[CLTriangleList[i].Vertices[2]].Color = TempColor; bar.PerformStep(); } data.CLTriangleArray = CLTriangleList.ToArray(); for (int i = 0; i < data.numQuadnodes; i++) { CLReader.BaseStream.Position = data.pointQuadtree + i * 0x20; QuadNode TempNode = new QuadNode { Index = Switch(CLReader.ReadUInt16()), Parent = Switch(CLReader.ReadUInt16()), Child = Switch(CLReader.ReadUInt16()) }; CLReader.BaseStream.Position += 8; TempNode.NodeTriangleAmount = Switch(CLReader.ReadUInt16()); TempNode.TriListOffset = Switch(CLReader.ReadUInt32()); TempNode.PosValueX = Switch(CLReader.ReadUInt16()); TempNode.PosValueZ = Switch(CLReader.ReadUInt16()); TempNode.Depth = CLReader.ReadByte(); data.CLQuadNodeList.Add(TempNode); bar.PerformStep(); } ReBuildQuadtree(ref data, bar); DetermineQuadtreeRenderStuff(ref data, device, bar); CLReader.Close(); data.CLVertexArray = new VertexColoredNormalized[CLVertexList.Count()]; for (int i = 0; i < CLVertexList.Count; i++) { data.CLVertexArray[i] = new VertexColoredNormalized(CLVertexList[i].Position, CLVertexList[i].CalculateNormals(), CLVertexList[i].Color); } int[] IndexArray = new int[data.CLTriangleArray.Count() * 3]; for (int i = 0; i < data.CLTriangleArray.Count() * 3; i++) { IndexArray[i] = data.CLTriangleArray[i / 3].Vertices[i % 3]; } if (collisionMesh != null) { collisionMesh.Dispose(); } collisionMesh = SharpMesh.Create(device, data.CLVertexArray, IndexArray, new List <SharpSubSet>() { new SharpSubSet(0, IndexArray.Count(), null) }, SharpDX.Direct3D.PrimitiveTopology.TriangleList); return(data); }