bool Torus::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { int i, max_i, Found; DBL Depth[4]; Vector3d IPoint; Found = false; if ((max_i = Intersect(ray, Depth, Thread)) > 0) { for (i = 0; i < max_i; i++) { if ((Depth[i] > DEPTH_TOLERANCE) && (Depth[i] < MAX_DISTANCE)) { IPoint = ray.Evaluate(Depth[i]); if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth[i], IPoint, this)); Found = true; } } } } return(Found); }
bool Plane::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { DBL Depth; Vector3d IPoint; if (Intersect(ray, &Depth, Thread)) { IPoint = ray.Evaluate(Depth); if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth,IPoint,this)); return(true); } } return(false); }
bool Triangle::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { DBL Depth; Vector3d IPoint; Thread->Stats()[Ray_Triangle_Tests]++; if (Intersect(ray, &Depth)) { Thread->Stats()[Ray_Triangle_Tests_Succeeded]++; IPoint = ray.Evaluate(Depth); if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth,IPoint,this)); return(true); } } return(false); }
bool SpindleTorus::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { int i, max_i, Found; DBL Depth[4]; Vector3d IPoint; Found = false; if ((max_i = Intersect(ray, Depth, Thread)) > 0) { for (i = 0; i < max_i; i++) { if ((Depth[i] > DEPTH_TOLERANCE) && (Depth[i] < MAX_DISTANCE)) { IPoint = ray.Evaluate(Depth[i]); if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { // To test whether the point is on the spindle, // we test whether it is inside a sphere around the origin going through the spindle's tips. Vector3d P; MInvTransPoint(P, IPoint, Trans); bool onSpindle = (P.lengthSqr() < mSpindleTipYSqr); bool validIntersection = (onSpindle ? (mSpindleMode & SpindleVisible) : (mSpindleMode & NonSpindleVisible)); if (validIntersection) { Depth_Stack->push(Intersection(Depth[i], IPoint, this, P, onSpindle)); Found = true; } } } } } return(Found); }
bool Disc::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { int Intersection_Found; DBL Depth; Vector3d IPoint; Intersection_Found = false; Thread->Stats()[Ray_Disc_Tests]++; if (Intersect(ray, &Depth)) { Thread->Stats()[Ray_Disc_Tests_Succeeded]++; IPoint = ray.Evaluate(Depth); if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth,IPoint,this)); Intersection_Found = true; } } return (Intersection_Found); }
bool Cone::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { int Intersection_Found, cnt, i; Vector3d IPoint; CONE_INT I[4]; Intersection_Found = false; if ((cnt = Intersect(ray, I, Thread)) != 0) { for (i = 0; i < cnt; i++) { IPoint = ray.Evaluate(I[i].d); if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(I[i].d,IPoint,this,I[i].t)); Intersection_Found = true; } } } return (Intersection_Found); }
bool IsoSurface::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { int Side1 = 0, Side2 = 0, itrace = 0; DBL Depth1 = 0.0, Depth2 = 0.0; BasicRay New_Ray; Vector3d IPoint; Vector3d Plocal, Dlocal; DBL tmax = 0.0, tmin = 0.0, tmp = 0.0; DBL maxg = max_gradient; int i = 0 ; /* count of intervals in stack - 1 */ int IFound = false; int begin = 0, end = 0; bool in_shadow_test = false; Vector3d VTmp; Thread->Stats()[Ray_IsoSurface_Bound_Tests]++; if(container->Intersect(ray, Trans, Depth1, Depth2, Side1, Side2)) /* IsoSurface_Bound_Tests */ { Thread->Stats()[Ray_IsoSurface_Bound_Tests_Succeeded]++; in_shadow_test = ray.IsShadowTestRay(); if(Depth1 < 0.0) Depth1 = 0.0; if(Trans != NULL) { MInvTransPoint(Plocal, ray.Origin, Trans); MInvTransDirection(Dlocal, ray.Direction, Trans); } else { Plocal = ray.Origin; Dlocal = ray.Direction; } Thread->isosurfaceData->Inv3 = 1; if(closed != false) { VTmp = Plocal + Depth1 * Dlocal; tmp = Vector_Function(Thread->functionContext, VTmp); if(Depth1 > accuracy) { if(tmp < 0.0) /* The ray hits the bounding shape */ { IPoint = ray.Evaluate(Depth1); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth1, IPoint, this, 1, Side1)); IFound = true; itrace++; Thread->isosurfaceData->Inv3 *= -1; } } } else { if(tmp < (maxg * accuracy * 4.0)) { Depth1 = accuracy * 5.0; VTmp = Plocal + Depth1 * Dlocal; if(Vector_Function(Thread->functionContext, VTmp) < 0) Thread->isosurfaceData->Inv3 = -1; /* Change the sign of the function (IPoint is in the bounding shpae.)*/ } VTmp = Plocal + Depth2 * Dlocal; if(Vector_Function(Thread->functionContext, VTmp) < 0.0) { IPoint = ray.Evaluate(Depth2); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth2, IPoint, this, 1, Side2)); IFound = true; } } } } /* METHOD 2 by R. Suzuki */ tmax = Depth2 = min(Depth2, BOUND_HUGE); tmin = Depth1 = min(Depth2, Depth1); if((tmax - tmin) < accuracy) { if (IFound) Depth_Stack->pop(); // we added an intersection already, so we need to undo that return (false); } Thread->Stats()[Ray_IsoSurface_Tests]++; if((Depth1 < accuracy) && (Thread->isosurfaceData->Inv3 == 1)) { /* IPoint is on the isosurface */ VTmp = Plocal + tmin * Dlocal; if(fabs(Vector_Function(Thread->functionContext, VTmp)) < (maxg * accuracy * 4.0)) { tmin = accuracy * 5.0; VTmp = Plocal + tmin * Dlocal; if(Vector_Function(Thread->functionContext, VTmp) < 0) Thread->isosurfaceData->Inv3 = -1; /* change the sign and go into the isosurface */ } } Thread->isosurfaceData->ctx = Thread->functionContext; for (; itrace < max_trace; itrace++) { if(Function_Find_Root(*(Thread->isosurfaceData), Plocal, Dlocal, &tmin, &tmax, maxg, in_shadow_test, Thread) == false) break; else { IPoint = ray.Evaluate(tmin); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(tmin, IPoint, this, 0, 0 /*Side1*/)); IFound = true; } } tmin += accuracy * 5.0; if((tmax - tmin) < accuracy) break; Thread->isosurfaceData->Inv3 *= -1; } if(IFound) Thread->Stats()[Ray_IsoSurface_Tests_Succeeded]++; } if(eval == true) { DBL temp_max_gradient = max_gradient; // TODO FIXME - works around nasty gcc (found using 4.0.1) bug failing to honor casting away of volatile on pass by value on template argument lookup [trf] max_gradient = max((DBL)temp_max_gradient, maxg); // TODO FIXME - This is not thread-safe but should be!!! [trf] } return (IFound); }
bool Sphere::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { Thread->Stats()[Ray_Sphere_Tests]++; if(Do_Ellipsoid) { register int Intersection_Found; DBL Depth1, Depth2, len; Vector3d IPoint; BasicRay New_Ray; // Transform the ray into the ellipsoid's space MInvTransRay(New_Ray, ray, Trans); len = New_Ray.Direction.length(); New_Ray.Direction /= len; Intersection_Found = false; if(Intersect(New_Ray, Center, Sqr(Radius), &Depth1, &Depth2)) { Thread->Stats()[Ray_Sphere_Tests_Succeeded]++; if((Depth1 > DEPTH_TOLERANCE) && (Depth1 < MAX_DISTANCE)) { IPoint = New_Ray.Evaluate(Depth1); MTransPoint(IPoint, IPoint, Trans); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth1 / len, IPoint, this)); Intersection_Found = true; } } if((Depth2 > DEPTH_TOLERANCE) && (Depth2 < MAX_DISTANCE)) { IPoint = New_Ray.Evaluate(Depth2); MTransPoint(IPoint, IPoint, Trans); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth2 / len, IPoint, this)); Intersection_Found = true; } } } return(Intersection_Found); } else { register int Intersection_Found; DBL Depth1, Depth2; Vector3d IPoint; Intersection_Found = false; if(Intersect(ray, Center, Sqr(Radius), &Depth1, &Depth2)) { Thread->Stats()[Ray_Sphere_Tests_Succeeded]++; if((Depth1 > DEPTH_TOLERANCE) && (Depth1 < MAX_DISTANCE)) { IPoint = ray.Evaluate(Depth1); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth1, IPoint, this)); Intersection_Found = true; } } if((Depth2 > DEPTH_TOLERANCE) && (Depth2 < MAX_DISTANCE)) { IPoint = ray.Evaluate(Depth2); if(Clip.empty() || Point_In_Clip(IPoint, Clip, Thread)) { Depth_Stack->push(Intersection(Depth2, IPoint, this)); Intersection_Found = true; } } } return(Intersection_Found); } }