public bool ObjectsIntersectRay( int[] objectIndexArray, int firstIndex, int indexCount, FastRay3d ray, Func <IIntersectableObjectSet, int, bool> objectFilter, Func <IIntersectableObjectSet, int, int, RayHit3d, bool> hitFilter, double tmin, double tmax, ref ObjectRayHit hit) { return(false); }
public bool ObjectsIntersectRay( int[] objectIndexArray, int firstIndex, int indexCount, FastRay3d fastRay, Func <IIntersectableObjectSet, int, bool> objectFilter, Func <IIntersectableObjectSet, int, int, RayHit3d, bool> hitFilter, double tmin, double tmax, ref ObjectRayHit hit ) { int kdTreeIndex = -1; for (int i = firstIndex, e = firstIndex + indexCount; i < e; i++) { var index = objectIndexArray[i]; var placeHolder = KdTreePlaceholders[index]; //if bounding box is hit, stream Kd-intersection tree double t; // this t is not needed, only for the bb intersection call! if (placeHolder.BoundingBox.Intersects(fastRay.Ray, out t)) { var kdTree = LookupCache(placeHolder); if (kdTree.ObjectSet == null) { kdTree.ObjectSet = ObjectSetBuilder.GetTriangleSetFromPath(placeHolder); } if (kdTree.Intersect(fastRay, objectFilter, hitFilter, tmin, tmax, ref hit)) { kdTreeIndex = index; } //} //catch (NullReferenceException) //{ // if (kdTree.ObjectSet == null) // { // kdTree.ObjectSet = ObjectSetBuilder.GetTriangleSetFromPath(placeHolder); // if (kdTree.Intersect(fastRay, objectFilter, hitFilter, tmin, tmax, ref hit)) // kdTreeIndex = index; // } //} } } if (kdTreeIndex < 0) { return(false); } if (hit.ObjectStack == null) { hit.ObjectStack = new List <SetObject>(); } hit.ObjectStack.Add(new SetObject(this, kdTreeIndex)); return(true); }
public bool ObjectsIntersectRay( int[] objectIndexArray, int firstIndex, int indexCount, FastRay3d fastRay, Func <IIntersectableObjectSet, int, bool> objectFilter, Func <IIntersectableObjectSet, int, int, RayHit3d, bool> hitFilter, double tmin, double tmax, ref ObjectRayHit hit) { bool result = false; if (objectFilter == null) { for (int i = firstIndex, e = firstIndex + indexCount; i < e; i++) { var index = objectIndexArray[i]; if (fastRay.Ray.Hits(Lines[index], tmin, tmax, ref hit.RayHit)) { // Report.Line("hit shell of cylinder " + index + " at " + hit.RayHit.Point); if (hitFilter == null) { result = hit.Set(this, index); break; } if (!hitFilter(this, index, 0, hit.RayHit)) { result = hit.Set(this, index); break; } else { //continue shooting //Report.Line("Filtered"); hit.RayHit.T = tmax; } } } } else { foreach (int index in objectIndexArray) { if (objectFilter(this, index)) { if (fastRay.Ray.Hits(Lines[index], tmin, tmax, ref hit.RayHit) && (hitFilter == null || !hitFilter(this, index, 0, hit.RayHit))) { result = hit.Set(this, index); } } } } return(result); }
public bool ObjectsIntersectRay( int[] objectIndexArray, int firstIndex, int indexCount, FastRay3d fastRay, Func <IIntersectableObjectSet, int, bool> objectFilter, Func <IIntersectableObjectSet, int, int, RayHit3d, bool> hitFilter, double tmin, double tmax, ref ObjectRayHit hit ) { var plist = Position3dList; bool result = false; if (objectFilter == null) { for (int i = firstIndex, e = firstIndex + indexCount; i < e; i++) { var index = objectIndexArray[i]; int pi = index * 3; var rawHit = hit.RayHit; if (fastRay.Ray.HitsTriangle( plist[pi], plist[pi + 1], plist[pi + 2], tmin, tmax, ref rawHit) && (hitFilter == null || !hitFilter(this, index, 0, rawHit))) { hit.RayHit = rawHit; result = hit.Set(this, index); } } } else { for (int i = firstIndex, e = firstIndex + indexCount; i < e; i++) { var index = objectIndexArray[i]; if (objectFilter(this, index)) { int pi = index * 3; var rawHit = hit.RayHit; if (fastRay.Ray.HitsTriangle( plist[pi], plist[pi + 1], plist[pi + 2], tmin, tmax, ref rawHit) && (hitFilter == null || !hitFilter(this, index, 0, rawHit))) { hit.RayHit = rawHit; result = hit.Set(this, index); } } } } return(result); }
public bool ObjectsIntersectRay( int[] objectIndexArray, int firstIndex, int indexCount, FastRay3d fastRay, Func <IIntersectableObjectSet, int, bool> objectFilter, Func <IIntersectableObjectSet, int, int, RayHit3d, bool> hitFilter, double tmin, double tmax, ref ObjectRayHit hit) { bool result = false; if (objectFilter == null) { for (int i = firstIndex, e = firstIndex + indexCount; i < e; i++) { var index = objectIndexArray[i]; var rawHit = hit.RayHit; if (fastRay.Ray.Hits(Sphere3ds[index], tmin, tmax, ref rawHit) && (hitFilter == null || !hitFilter(this, index, 0, rawHit))) { hit.RayHit = rawHit; result = hit.Set(this, index); } } } else { for (int i = firstIndex, e = firstIndex + indexCount; i < e; i++) { var index = objectIndexArray[i]; if (objectFilter(this, index)) { var rawHit = hit.RayHit; if (fastRay.Ray.Hits(Sphere3ds[index], tmin, tmax, ref rawHit) && (hitFilter == null || !hitFilter(this, index, 0, rawHit))) { hit.RayHit = rawHit; result = hit.Set(this, index); } } } } return(result); }
/// <summary> /// The intersection of a polygon with a ray is performed using the /// intersection with the constituting triangles of the polygon. This /// only works for convex polygons, and the part number in the hit is /// used to store the number of the triangle within the polygon. /// </summary> public bool ObjectsIntersectRay(int[] objectIndexArray, int firstIndex, int indexCount, FastRay3d fastRay, Func <IIntersectableObjectSet, int, bool> ios_index_objectFilter, Func <IIntersectableObjectSet, int, int, RayHit3d, bool> hitFilter, double tmin, double tmax, ref ObjectRayHit hit) { bool result = false; int[] fia = FirstIndexArray, via = VertexIndexArray; var pa = PositionArray; for (int i = firstIndex, e = firstIndex + indexCount; i < e; i++) { var oi = objectIndexArray[i]; if (ios_index_objectFilter != null && !ios_index_objectFilter(this, oi)) { continue; } int fvi = fia[oi], fve = fia[oi + 1]; V3d p0 = pa[via[fvi++]], e0 = pa[via[fvi++]] - p0; int fvi0 = fvi; while (fvi < fve) { var e1 = pa[via[fvi]] - p0; var rawHit = hit.RayHit; if (fastRay.Ray.HitsTrianglePointAndEdges( p0, e0, e1, tmin, tmax, ref rawHit)) { int part = fvi - fvi0; if (hitFilter == null || !hitFilter(this, oi, part, rawHit)) { hit.RayHit = rawHit; result = hit.Set(this, oi, part); break; } } ++fvi; e0 = e1; } } return(result); }
public bool ObjectsIntersectRay(int[] objectIndexArray, int firstIndex, int indexCount, FastRay3d fastRay, Func <IIntersectableObjectSet, int, bool> objectFilter, Func <IIntersectableObjectSet, int, int, RayHit3d, bool> hitFilter, double tmin, double tmax, ref ObjectRayHit hit) { int kdTreeIndex = -1; for (int i = firstIndex, e = firstIndex + indexCount; i < e; i++) { var index = objectIndexArray[i]; if (objectFilter != null && !objectFilter(this, index)) { continue; } var x = ConcreteKdTreeList[index]; var trafo = x.Trafo; var transformedRay = new FastRay3d( trafo.Backward.TransformPos(fastRay.Ray.Origin), trafo.Backward.TransformDir(fastRay.Ray.Direction)); if (x.KdIntersectionTree.Intersect(transformedRay, objectFilter, hitFilter, tmin, tmax, ref hit)) { kdTreeIndex = index; hit.RayHit.Point = trafo.Forward.TransformPos(hit.RayHit.Point); } } if (kdTreeIndex < 0) { return(false); } if (hit.ObjectStack == null) { hit.ObjectStack = new List <SetObject>(); } hit.ObjectStack.Add(new SetObject(this, kdTreeIndex)); return(true); }
public bool ObjectsIntersectRay(int[] objectIndexArray, int firstIndex, int indexCount, FastRay3d ray, Func <IIntersectableObjectSet, int, bool> ios_index_objectFilter, Func <IIntersectableObjectSet, int, int, RayHit3d, bool> ios_index_part_hit_hitFilter, double tmin, double tmax, ref ObjectRayHit hit) { var found = false; var index = -1; tmax = Fun.Min(tmax, hit.RayHit.T); for (int i = 0; i < indexCount; i++) { var id = objectIndexArray[firstIndex + i]; if (ios_index_objectFilter == null || ios_index_objectFilter(this, id)) { GetTriangle(id, out V3d p0, out V3d p1, out V3d p2); if (ray.Ray.IntersectsTriangle(p0, p1, p2, tmin, tmax, out double t)) { tmax = t; found = true; index = id; } } } if (found) { hit = new ObjectRayHit() { SetObject = new SetObject(this, index), ObjectStack = new List <SetObject>(), // TODO RayHit = new RayHit3d() { Part = 0, Point = ray.Ray.GetPointOnRay(tmax), T = tmax, Coord = V2d.Zero, // TODO BackSide = false // TODO } }; return(true); } else { return(false); } }