public bool TestTriangle(Triangle triangle) { foreach(var vertex in triangle.Vertices) if(TestPoint(vertex.Position)) return true; // a bad part begins here // intersect every box edge with a triangle and // intersect every triangle edge with box // triangle edges vs box part List<Ray> triangleRays = new List<Ray>(); /* * 0 1 * 0 2 * 1 0 * 1 2 * 2 0 * 2 1 */ triangleRays.Add(new Ray(triangle.Vertices[0].Position, triangle.Vertices[0].Position - triangle.Vertices[1].Position, (triangle.Vertices[0].Position - triangle.Vertices[1].Position).Length)); triangleRays.Add(new Ray(triangle.Vertices[0].Position, triangle.Vertices[0].Position - triangle.Vertices[2].Position, (triangle.Vertices[0].Position - triangle.Vertices[2].Position).Length)); triangleRays.Add(new Ray(triangle.Vertices[1].Position, triangle.Vertices[1].Position - triangle.Vertices[0].Position, (triangle.Vertices[1].Position - triangle.Vertices[0].Position).Length)); triangleRays.Add(new Ray(triangle.Vertices[1].Position, triangle.Vertices[1].Position - triangle.Vertices[2].Position, (triangle.Vertices[1].Position - triangle.Vertices[2].Position).Length)); triangleRays.Add(new Ray(triangle.Vertices[2].Position, triangle.Vertices[2].Position - triangle.Vertices[0].Position, (triangle.Vertices[2].Position - triangle.Vertices[0].Position).Length)); triangleRays.Add(new Ray(triangle.Vertices[2].Position, triangle.Vertices[2].Position - triangle.Vertices[1].Position, (triangle.Vertices[2].Position - triangle.Vertices[1].Position).Length)); Vector3 bMin = Center - new Vector3(Radius); Vector3 bMax = Center + new Vector3(Radius); // since NO origin will be in a box there should be 2 or 0 intersections foreach(var r in triangleRays) { Vector2 ires = IntersectBox(r.Origin, r.Direction, bMin, bMax); if(ires.X >= ires.Y && ires.Y >= -r.EstimatedLength && ires.Y <= r.EstimatedLength) return true; } List<Ray> boxEdgesRays = new List<Ray>(); boxEdgesRays.Add(new Ray(bMin, new Vector3(Radius * 2, 0, 0), Radius * 2)); boxEdgesRays.Add(new Ray(bMin, new Vector3(0, Radius * 2, 0), Radius * 2)); boxEdgesRays.Add(new Ray(bMin, new Vector3(0, 0, Radius * 2), Radius * 2)); boxEdgesRays.Add(new Ray(bMax, new Vector3(Radius * 2, 0, 0), Radius * 2)); boxEdgesRays.Add(new Ray(bMax, new Vector3(0, Radius * 2, 0), Radius * 2)); boxEdgesRays.Add(new Ray(bMax, new Vector3(0, 0, Radius * 2), Radius * 2)); foreach(var r in boxEdgesRays) { float ires = IntersectTriangle(r.Origin, r.Direction, triangle.Vertices.Select<Vertex, Vector3>((a) => a.Position).ToArray()); if(ires > 0 && ires <= r.EstimatedLength) return true; } return false; }
public void PrepareTrianglesData(List<Mesh3d> meshes) { List<Triangle> triangles = new List<Triangle>(); foreach(var mesh in meshes) { var Triangle = new Triangle(); var vertices = mesh.MainObjectInfo.GetOrderedVertices(); var normals = mesh.MainObjectInfo.GetOrderedNormals(); for(int i = 0; i < vertices.Count; i++) { var vertex = new Vertex() { Position = vertices[i], Normal = normals[i], Albedo = mesh.MainMaterial.Color.Xyz }; vertex.Tranform(mesh.Matrix); Triangle.Vertices.Add(vertex); if(Triangle.Vertices.Count == 3) { triangles.Add(Triangle); Triangle = new Triangle(); } } } SceneOctalTree tree = new SceneOctalTree(); Triangle[] trcopy = new Triangle[triangles.Count]; triangles.CopyTo(trcopy); tree.CreateFromTriangleList(trcopy.ToList()); TriangleCount = triangles.Count; // lets prepare byte array // layout // posx, posy, poz, norx, nory, norz, albr, albg, albz List<byte> bytes = new List<byte>(); foreach(var triangle in triangles) { foreach(var vertex in triangle.Vertices) { bytes.AddRange(BitConverter.GetBytes(vertex.Position.X)); bytes.AddRange(BitConverter.GetBytes(vertex.Position.Y)); bytes.AddRange(BitConverter.GetBytes(vertex.Position.Z)); bytes.AddRange(BitConverter.GetBytes(0.0f)); bytes.AddRange(BitConverter.GetBytes(vertex.Normal.X)); bytes.AddRange(BitConverter.GetBytes(vertex.Normal.Y)); bytes.AddRange(BitConverter.GetBytes(vertex.Normal.Z)); bytes.AddRange(BitConverter.GetBytes(0.0f)); bytes.AddRange(BitConverter.GetBytes(vertex.Albedo.X)); bytes.AddRange(BitConverter.GetBytes(vertex.Albedo.Y)); bytes.AddRange(BitConverter.GetBytes(vertex.Albedo.Z)); bytes.AddRange(BitConverter.GetBytes(0.0f)); } } MeshDataSSBO = new ShaderStorageBuffer(); TrianglesStream = new ShaderStorageBuffer(); OctreeBoxes = new ShaderStorageBuffer(); GLThread.Invoke(() => { MeshDataSSBO.MapData(bytes.ToArray()); tree.PopulateSSBOs(TrianglesStream, OctreeBoxes); BoxesCount = tree.TotalBoxesCount; }); RandomsSSBO = new ShaderStorageBuffer(); }