public void Execute() { var bvh = new BoundingVolumeHierarchy(Nodes, NodeFilters); bvh.BuildFirstNLevels(Points, Ranges, BranchNodeOffsets, ThreadCount, out int branchCount); BranchCount[0] = branchCount; }
private bool FindInteractionVolumeHit(Ray ray, out int interactionVolumeHitIndex, out IntersectInfo info) { interactionVolumeHitIndex = -1; if (interactionVolumes.Count == 0 || interactionVolumes[0].CollisionVolume == null) { info = null; return(false); } List <IRayTraceable> mesheTraceables = new List <IRayTraceable>(); foreach (InteractionVolume interactionVolume in interactionVolumes) { IRayTraceable traceData = interactionVolume.CollisionVolume; mesheTraceables.Add(new Transform(traceData, interactionVolume.TotalTransform)); } IRayTraceable allObjects = BoundingVolumeHierarchy.CreateNewHierachy(mesheTraceables); info = allObjects.GetClosestIntersection(ray); if (info != null) { for (int i = 0; i < interactionVolumes.Count; i++) { List <IRayTraceable> insideBounds = new List <IRayTraceable>(); interactionVolumes[i].CollisionVolume.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox()); if (insideBounds.Contains(info.closestHitObject)) { interactionVolumeHitIndex = i; return(true); } } } return(false); }
public static IPrimitive Convert(IObject3D item, MaterialAbstract partMaterial = null) { List <IPrimitive> renderCollection = new List <IPrimitive>(); if (partMaterial == null) { partMaterial = new SolidMaterial(new ColorF(.9, .2, .1), .01, 0.0, 2.0); } int index = 0; Vector3[] triangle = new Vector3[3]; foreach (Mesh mesh in item.VisibleMeshes().Select(i => i.Mesh)) { foreach (Face face in mesh.Faces) { foreach (Vertex vertex in face.Vertices()) { triangle[index++] = vertex.Position; if (index == 3) { index = 0; renderCollection.Add(new TriangleShape(triangle[0], triangle[1], triangle[2], partMaterial)); } } } } return(BoundingVolumeHierarchy.CreateNewHierachy(renderCollection)); }
public static IRayTraceable Convert(PolygonMesh.Mesh simpleMesh) { List <IRayTraceable> renderCollection = new List <IRayTraceable>(); //SolidMaterial redStuff = new SolidMaterial(new RGBA_Floats(.9, .2, .1), .01, 0.0, 2.0); SolidMaterial mhBlueStuff = new SolidMaterial(new RGBA_Floats(0, .32, .58), .01, 0.0, 2.0); int index = 0; Vector3[] triangle = new Vector3[3]; //PolygonMesh.Mesh simpleMesh = PolygonMesh.Processors.StlProcessing.Load("complex.stl"); //PolygonMesh.Mesh simpleMesh = PolygonMesh.Processors.StlProcessing.Load("Spider With Base.stl"); foreach (PolygonMesh.Face face in simpleMesh.Faces) { foreach (PolygonMesh.Vertex vertex in face.Vertices()) { triangle[index++] = vertex.Position; if (index == 3) { index = 0; renderCollection.Add(new TriangleShape(triangle[0], triangle[1], triangle[2], mhBlueStuff)); } } } return(BoundingVolumeHierarchy.CreateNewHierachy(renderCollection)); }
public void Execute() { if (ShouldDoWork[0] == 0) { // Restore original branch count BranchCount[0] = OldBranchCount[0]; return; } int minBranchNodeIndex = BranchNodeOffsets[0] - 1; int branchCount = BranchCount[0]; for (int i = 1; i < BranchCount[0]; i++) { minBranchNodeIndex = math.min(BranchNodeOffsets[i] - 1, minBranchNodeIndex); } var bvh = new BoundingVolumeHierarchy(Nodes, NodeFilters); bvh.Refit(Aabbs, 1, minBranchNodeIndex); if (NodeFilters != null) { bvh.BuildCombinedCollisionFilter(LeafFilters, 1, minBranchNodeIndex); } }
public static IPrimitive Convert(IObject3D rootItem) { var tracePrimitives = new List <IPrimitive>(); foreach (var item in rootItem.VisibleMeshes()) { SolidMaterial partMaterial; var color = item.WorldColor(rootItem); if (color.alpha != 0) { partMaterial = new SolidMaterial(new ColorF(color.Red0To1, color.Green0To1, color.Blue0To1), .01, 0.0, 2.0); } else { partMaterial = new SolidMaterial(new ColorF(.9, .2, .1), .01, 0.0, 2.0); } var worldMatrix = item.WorldMatrix(rootItem); item.Mesh.AddTracePrimitives(partMaterial, worldMatrix, tracePrimitives); } // return an empty collection return(BoundingVolumeHierarchy.CreateNewHierachy(tracePrimitives)); }
public static IPrimitive Convert(PolygonMesh.Mesh simpleMesh, MaterialAbstract partMaterial = null) { List <IPrimitive> renderCollection = new List <IPrimitive>(); if (partMaterial == null) { partMaterial = new SolidMaterial(new RGBA_Floats(.9, .2, .1), .01, 0.0, 2.0); } int index = 0; Vector3[] triangle = new Vector3[3]; foreach (PolygonMesh.Face face in simpleMesh.Faces) { foreach (PolygonMesh.Vertex vertex in face.Vertices()) { triangle[index++] = vertex.Position; if (index == 3) { index = 0; renderCollection.Add(new TriangleShape(triangle[0], triangle[1], triangle[2], partMaterial)); } } } return(BoundingVolumeHierarchy.CreateNewHierachy(renderCollection)); }
public static ITraceable Convert(IObject3D item, MaterialAbstract partMaterial = null) { var renderCollection = new List <ITraceable>(); if (partMaterial == null) { partMaterial = new SolidMaterial(new ColorF(.9, .2, .1), .01, 0.0, 2.0); } int index = 0; var triangle = new Vector3[3]; foreach (Mesh mesh in item.VisibleMeshes().Select(i => i.Mesh)) { throw new NotImplementedException(); //foreach (Face face in mesh.Faces) //{ // foreach (Vertex vertex in face.Vertices()) // { // triangle[index++] = vertex.Position; // if (index == 3) // { // index = 0; // renderCollection.Add(new TriangleShape(triangle[0], triangle[1], triangle[2], partMaterial)); // } // } //} } return(BoundingVolumeHierarchy.CreateNewHierachy(renderCollection)); }
public static void CreateITraceableForMeshGroup(List <PlatingMeshGroupData> perMeshGroupInfo, List <MeshGroup> meshGroups, int meshGroupIndex, ReportProgressRatio reportProgress) { if (meshGroups != null) { MeshGroup meshGroup = meshGroups[meshGroupIndex]; perMeshGroupInfo[meshGroupIndex].meshTraceableData.Clear(); int totalActionCount = 0; foreach (Mesh mesh in meshGroup.Meshes) { totalActionCount += mesh.Faces.Count; } int currentAction = 0; bool needUpdateTitle = true; for (int i = 0; i < meshGroup.Meshes.Count; i++) { Mesh mesh = meshGroup.Meshes[i]; List <IPrimitive> allPolys = AddTraceDataForMesh(mesh, totalActionCount, ref currentAction, ref needUpdateTitle, reportProgress); needUpdateTitle = true; if (reportProgress != null) { bool continueProcessing; reportProgress(currentAction / (double)totalActionCount, "Creating Trace Group", out continueProcessing); } // only allow limited recusion to speed this up building this data IPrimitive traceData = BoundingVolumeHierarchy.CreateNewHierachy(allPolys, 0); perMeshGroupInfo[meshGroupIndex].meshTraceableData.Add(traceData); } } }
public static void CreateITraceableForMesh(List <PlatingMeshData> perMeshInfo, List <Mesh> meshes, int i) { if (meshes[i] != null) { List <IRayTraceable> allPolys = new List <IRayTraceable>(); List <Vector3> positions = new List <Vector3>(); foreach (Face face in meshes[i].Faces) { positions.Clear(); foreach (Vertex vertex in face.VertexIterator()) { positions.Add(vertex.Position); } // We should use the teselator for this if it is greater than 3. Vector3 next = positions[1]; for (int positionIndex = 2; positionIndex < positions.Count; positionIndex++) { TriangleShape triangel = new TriangleShape(positions[0], next, positions[positionIndex], null); allPolys.Add(triangel); next = positions[positionIndex]; } } perMeshInfo[i].traceableData = BoundingVolumeHierarchy.CreateNewHierachy(allPolys); } }
/// <summary> /// Create a bounding volume hierarchy for the give mesh. /// </summary> /// <param name="mesh">The mesh to add the BVH to.</param> /// <param name="material">The tracing material to use.</param> /// <param name="matrix">A transformation to apply to the trace data</param> /// <param name="maxRecursion">The max depth to create the BVH tree.</param> /// <returns>The created BVH tree.</returns> public static ITraceable CreateBVHData(this Mesh mesh, MaterialAbstract material, Matrix4X4 matrix, int maxRecursion = int.MaxValue) { var allPolys = new List <ITraceable>(); mesh.AddTraceables(material, matrix, allPolys); return(BoundingVolumeHierarchy.CreateNewHierachy(allPolys, maxRecursion)); }
public static IPrimitive CreateTraceDataForMesh(Mesh mesh) { int unusedInt = 0; bool unusedBool = false; List <IPrimitive> allPolys = AddTraceDataForMesh(mesh, 0, ref unusedInt, ref unusedBool, null); return(BoundingVolumeHierarchy.CreateNewHierachy(allPolys)); }
public static IPrimitive Convert(List <IObject3D> renderDatas) { List <IPrimitive> renderCollection = new List <IPrimitive>(); foreach (var renderData in renderDatas) { renderCollection.Add(Convert(renderData)); } return(BoundingVolumeHierarchy.CreateNewHierachy(renderCollection)); }
public void NodeCount() { const int primitiveCount = 1_000; for (int i = 0; i < 10; i++) { BoundingVolumeHierarchy bvh = RandomBVH(primitiveCount); int nodeCount = CountNodes(bvh); Debug.WriteLine($"Node count in percentage of primitives: {(float)nodeCount / primitiveCount}"); Assert.IsTrue(nodeCount <= primitiveCount * 2); }
public static IPrimitive CreateTraceData(this FaceList faceList, List <Vector3Float> vertexList, int maxRecursion = int.MaxValue) { var allPolys = new List <IPrimitive>(); foreach (var face in faceList) { allPolys.Add(new TriangleShape(vertexList[face.v0], vertexList[face.v1], vertexList[face.v2], null)); } return(BoundingVolumeHierarchy.CreateNewHierachy(allPolys, maxRecursion)); }
private bool FindHitObject3DControl(Ray ray, out IObject3DControl hitObject3DControl, out IntersectInfo info) { var object3DControls = this.Object3DControls; hitObject3DControl = null; if (!object3DControls.Any()) { info = null; return(false); } var traceables = new List <ITraceable>(); foreach (var object3DControl in object3DControls) { ITraceable traceable = object3DControl.GetTraceable(); if (traceable != null) { traceables.Add(traceable); } } if (traceables.Count <= 0) { info = null; return(false); } var bvhHierachy = BoundingVolumeHierarchy.CreateNewHierachy(traceables); info = bvhHierachy.GetClosestIntersection(ray); if (info != null) { // we hit some part of the collection of controls, figure out which one foreach (var object3DControlBase in object3DControls) { var insideBounds = new List <IBvhItem>(); var traceable = object3DControlBase.GetTraceable(); if (traceable != null) { traceable.GetContained(insideBounds, info.ClosestHitObject.GetAxisAlignedBoundingBox()); if (insideBounds.Contains(info.ClosestHitObject)) { // we hit the control that has the hit point within its bounds hitObject3DControl = object3DControlBase; return(true); } } } } return(false); }
/// <summary> /// Create a bounding volume hierarchy for the given mesh. /// </summary> /// <param name="mesh">The mesh to add the BVH to.</param> /// <returns>The created BVH tree.</returns> public static ITraceable CreateBVHData(this Mesh mesh, BvhCreationOptions bvhCreationOptions = BvhCreationOptions.LegacySlowConstructionFastTracing) { // test new BvHBuilderAac // BvhBuilderAac.Create(mesh); var allPolys = new List <ITraceable>(); mesh.AddTraceables(null, Matrix4X4.Identity, allPolys); return(BoundingVolumeHierarchy.CreateNewHierachy(allPolys, bvhCreationOptions)); }
private bool FindInteractionVolumeHit(Ray ray, out InteractionVolume hitIAVolume, out IntersectInfo info) { var iaVolumes = this.InteractionVolumes; hitIAVolume = null; if (!iaVolumes.Any()) { info = null; return(false); } // TODO: Rewrite as projection without extra list // - Looks like the extra list is always required as CreateNewHierachy requires a List and we can only produce an IEnumerable without the list overhead // - var uiTraceables = iaVolumes.Where(ia => ia.CollisionVolume != null).Select(ia => new Transform(ia.CollisionVolume, ia.TotalTransform)).ToList<IPrimitive>(); var uiTraceables = new List <IPrimitive>(); foreach (var interactionVolume in iaVolumes.OfType <InteractionVolume>()) { if (interactionVolume.CollisionVolume != null) { IPrimitive traceData = interactionVolume.CollisionVolume; uiTraceables.Add(new Transform(traceData, interactionVolume.TotalTransform)); } } if (uiTraceables.Count <= 0) { info = null; return(false); } IPrimitive allUiObjects = BoundingVolumeHierarchy.CreateNewHierachy(uiTraceables); info = allUiObjects.GetClosestIntersection(ray); if (info != null) { foreach (var iaVolume in iaVolumes.OfType <InteractionVolume>()) { var insideBounds = new List <IBvhItem>(); if (iaVolume.CollisionVolume != null) { iaVolume.CollisionVolume.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox()); if (insideBounds.Contains(info.closestHitObject)) { hitIAVolume = iaVolume; return(true); } } } } return(false); }
public static IPrimitive Convert(List <PolygonMesh.MeshGroup> meshGroups, MaterialAbstract partMaterial = null) { List <IPrimitive> renderCollection = new List <IPrimitive>(); foreach (MeshGroup meshGroup in meshGroups) { renderCollection.Add(Convert(meshGroup, partMaterial)); } return(BoundingVolumeHierarchy.CreateNewHierachy(renderCollection)); }
public IRayTraceable GetIRayTraceableRecursive(Union objectToProcess) { List <IRayTraceable> items = new List <IRayTraceable>(); foreach (CsgObject copiedObject in objectToProcess.AllObjects) { items.Add(GetIRayTraceableRecursive((dynamic)copiedObject)); } return(BoundingVolumeHierarchy.CreateNewHierachy(items)); }
public static ITraceable CreateTraceData(FaceList faceList, List <Vector3Float> vertexList, BvhCreationOptions bvhCreationOptions = BvhCreationOptions.FavorFastTracing) { var allPolys = new List <ITraceable>(); foreach (var face in faceList) { allPolys.Add(new TriangleShape(vertexList[face.v0], vertexList[face.v1], vertexList[face.v2], null)); } return(BoundingVolumeHierarchy.CreateNewHierachy(allPolys, bvhCreationOptions)); }
public void Execute(int index) { Assert.IsTrue(BranchNodeOffsets[index] >= 0); var bvh = new BoundingVolumeHierarchy(Nodes, NodeFilters); int lastNode = bvh.BuildBranch(Points, Aabbs, Ranges[index], BranchNodeOffsets[index]); if (NodeFilters != null) { bvh.BuildCombinedCollisionFilter(BodyFilters, BranchNodeOffsets[index], lastNode); bvh.BuildCombinedCollisionFilter(Ranges[index].Root); } }
public void Construct() { Objects.Clear(); Objects.AddRange(_intersectables); if (_constructBvh) { BVH = new BoundingVolumeHierarchy(_boundables); Objects.Add(BVH); } else { Objects.AddRange(_boundables); } }
public void Execute() { if (ShouldDoWork[0] == 0) { // If we need to to skip tree building tasks, than set BranchCount to zero so // that BuildBranchesJob also gets early out in runtime. BranchCount[0] = 0; return; } var bvh = new BoundingVolumeHierarchy(Nodes, NodeFilters); bvh.BuildFirstNLevels(Points, Ranges, BranchNodeOffsets, ThreadCount, out int branchCount); BranchCount[0] = branchCount; }
private void AddCubeOfShperes() { List <IRayTraceable> scanData1 = new List <IRayTraceable>(); Random rand = new Random(0); double dist = 2; for (int i = 0; i < 4000; i++) { BaseShape littleShpere = new SphereShape(new Vector3(rand.NextDouble() * dist - dist / 2, rand.NextDouble() * dist - dist / 2, rand.NextDouble() * dist - dist / 2), rand.NextDouble() * .1 + .01, new SolidMaterial(new RGBA_Floats(rand.NextDouble() * .5 + .5, rand.NextDouble() * .5 + .5, rand.NextDouble() * .5 + .5), 0, 0.0, 2.0)); scanData1.Add(littleShpere); } renderCollection.Add(BoundingVolumeHierarchy.CreateNewHierachy(scanData1)); }
private bool FindMeshGroupHitPosition(Vector2 screenPosition, out int meshHitIndex) { meshHitIndex = 0; if (MeshGroupExtraData.Count == 0 || MeshGroupExtraData[0].meshTraceableData == null) { return(false); } List <IPrimitive> mesheTraceables = new List <IPrimitive>(); for (int i = 0; i < MeshGroupExtraData.Count; i++) { foreach (IPrimitive traceData in MeshGroupExtraData[i].meshTraceableData) { mesheTraceables.Add(new Transform(traceData, MeshGroupTransforms[i].TotalTransform)); } } IPrimitive allObjects = BoundingVolumeHierarchy.CreateNewHierachy(mesheTraceables); Vector2 meshViewerWidgetScreenPosition = meshViewerWidget.TransformFromParentSpace(this, screenPosition); Ray ray = meshViewerWidget.TrackballTumbleWidget.GetRayFromScreen(meshViewerWidgetScreenPosition); IntersectInfo info = allObjects.GetClosestIntersection(ray); if (info != null) { meshSelectInfo.planeDownHitPos = info.hitPosition; meshSelectInfo.lastMoveDelta = new Vector3(); for (int i = 0; i < MeshGroupExtraData.Count; i++) { List <IPrimitive> insideBounds = new List <IPrimitive>(); foreach (IPrimitive traceData in MeshGroupExtraData[i].meshTraceableData) { traceData.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox()); } if (insideBounds.Contains(info.closestHitObject)) { meshHitIndex = i; return(true); } } } return(false); }
public static IPrimitive CreateTraceData(this Mesh mesh, int maxRecursion = int.MaxValue) { List <IPrimitive> allPolys = new List <IPrimitive>(); List <Vector3> positions = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); foreach (Face face in mesh.Faces) { positions.Clear(); bool hasTexture = false; foreach (FaceEdge faceEdge in face.FaceEdges()) { if (mesh.TextureUV.ContainsKey((faceEdge, 0))) { uvs.Add(faceEdge.GetUv(0)); hasTexture = true; } positions.Add(faceEdge.FirstVertex.Position); } // We should use the tessellator for this if it is greater than 3. Vector3 next = positions[1]; Vector2 nextuv = hasTexture ? uvs[1] : Vector2.Zero; for (int positionIndex = 2; positionIndex < positions.Count; positionIndex++) { TriangleShape triangel; if (hasTexture) { triangel = new TriangleShapeUv(positions[0], next, positions[positionIndex], uvs[0], nextuv, uvs[positionIndex], null); } else { triangel = new TriangleShape(positions[0], next, positions[positionIndex], null); } allPolys.Add(triangel); next = positions[positionIndex]; } } return(BoundingVolumeHierarchy.CreateNewHierachy(allPolys, maxRecursion)); }
public void Execute(int index) { // This is need since we schedule the job before we know the exact number of // branches we need to build. if (index >= BranchCount[0]) { return; } Assert.IsTrue(BranchNodeOffsets[index] >= 0); var bvh = new BoundingVolumeHierarchy(Nodes, NodeFilters); int lastNode = bvh.BuildBranch(Points, Aabbs, Ranges[index], BranchNodeOffsets[index]); if (NodeFilters != null) { bvh.BuildCombinedCollisionFilter(BodyFilters, BranchNodeOffsets[index], lastNode); bvh.BuildCombinedCollisionFilter(Ranges[index].Root); } }
public void Execute() { int minBranchNodeIndex = BranchNodeOffsets[0] - 1; int branchCount = BranchCount[0]; for (int i = 1; i < BranchCount[0]; i++) { minBranchNodeIndex = math.min(BranchNodeOffsets[i] - 1, minBranchNodeIndex); } var bvh = new BoundingVolumeHierarchy(Nodes, NodeFilters); bvh.Refit(Aabbs, 1, minBranchNodeIndex); if (NodeFilters != null) { bvh.BuildCombinedCollisionFilter(LeafFilters, 1, minBranchNodeIndex); } }
private bool FindInteractionVolumeHit(Ray ray, out int interactionVolumeHitIndex, out IntersectInfo info) { interactionVolumeHitIndex = -1; if (interactionVolumes.Count == 0 || interactionVolumes[0].CollisionVolume == null) { info = null; return(false); } // TODO: Rewrite as projection without extra list List <IPrimitive> uiTraceables = new List <IPrimitive>(); foreach (InteractionVolume interactionVolume in interactionVolumes) { if (interactionVolume.CollisionVolume != null) { IPrimitive traceData = interactionVolume.CollisionVolume; uiTraceables.Add(new Transform(traceData, interactionVolume.TotalTransform)); } } IPrimitive allUiObjects = BoundingVolumeHierarchy.CreateNewHierachy(uiTraceables); info = allUiObjects.GetClosestIntersection(ray); if (info != null) { for (int i = 0; i < interactionVolumes.Count; i++) { List <IBvhItem> insideBounds = new List <IBvhItem>(); if (interactionVolumes[i].CollisionVolume != null) { interactionVolumes[i].CollisionVolume.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox()); if (insideBounds.Contains(info.closestHitObject)) { interactionVolumeHitIndex = i; return(true); } } } } return(false); }