Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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);
}
Пример #8
0
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);
    }
}