コード例 #1
0
ファイル: triangle.cpp プロジェクト: carolemieux/daikon
static void Transform_Smooth_Triangle(OBJECT *Object, TRANSFORM *Trans)
{
  SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;

  if (!Test_Flag(Object, DEGENERATE_FLAG))
  {
/*  BEG ROSE
    This is useless, because Compute_Triange recalculates this anyway:
    MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
    END ROSE */
    MTransPoint(Triangle->P1, Triangle->P1, Trans);
    MTransPoint(Triangle->P2, Triangle->P2, Trans);
    MTransPoint(Triangle->P3, Triangle->P3, Trans);
/*  BEG ROSE
    This code is definitely wrong:
    MTransPoint(Triangle->N1, Triangle->N1, Trans);
    MTransPoint(Triangle->N2, Triangle->N2, Trans);
    MTransPoint(Triangle->N3, Triangle->N3, Trans);
    Bug fix for this: */
    MTransNormal(Triangle->N1,Triangle->N1,Trans);
    MTransNormal(Triangle->N2,Triangle->N2,Trans);
    MTransNormal(Triangle->N3,Triangle->N3,Trans);
/*  END ROSE */

    Compute_Triangle((TRIANGLE *)Triangle, true);
  }
}
コード例 #2
0
ファイル: triangle.cpp プロジェクト: SteveShaw/povray
void SmoothTriangle::Transform(const TRANSFORM *tr)
{
    if(!Test_Flag(this, DEGENERATE_FLAG))
    {
        MTransPoint(P1, P1, tr);
        MTransPoint(P2, P2, tr);
        MTransPoint(P3, P3, tr);
        MTransNormal(N1, N1, tr);
        MTransNormal(N2, N2, tr);
        MTransNormal(N3, N3, tr);

        Compute_Triangle();
    }
}
コード例 #3
0
void UnWarp_Normal (VECTOR TNorm, VECTOR ENorm, TPATTERN *TPat, int DontScaleBumps)
{
	WARP *Warp = NULL;

	if(!DontScaleBumps)
		VNormalize(TNorm,ENorm);
	else
		Assign_Vector(TNorm,ENorm);

	if(TPat->Warps != NULL)
	{
		// go to the last entry
		for(Warp = TPat->Warps; Warp->Next_Warp != NULL; Warp = Warp->Next_Warp) ;

		// walk backwards from the last entry
		for(; Warp != NULL; Warp = Warp->Prev_Warp)
		{
			if(Warp->Warp_Type == TRANSFORM_WARP)
				MTransNormal(TNorm, TNorm, &(((TRANS *)Warp)->Trans));
		}
	}

	if(!DontScaleBumps)
		VNormalizeEq(TNorm);
}
コード例 #4
0
ファイル: torus.cpp プロジェクト: hjw3001/povray
void Torus::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *Thread) const
{
    DBL dist;
    Vector3d P, N, M;

    /* Transform the point into the torus space. */

    MInvTransPoint(P, Inter->IPoint, Trans);

    /* Get normal from derivatives. */

    dist = sqrt(P[X] * P[X] + P[Z] * P[Z]);

    if (dist > EPSILON)
    {
        M[X] = MajorRadius * P[X] / dist;
        M[Y] = 0.0;
        M[Z] = MajorRadius * P[Z] / dist;
    }
    else
    {
        M = Vector3d(0.0, 0.0, 0.0);
    }

    N = P - M;

    /* Transform the normalt out of the torus space. */

    MTransNormal(Result, N, Trans);

    Result.normalize();
}
コード例 #5
0
ファイル: torus.cpp プロジェクト: hjw3001/povray
void SpindleTorus::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *Thread) const
{
    DBL dist;
    Vector3d P, N, M;
    bool spindle = false;

    // The point has already been transformed into the torus space.
    P = Inter->LocalIPoint;

    // Get normal from derivatives.

    dist = sqrt(P[X] * P[X] + P[Z] * P[Z]);

    if (dist > EPSILON)
    {
        M[X] = MajorRadius * P[X] / dist;
        M[Y] = 0.0;
        M[Z] = MajorRadius * P[Z] / dist;
    }
    else
    {
        M = Vector3d(0.0, 0.0, 0.0);
    }

    if (Inter->b1) // Inter->b1 indicates whether the point is on the spindle (true) or not (false)
        N = P + M;
    else
        N = P - M;

    // Transform the normalt out of the torus space.
    MTransNormal(Result, N, Trans);
    Result.normalize();
}
コード例 #6
0
void Parametric_Normal(VECTOR Result, OBJECT* Object, INTERSECTION* Inter)
{
	VECTOR RU, RV;
	PARAMETRIC * Par = (PARAMETRIC *)Object;
	VECTOR * IPoint = &(Inter->IPoint);
	UV_VECT uv_vect;

	uv_vect[U] = Par->last_u;
	uv_vect[V] = Par->last_v;
	RU[X] = RV[X] = -Evaluate_Function_UV(*(Par->Function[X]), uv_vect);
	RU[Y] = RV[Y] = -Evaluate_Function_UV(*(Par->Function[Y]), uv_vect);
	RU[Z] = RV[Z] = -Evaluate_Function_UV(*(Par->Function[Z]), uv_vect);

	uv_vect[U] += Par->accuracy;
	RU[X] += Evaluate_Function_UV(*(Par->Function[X]), uv_vect);
	RU[Y] += Evaluate_Function_UV(*(Par->Function[Y]), uv_vect);
	RU[Z] += Evaluate_Function_UV(*(Par->Function[Z]), uv_vect);

	uv_vect[U] = Par->last_u;
	uv_vect[V] += Par->accuracy;
	RV[X] += Evaluate_Function_UV(*(Par->Function[X]), uv_vect);
	RV[Y] += Evaluate_Function_UV(*(Par->Function[Y]), uv_vect);
	RV[Z] += Evaluate_Function_UV(*(Par->Function[Z]), uv_vect);

	VCross(Result, RU, RV);
	if (Par->Trans != NULL)
		MTransNormal(Result, Result, Par->Trans);
	VNormalize(Result, Result);
}
コード例 #7
0
ファイル: object.cpp プロジェクト: atlaste/povray
void ContainedByBox::Normal(const Vector3d& point, const TRANSFORM* pTrans, int side, Vector3d& rNormal) const
{
    switch (side)
    {
        case Box::kSideHit_X0:
            rNormal = Vector3d(-1.0, 0.0, 0.0);
            break;
        case Box::kSideHit_X1:
            rNormal = Vector3d( 1.0, 0.0, 0.0);
            break;
        case Box::kSideHit_Y0:
            rNormal = Vector3d( 0.0,-1.0, 0.0);
            break;
        case Box::kSideHit_Y1:
            rNormal = Vector3d( 0.0, 1.0, 0.0);
            break;
        case Box::kSideHit_Z0:
            rNormal = Vector3d( 0.0, 0.0,-1.0);
            break;
        case Box::kSideHit_Z1:
            rNormal = Vector3d( 0.0, 0.0, 1.0);
            break;
        default:
            POV_SHAPE_ASSERT(false);
    }

    /* Transform the normal into the world space. */
    if(pTrans != NULL)
    {
        MTransNormal(rNormal, rNormal, pTrans);

        rNormal.normalize();
    }
}
コード例 #8
0
ファイル: torus.cpp プロジェクト: Degot/povray
void Torus::Normal(VECTOR Result, Intersection *Inter, TraceThreadData *Thread) const
{
	DBL dist;
	VECTOR P, N, M;

	/* Transform the point into the torus space. */

	MInvTransPoint(P, Inter->IPoint, Trans);

	/* Get normal from derivatives. */

	dist = sqrt(P[X] * P[X] + P[Z] * P[Z]);

	if (dist > EPSILON)
	{
		M[X] = MajorRadius * P[X] / dist;
		M[Y] = 0.0;
		M[Z] = MajorRadius * P[Z] / dist;
	}
	else
	{
		Make_Vector(M, 0.0, 0.0, 0.0);
	}

	VSub(N, P, M);

	/* Transform the normalt out of the torus space. */

	MTransNormal(Result, N, Trans);

	VNormalize(Result, Result);
}
コード例 #9
0
ファイル: fpmetric.cpp プロジェクト: fourks/povray
void Parametric::Normal(VECTOR Result, Intersection *Inter, TraceThreadData *Thread) const
{
	VECTOR RU, RV;
	UV_VECT uv_vect;

	uv_vect[U] = Inter->Iuv[U];
	uv_vect[V] = Inter->Iuv[V];
	RU[X] = RV[X] = -Evaluate_Function_UV(Thread->functionContext, *(Function[X]), uv_vect);
	RU[Y] = RV[Y] = -Evaluate_Function_UV(Thread->functionContext, *(Function[Y]), uv_vect);
	RU[Z] = RV[Z] = -Evaluate_Function_UV(Thread->functionContext, *(Function[Z]), uv_vect);

	uv_vect[U] += accuracy;
	RU[X] += Evaluate_Function_UV(Thread->functionContext, *(Function[X]), uv_vect);
	RU[Y] += Evaluate_Function_UV(Thread->functionContext, *(Function[Y]), uv_vect);
	RU[Z] += Evaluate_Function_UV(Thread->functionContext, *(Function[Z]), uv_vect);

	uv_vect[U] = Inter->Iuv[U];
	uv_vect[V] += accuracy;
	RV[X] += Evaluate_Function_UV(Thread->functionContext, *(Function[X]), uv_vect);
	RV[Y] += Evaluate_Function_UV(Thread->functionContext, *(Function[Y]), uv_vect);
	RV[Z] += Evaluate_Function_UV(Thread->functionContext, *(Function[Z]), uv_vect);

	VCross(Result, RU, RV);
	if (Trans != NULL)
		MTransNormal(Result, Result, Trans);
	VNormalize(Result, Result);
}
コード例 #10
0
ファイル: planes.cpp プロジェクト: Degot/povray
void Plane::Normal(VECTOR Result, Intersection *, TraceThreadData *) const
{
	Assign_Vector(Result, Normal_Vector);

	if(Trans != NULL)
	{
		MTransNormal(Result, Result, Trans);

		VNormalize(Result, Result);
	}
}
コード例 #11
0
ファイル: plane.cpp プロジェクト: dickbalaska/povray
void Plane::Normal(Vector3d& Result, Intersection *, TraceThreadData *) const
{
    Result = Normal_Vector;

    if(Trans != NULL)
    {
        MTransNormal(Result, Result, Trans);

        Result.normalize();
    }
}
コード例 #12
0
static void Plane_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *)
{
  Assign_Vector(Result,((PLANE *)Object)->Normal_Vector);

  if (((PLANE *)Object)->Trans != NULL)
  {
    MTransNormal(Result, Result, ((PLANE *)Object)->Trans);

    VNormalize(Result, Result);
  }
}
コード例 #13
0
ファイル: disc.cpp プロジェクト: wfpokorny/povray
void Disc::Transform(const TRANSFORM *tr)
{
    MTransNormal(normal, normal, tr);

    normal.normalize();

    Compose_Transforms(Trans, tr);

    /* Recalculate the bounds */

    Compute_BBox();
}
コード例 #14
0
static void Transform_Polygon(OBJECT *Object, TRANSFORM *Trans)
{
  VECTOR N;
  POLYGON *Polyg = (POLYGON *)Object;

  Compose_Transforms(Polyg->Trans, Trans);

  Make_Vector(N, 0.0, 0.0, 1.0);
  MTransNormal(Polyg->S_Normal, N, Polyg->Trans);

  VNormalizeEq(Polyg->S_Normal);

  Compute_Polygon_BBox(Polyg);
}
コード例 #15
0
static void Transform_Disc (OBJECT *Object, TRANSFORM *Trans)
{
  DISC *Disc = (DISC *)Object;

  MTransNormal(((DISC *)Object)->normal, ((DISC *)Object)->normal, Trans);

  VNormalize(((DISC *)Object)->normal, ((DISC *)Object)->normal);

  Compose_Transforms(Disc->Trans, Trans);

  /* Recalculate the bounds */

  Compute_Disc_BBox(Disc);
}
コード例 #16
0
ファイル: polygon.cpp プロジェクト: hjw3001/povray
void Polygon::Transform(const TRANSFORM *tr)
{
    Vector3d N;

    if(Trans == NULL)
        Trans = Create_Transform();

    Compose_Transforms(Trans, tr);

    N = Vector3d(0.0, 0.0, 1.0);
    MTransNormal(S_Normal, N, Trans);

    S_Normal.normalize();

    Compute_BBox();
}
コード例 #17
0
ファイル: sphere.cpp プロジェクト: SteveShaw/povray
void Sphere::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *Thread) const
{
    if(Do_Ellipsoid)
    {
        Vector3d New_Point;
        // Transform the point into the sphere's space
        MInvTransPoint(New_Point, Inter->IPoint, Trans);
        Result = New_Point - Center;
        MTransNormal(Result, Result, Trans);
        Result.normalize();
    }
    else
    {
        Result = (Inter->IPoint - Center) / Radius;
    }
}
コード例 #18
0
ファイル: isosurface.cpp プロジェクト: quickfur/povray
void IsoSurface::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *Thread) const
{
    Vector3d New_Point, TPoint;
    DBL funct;
    bool containerHit = Inter->i1;

    if (containerHit)
    {
        container->Normal(Inter->IPoint, Trans, Inter->i2, Result);
    }
    else
    {
        /* Transform the point into the isosurface space */
        if(Trans != NULL)
            MInvTransPoint(New_Point, Inter->IPoint, Trans);
        else
            New_Point = Inter->IPoint;

        TPoint = New_Point;
        funct = Evaluate_Function(Function, Thread->functionContext, TPoint);

        TPoint = New_Point;
        TPoint[X] += accuracy;
        Result[X] = Evaluate_Function(Function, Thread->functionContext, TPoint) - funct;
            TPoint = New_Point;

        TPoint[Y] += accuracy;
        Result[Y] = Evaluate_Function(Function, Thread->functionContext, TPoint) - funct;
            TPoint = New_Point;

        TPoint[Z] += accuracy;
        Result[Z] = Evaluate_Function(Function, Thread->functionContext, TPoint) - funct;

        if((Result[X] == 0) && (Result[Y] == 0) && (Result[Z] == 0))
            Result[X] = 1.0;
        Result.normalize();

        /* Transform the point into the boxes space. */
        if(Trans != NULL)
        {
            MTransNormal(Result, Result, Trans);

            Result.normalize();
        }
    }
}
コード例 #19
0
ファイル: sor.cpp プロジェクト: SteveShaw/povray
void Sor::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *Thread) const
{
    DBL k;
    Vector3d P;
    SOR_SPLINE_ENTRY *Entry;
    Vector3d N;

    switch (Inter->i1)
    {
        case CURVE:

            /* Transform the intersection point into the surface of revolution space. */

            MInvTransPoint(P, Inter->IPoint, Trans);

            Entry = &Spline->Entry[Inter->i2];

            k = 0.5 * (P[Y] * (3.0 * Entry->A * P[Y] + 2.0 * Entry->B) + Entry->C);

            N[X] = P[X];
            N[Y] = -k;
            N[Z] = P[Z];

            break;

        case BASE_PLANE:

            N = Vector3d(0.0, -1.0, 0.0);

            break;


        case CAP_PLANE:

            N = Vector3d(0.0, 1.0, 0.0);

            break;
    }

    /* Transform the normal out of the surface of revolution space. */

    MTransNormal(Result, N, Trans);

    Result.normalize();
}
コード例 #20
0
static void Cone_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
{
  CONE *Cone = (CONE *)Object;

  /* Transform the point into the cones space */

  MInvTransPoint(Result, Inter->IPoint, Cone->Trans);

  /* Calculating the normal is real simple in canonical cone space */

  switch (Inter->i1)
  {
    case SIDE_HIT:

      if (Test_Flag(Cone, CYLINDER_FLAG))
      {
        Result[Z] = 0.0;
      }
      else
      {
        Result[Z] = -Result[Z];
      }

      break;

    case BASE_HIT:

      Make_Vector(Result, 0.0, 0.0, -1.0);

      break;

    case CAP_HIT:

      Make_Vector(Result, 0.0, 0.0, 1.0);

      break;
  }

  /* Transform the point out of the cones space */

  MTransNormal(Result, Result, Cone->Trans);

  VNormalize(Result, Result);
}
コード例 #21
0
ファイル: lathe.cpp プロジェクト: neuroradiology/povray
void Lathe::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *Thread) const
{
    DBL r, dx, dy;
    Vector3d P, N;
    LATHE_SPLINE_ENTRY *Entry;

    Entry = &Spline->Entry[Inter->i1];

    /* Transform the point into the lathe space. */

    MInvTransPoint(P, Inter->IPoint, Trans);

    /* Get distance from rotation axis. */

    r = P[X] * P[X] + P[Z] * P[Z];

    if (r > EPSILON)
    {
        r = sqrt(r);

        /* Get derivatives. */

        dx = Inter->d1 * (3.0 * Entry->A[X] * Inter->d1 + 2.0 * Entry->B[X]) + Entry->C[X];
        dy = Inter->d1 * (3.0 * Entry->A[Y] * Inter->d1 + 2.0 * Entry->B[Y]) + Entry->C[Y];

        /* Get normal by rotation. */

        N[X] =  dy * P[X];
        N[Y] = -dx * r;
        N[Z] =  dy * P[Z];
    }
    else
    {
        N[X] = N[Z] = 0.0;
        N[Y] = 1.0;
    }

    /* Transform the normalt out of the lathe space. */

    MTransNormal(Result, N, Trans);

    Result.normalize();
}
コード例 #22
0
ファイル: cone.cpp プロジェクト: hjw3001/povray
void Cone::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *Thread) const
{
    /* Transform the point into the cones space */

    MInvTransPoint(Result, Inter->IPoint, Trans);

    /* Calculating the normal is real simple in canonical cone space */

    switch (Inter->i1)
    {
        case SIDE_HIT:

            if (Test_Flag(this, CYLINDER_FLAG))
            {
                Result[Z] = 0.0;
            }
            else
            {
                Result[Z] = -Result[Z];
            }

            break;

        case BASE_HIT:

            Result = Vector3d(0.0, 0.0, -1.0);

            break;

        case CAP_HIT:

            Result = Vector3d(0.0, 0.0, 1.0);

            break;
    }

    /* Transform the point out of the cones space */

    MTransNormal(Result, Result, Trans);

    Result.normalize();
}
コード例 #23
0
ファイル: object.cpp プロジェクト: atlaste/povray
void ContainedBySphere::Normal(const Vector3d& point, const TRANSFORM* pTrans, int side, Vector3d& rNormal) const
{
    Vector3d newPoint;

    /* Transform the point into the isosurface space */
    if(pTrans != NULL)
        MInvTransPoint(newPoint, point, pTrans);
    else
        newPoint = point;

    rNormal = (newPoint - center) / radius;

    /* Transform the normal into the world space. */
    if(pTrans != NULL)
    {
        MTransNormal(rNormal, rNormal, pTrans);

        rNormal.normalize();
    }
}
コード例 #24
0
ファイル: lemon.cpp プロジェクト: atlaste/povray
bool Lemon::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread)
{
    bool Intersection_Found;
    int cnt, i;
    Vector3d Real_Normal;
    Vector3d Real_Pt,INormal;
    LEMON_INT I[4];
    Vector3d P,D;
    DBL len;

    Thread->Stats()[Ray_Lemon_Tests]++;
    MInvTransPoint(P, ray.Origin, Trans);
    MInvTransDirection(D, ray.Direction, Trans);
    len = D.length();
    D /= len;

    Intersection_Found = false;

    if ((cnt = Intersect(P, D, I, Thread)) != 0)
    {
        for (i = 0; i < cnt; i++)
        {
            Real_Pt = ray.Origin + I[i].d/len * ray.Direction;

            if (Clip.empty() || Point_In_Clip(Real_Pt, Clip, Thread))
            {
                INormal = I[i].n;
                MTransNormal(Real_Normal, INormal, Trans);
                Real_Normal.normalize();

                Depth_Stack->push(Intersection(I[i].d/len,Real_Pt,Real_Normal,this));
                Intersection_Found = true;
            }
        }
    }
    if(Intersection_Found)
    {
        Thread->Stats()[Ray_Lemon_Tests_Succeeded]++;
    }
    return (Intersection_Found);
}
コード例 #25
0
static void Box_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
{
  switch (Inter->i1)
  {
    case SIDE_X_0: Make_Vector(Result, -1.0,  0.0,  0.0); break;
    case SIDE_X_1: Make_Vector(Result,  1.0,  0.0,  0.0); break;
    case SIDE_Y_0: Make_Vector(Result,  0.0, -1.0,  0.0); break;
    case SIDE_Y_1: Make_Vector(Result,  0.0,  1.0,  0.0); break;
    case SIDE_Z_0: Make_Vector(Result,  0.0,  0.0, -1.0); break;
    case SIDE_Z_1: Make_Vector(Result,  0.0,  0.0,  1.0); break;

    default: Error("Unknown box side in Box_Normal().");
  }

  /* Transform the point into the boxes space. */

  if (((BOX *)Object)->Trans != NULL)
  {
    MTransNormal(Result, Result, ((BOX *)Object)->Trans);

    VNormalize(Result, Result);
  }
}
コード例 #26
0
ファイル: super.cpp プロジェクト: UberPOV/UberPOV
void Superellipsoid::Normal(Vector3d& Result, Intersection *Inter, TraceThreadData *Thread) const
{
    Vector3d const& E = Power;
    Vector3d P;

    /* Transform the point into the superellipsoid space. */
    MInvTransPoint(P, Inter->IPoint, Trans);

    DBL r, z2n = 0;
    if (P[Z] != 0)
    {
        z2n = power(fabs(P[Z]), E[Z]);
        P[Z] = z2n / P[Z];
    }

    if (fabs(P[X]) > fabs(P[Y]))
    {
        r = power(fabs(P[Y] / P[X]), E[X]);

        P[X] = (1-z2n)  /  P[X];
        P[Y] = P[Y] ? (1-z2n) * r / P[Y] : 0;
    }
    else if (P[Y] != 0)
    {
        r = power(fabs(P[X] / P[Y]), E[X]);

        P[X] = P[X] ? (1-z2n) * r / P[X] : 0;
        P[Y] = (1-z2n) / P[Y];
    }
    if(P[Z])
        P[Z] *= (1 + r);

    /* Transform the normalt out of the superellipsoid space. */
    MTransNormal(Result, P, Trans);

    Result.normalize();
}
コード例 #27
0
ファイル: fractal.cpp プロジェクト: hjw3001/povray
bool Fractal::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread)
{
    bool Intersection_Found;
    bool LastIsInside = false;
    bool CurrentIsInside, NextIsInside;
    DBL Depth, Depth_Max;
    DBL Dist, Dist_Next, LenSqr, LenInv;

    Vector3d IPoint, Mid_Point, Next_Point, Real_Pt;
    Vector3d Real_Normal, F_Normal;
    Vector3d Direction;
    BasicRay New_Ray;

    Thread->Stats()[Ray_Fractal_Tests]++;

    Intersection_Found = false;

    /* Get into Fractal's world. */

    if (Trans != NULL)
    {
        MInvTransDirection(Direction, ray.Direction, Trans);
        LenSqr = Direction.lengthSqr();

        if (LenSqr == 0.0)
        {
            return (false);
        }

        if (LenSqr != 1.0)
        {
            LenInv = 1.0 / sqrt(LenSqr);
            Direction *= LenInv;
        }
        else
            LenInv = 1.0;

        New_Ray.Direction = Direction;
        MInvTransPoint(New_Ray.Origin, ray.Origin, Trans);
    }
    else
    {
        Direction = ray.Direction;
        New_Ray = ray;
        LenInv = 1.0;
    }

    /* Bound fractal. */

    if (!F_Bound(New_Ray, this, &Depth, &Depth_Max))
    {
        return (false);
    }

    if (Depth_Max < Fractal_Tolerance)
    {
        return (false);
    }

    if (Depth < Fractal_Tolerance)
    {
        Depth = Fractal_Tolerance;
    }

    /* Jump to starting point */

    Next_Point = New_Ray.Origin + Direction * Depth;

    CurrentIsInside = D_Iteration(Next_Point, this, Direction, &Dist, Thread->Fractal_IStack);

    /* Light ray starting inside ? */

    if (CurrentIsInside)
    {
        Next_Point += (2.0 * Fractal_Tolerance) * Direction;

        Depth += 2.0 * Fractal_Tolerance;

        if (Depth > Depth_Max)
        {
            return (false);
        }

        CurrentIsInside = D_Iteration(Next_Point, this, Direction, &Dist, Thread->Fractal_IStack);
    }

    /* Ok. Trace it */

    while (Depth < Depth_Max)
    {
        /*
         * Get close to the root: Advance with Next_Point, keeping track of last
         * position in IPoint...
         */

        while (1)
        {
            if (Dist < Precision)
                Dist = Precision;

            Depth += Dist;

            if (Depth > Depth_Max)
            {
                if (Intersection_Found)
                    Thread->Stats()[Ray_Fractal_Tests_Succeeded]++;
                return (Intersection_Found);
            }

            IPoint = Next_Point;
            Next_Point += Dist * Direction;

            NextIsInside = D_Iteration(Next_Point, this, Direction, &Dist_Next, Thread->Fractal_IStack);

            if (NextIsInside != CurrentIsInside)
            {
                /* Set surface was crossed... */

                Depth -= Dist;
                break;
            }
            else
            {
                Dist = Dist_Next; /* not reached */
            }
        }

        /* then, polish the root via bisection method... */

        while (Dist > Fractal_Tolerance)
        {
            Dist *= 0.5;
            Mid_Point = IPoint + Dist * Direction;

            LastIsInside = Iteration(Mid_Point, this, Thread->Fractal_IStack);

            if (LastIsInside == CurrentIsInside)
            {
                IPoint = Mid_Point;

                Depth += Dist;

                if (Depth > Depth_Max)
                {
                    if (Intersection_Found)
                        Thread->Stats()[Ray_Fractal_Tests_Succeeded]++;
                    return (Intersection_Found);
                }
            }
        }

        if (!CurrentIsInside) /* Mid_Point isn't inside the set */
        {
            IPoint += Dist * Direction;

            Depth += Dist;

            Iteration(IPoint, this, Thread->Fractal_IStack);
        }
        else
        {
            if (LastIsInside != CurrentIsInside)
            {
                Iteration(IPoint, this, Thread->Fractal_IStack);
            }
        }

        if (Trans != NULL)
        {
            MTransPoint(Real_Pt, IPoint, Trans);
            Normal_Calc(this, F_Normal, Thread->Fractal_IStack);
            MTransNormal(Real_Normal, F_Normal, Trans);
        }
        else
        {
            Real_Pt = IPoint;
            Normal_Calc(this, Real_Normal, Thread->Fractal_IStack);
        }

        if (Clip.empty() || Point_In_Clip(Real_Pt, Clip, Thread))
        {
            Real_Normal.normalize();
            Depth_Stack->push(Intersection(Depth * LenInv, Real_Pt, Real_Normal, this));
            Intersection_Found = true;

            /* If fractal isn't used with CSG we can exit now. */

            if (!(Type & IS_CHILD_OBJECT))
            {
                break;
            }
        }

        /* Start over where work was left */

        IPoint = Next_Point;
        Dist = Dist_Next;
        CurrentIsInside = NextIsInside;

    }

    if (Intersection_Found)
        Thread->Stats()[Ray_Fractal_Tests_Succeeded]++;
    return (Intersection_Found);
}
コード例 #28
0
ファイル: polygon.cpp プロジェクト: hjw3001/povray
void Polygon::Compute_Polygon(int number, Vector3d *points)
{
    int i;
    DBL x, y, z, d;
    Vector3d o, u, v, w, N;
    MATRIX a, b;

    /* Create polygon data. */

    if (Data == NULL)
    {
        Data = reinterpret_cast<POLYGON_DATA *>(POV_MALLOC(sizeof(POLYGON_DATA), "polygon points"));

        Data->References = 1;

        Data->Number = number;

        Data->Points = reinterpret_cast<Vector2d *>(POV_MALLOC(number*sizeof(Vector2d), "polygon points"));
    }
    else
    {
        throw POV_EXCEPTION_STRING("Polygon data already computed.");
    }

    /* Get polygon's coordinate system (one of the many possible) */

    o = points[0];

    /* Find valid, i.e. non-zero u vector. */

    for (i = 1; i < number; i++)
    {
        u = points[i] - o;

        if (u.lengthSqr() > EPSILON)
        {
            break;
        }
    }

    if (i == number)
    {
        Set_Flag(this, DEGENERATE_FLAG);

;// TODO MESSAGE    Warning("Points in polygon are co-linear. Ignoring polygon.");
    }

    /* Find valid, i.e. non-zero v and w vectors. */

    for (i++; i < number; i++)
    {
        v = points[i] - o;

        w = cross(u, v);

        if ((v.lengthSqr() > EPSILON) && (w.lengthSqr() > EPSILON))
        {
            break;
        }
    }

    if (i == number)
    {
        Set_Flag(this, DEGENERATE_FLAG);

;// TODO MESSAGE    Warning("Points in polygon are co-linear. Ignoring polygon.");
    }

    u = cross(v, w);
    v = cross(w, u);

    u.normalize();
    v.normalize();
    w.normalize();

    MIdentity(a);
    MIdentity(b);

    a[3][0] = -o[X];
    a[3][1] = -o[Y];
    a[3][2] = -o[Z];

    b[0][0] =  u[X];
    b[1][0] =  u[Y];
    b[2][0] =  u[Z];

    b[0][1] =  v[X];
    b[1][1] =  v[Y];
    b[2][1] =  v[Z];

    b[0][2] =  w[X];
    b[1][2] =  w[Y];
    b[2][2] =  w[Z];

    MTimesC(Trans->inverse, a, b);

    MInvers(Trans->matrix, Trans->inverse);

    /* Project points onto the u,v-plane (3D --> 2D) */

    for (i = 0; i < number; i++)
    {
        x = points[i][X] - o[X];
        y = points[i][Y] - o[Y];
        z = points[i][Z] - o[Z];

        d = x * w[X] + y * w[Y] + z * w[Z];

        if (fabs(d) > ZERO_TOLERANCE)
        {
            Set_Flag(this, DEGENERATE_FLAG);

;// TODO MESSAGE      Warning("Points in polygon are not co-planar. Ignoring polygons.");
        }

        Data->Points[i][X] = x * u[X] + y * u[Y] + z * u[Z];
        Data->Points[i][Y] = x * v[X] + y * v[Y] + z * v[Z];
    }

    N = Vector3d(0.0, 0.0, 1.0);
    MTransNormal(S_Normal, N, Trans);

    S_Normal.normalize();

    Compute_BBox();
}
コード例 #29
0
ファイル: ovus.cpp プロジェクト: jwmynhier/povray
bool Ovus::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread)
{
    bool Found = false;
    Vector3d Real_Normal, Real_Pt, INormal, IPoint;
    DBL Depth1, Depth2, Depth3, Depth4, Depth5, Depth6;
    DBL len, horizontal;
    Vector3d P,D;

    Thread->Stats()[Ray_Ovus_Tests]++;
    MInvTransPoint(P, ray.Origin, Trans);
    MInvTransDirection(D, ray.Direction, Trans);
    len = D.length();
    D /= len;

    Intersect_Ovus_Spheres(P, D, &Depth1, &Depth2, &Depth3,
                           &Depth4, &Depth5, &Depth6, Thread);
    if (Depth1 > EPSILON)
    {
        IPoint = P + Depth1 * D;
        if (IPoint[Y] < BottomVertical)
        {
            MTransPoint(Real_Pt, IPoint, Trans);
            if (Clip.empty()||(Point_In_Clip(Real_Pt, Clip, Thread)))
            {
                INormal = IPoint / BottomRadius;
                MTransNormal(Real_Normal, INormal, Trans);
                Real_Normal.normalize();
                Depth_Stack->push(Intersection(Depth1/len, Real_Pt, Real_Normal, this));
                Found = true;
            }
        }
    }

    if (Depth2 > EPSILON)
    {
        IPoint = P + Depth2 * D;

        if (IPoint[Y] < BottomVertical)
        {
            MTransPoint(Real_Pt, IPoint, Trans);
            if (Clip.empty()||(Point_In_Clip(Real_Pt, Clip, Thread)))
            {
                INormal = IPoint / BottomRadius;
                MTransNormal(Real_Normal, INormal, Trans);
                Real_Normal.normalize();
                Depth_Stack->push(Intersection(Depth2/len, Real_Pt, Real_Normal, this));
                Found = true;
            }
        }
    }

    if (Depth3 > EPSILON)
    {
        IPoint = P + Depth3 * D;

        if (IPoint[Y] > TopVertical)
        {
            MTransPoint(Real_Pt, IPoint, Trans);
            if (Clip.empty()||(Point_In_Clip(Real_Pt, Clip, Thread)))
            {
                INormal = IPoint;
                INormal[Y] -= BottomRadius;
                INormal /= TopRadius;
                MTransNormal(Real_Normal, INormal, Trans);
                Real_Normal.normalize();
                Depth_Stack->push(Intersection(Depth3/len, Real_Pt, Real_Normal, this));
                Found = true;
            }
        }
    }
    if (Depth4 > EPSILON)
    {
        IPoint = P + Depth4 * D;

        if (IPoint[Y] > TopVertical)
        {
            MTransPoint(Real_Pt, IPoint, Trans);
            if (Clip.empty()||(Point_In_Clip(Real_Pt, Clip, Thread)))
            {
                INormal = IPoint;
                INormal[Y] -= BottomRadius;
                INormal /= TopRadius;
                MTransNormal(Real_Normal, INormal, Trans);
                Real_Normal.normalize();
                Depth_Stack->push(Intersection(Depth4/len, Real_Pt, Real_Normal, this));
                Found = true;
            }
        }
    }

    if (Depth5 > EPSILON)
    {
        IPoint = P + Depth5 * D;
        MTransPoint(Real_Pt, IPoint, Trans);

        if (Clip.empty()||(Point_In_Clip(Real_Pt, Clip, Thread)))
        {
            INormal = IPoint;

            INormal[Y] -= VerticalPosition;
            horizontal = sqrt(Sqr(INormal[X]) + Sqr(INormal[Z]));
            INormal[X] += (INormal[X] * HorizontalPosition / horizontal);
            INormal[Z] += (INormal[Z] * HorizontalPosition / horizontal);
            INormal.normalize();
            MTransNormal(Real_Normal, INormal, Trans);
            Real_Normal.normalize();
            Depth_Stack->push(Intersection(Depth5/len, Real_Pt, Real_Normal, this));
            Found = true;
        }
    }
    if (Depth6 > EPSILON)
    {
        IPoint = P + Depth6 * D;
        MTransPoint(Real_Pt, IPoint, Trans);

        if (Clip.empty()||(Point_In_Clip(Real_Pt, Clip, Thread)))
        {
            INormal = IPoint;
            INormal[Y] -= VerticalPosition;
            horizontal = sqrt(Sqr(INormal[X]) + Sqr(INormal[Z]));
            INormal[X] += (INormal[X] * HorizontalPosition / horizontal);
            INormal[Z] += (INormal[Z] * HorizontalPosition / horizontal);
            INormal.normalize();
            MTransNormal(Real_Normal, INormal, Trans);
            Real_Normal.normalize();

            Depth_Stack->push(Intersection(Depth6/len, Real_Pt, Real_Normal, this));
            Found = true;
        }
    }
    if (Found)
    {
        Thread->Stats()[Ray_Ovus_Tests_Succeeded]++;
    }
    return (Found);
}
コード例 #30
0
ファイル: warp.cpp プロジェクト: BentSm/povray
bool TransformWarp::UnwarpNormal(Vector3d& TNorm) const
{
    MTransNormal(TNorm, TNorm, &Trans);
    return true;
}