示例#1
0
文件: torus.cpp 项目: Degot/povray
bool Torus::All_Intersections(const Ray& ray, IStack& Depth_Stack, SceneThreadData *Thread)
{
	int i, max_i, Found;
	DBL Depth[4];
	VECTOR 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))
			{
				VEvaluateRay(IPoint, ray.Origin, Depth[i], ray.Direction);

				if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread))
				{
					Depth_Stack->push(Intersection(Depth[i], IPoint, this));

					Found = true;
				}
			}
		}
	}

	return(Found);
}
示例#2
0
static int All_Cone_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
{
  int Intersection_Found, cnt, i;
  VECTOR IPoint;
  CONE_INT I[4];

  Intersection_Found = false;

  if ((cnt = intersect_cone(Ray, (CONE *)Object, I)) != 0)
  {
    for (i = 0; i < cnt; i++)
    {
      VEvaluateRay(IPoint, Ray->Initial, I[i].d, Ray->Direction);

      if (Point_In_Clip(IPoint, Object->Clip))
      {
        push_entry_i1(I[i].d,IPoint,Object,I[i].t,Depth_Stack);

        Intersection_Found = true;
      }
    }
  }

  return (Intersection_Found);
}
示例#3
0
inline DBL Float_IsoSurface_Function(ISOSURFACE* ISOSRF, DBL* t)
{
	VECTOR VTmp;

	VEvaluateRay(VTmp, ISOSRF->P, *t, ISOSRF->D);

	return ((DBL)(ISOSRF->Inv3) * (Evaluate_Function(*(ISOSRF->Function), VTmp) - ISOSRF->threshold));
}
示例#4
0
static int All_Box_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
{
  int Intersection_Found;
  int Side1, Side2;
  DBL Depth1, Depth2;
  VECTOR IPoint;

  Increase_Counter(stats[Ray_Box_Tests]);

  Intersection_Found = false;

  if (Intersect_Box(Ray, ((BOX *)Object)->Trans, ((BOX *)Object)->bounds[0], ((BOX *)Object)->bounds[1], &Depth1, &Depth2, &Side1, &Side2))
  {
    if (Depth1 > DEPTH_TOLERANCE)
    {
      VEvaluateRay(IPoint, Ray->Initial, Depth1, Ray->Direction);

      if (Point_In_Clip(IPoint, Object->Clip))
      {
        push_entry_i1(Depth1,IPoint,Object,Side1,Depth_Stack);

        Intersection_Found = true;
      }
    }

    VEvaluateRay(IPoint, Ray->Initial, Depth2, Ray->Direction);

    if (Point_In_Clip(IPoint, Object->Clip))
    {
      push_entry_i1(Depth2,IPoint,Object,Side2,Depth_Stack);

      Intersection_Found = true;
    }
  }

  if (Intersection_Found)
  {
    Increase_Counter(stats[Ray_Box_Tests_Succeeded]);
  }

  return (Intersection_Found);
}
示例#5
0
static int All_Quadric_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
{
  DBL Depth1, Depth2;
  VECTOR IPoint;
  register int Intersection_Found;

  Intersection_Found = false;

  if (Intersect_Quadric(Ray, (QUADRIC *)Object, &Depth1, &Depth2))
  {
    if ((Depth1 > Small_Tolerance) && (Depth1 < Max_Distance))
    {
      VEvaluateRay(IPoint, Ray->Initial, Depth1, Ray->Direction);

      if (Point_In_Clip(IPoint, Object->Clip))
      {
        push_entry(Depth1, IPoint, Object, Depth_Stack);

        Intersection_Found = true;
      }
    }

    if ((Depth2 > Small_Tolerance) && (Depth2 < Max_Distance))
    {
      VEvaluateRay(IPoint, Ray->Initial, Depth2, Ray->Direction);

      if (Point_In_Clip(IPoint, Object->Clip))
      {
        push_entry(Depth2, IPoint, Object, Depth_Stack);

        Intersection_Found = true;
      }
    }
  }

  return(Intersection_Found);
}
示例#6
0
文件: planes.cpp 项目: Degot/povray
bool Plane::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread)
{
	DBL Depth;
	VECTOR IPoint;

	if (Intersect(ray, &Depth, Thread))
	{
		VEvaluateRay(IPoint, ray.Origin, Depth, ray.Direction);

		if (Clip.empty() || Point_In_Clip(IPoint, Clip, Thread))
		{
			Depth_Stack->push(Intersection(Depth,IPoint,this));
			return(true);
		}
	}

	return(false);
}
示例#7
0
static int All_Plane_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
{
  DBL Depth;
  VECTOR IPoint;

  if (Intersect_Plane(Ray, (PLANE *)Object, &Depth))
  {
    VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);

    if (Point_In_Clip(IPoint, Object->Clip))
    {
      push_entry(Depth,IPoint,Object,Depth_Stack);

      return(true);
    }
  }

  return(false);
}
示例#8
0
static int All_Disc_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
{
  int Intersection_Found;
  DBL Depth;
  VECTOR IPoint;

  Intersection_Found = false;

  if (Intersect_Disc (Ray, (DISC *)Object, &Depth))
  {
    VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);

    if (Point_In_Clip (IPoint, Object->Clip))
    {
      push_entry(Depth,IPoint,Object,Depth_Stack);
      Intersection_Found = true;
    }
  }

  return (Intersection_Found);
}
示例#9
0
static DBL constant_fog(RAY *Ray, DBL Depth, DBL  Width, FOG *Fog, COLOUR Colour)
{
  DBL k;
  VECTOR P;

  if (Fog->Turb != NULL)
  {
    Depth += Width / 2.0;

    VEvaluateRay(P, Ray->Initial, Depth, Ray->Direction);

    VEvaluateEq(P, Fog->Turb->Turbulence);

    /* The further away the less influence turbulence has. */

    k = exp(-Width / Fog->Distance);

    Width *= 1.0 - k * min(1.0, Turbulence(P, Fog->Turb, NULL)*Fog->Turb_Depth);
  }

  Assign_Colour(Colour, Fog->Colour);

  return (exp(-Width / Fog->Distance));
}
示例#10
0
int IsoSurface_Function_Find_Root(ISOSURFACE* ISOSRF, VECTOR P, VECTOR D, DBL* Depth1, DBL* Depth2, bool in_shadow_test)
{
	DBL dt, t21, l_b, l_e, oldmg;
	ISO_Pair EP1, EP2;
	VECTOR VTmp;

	Increase_Counter(stats[Ray_IsoSurface_Find_Root]);

	VLength(ISOSRF->Vlength, D);

	if(ISOSRF->cache)
	{
		Increase_Counter(stats[Ray_IsoSurface_Cache]);
		VEvaluateRay(VTmp, P, *Depth1, D);
		VSubEq(VTmp, ISOSRF->P);
		VLength(l_b, VTmp);
		VEvaluateRay(VTmp, P, *Depth2, D);
		VSubEq(VTmp, ISOSRF->D);
		VLength(l_e, VTmp);
		if((ISOSRF->fmax - ISOSRF->max_gradient * max(l_b, l_e)) > 0.0)
		{
			Increase_Counter(stats[Ray_IsoSurface_Cache_Succeeded]);
			return false;
		}
	}

	Assign_Vector(ISOSRF->P, P);
	Assign_Vector(ISOSRF->D, D);

	ISOSRF->cache = false;
	EP1.t = *Depth1;
	EP1.f = Float_IsoSurface_Function(ISOSRF, Depth1);
	ISOSRF->fmax = EP1.f;
	if((ISOSRF->closed == false) && (EP1.f < 0.0))
	{
		ISOSRF->Inv3 *= -1;
		EP1.f *= -1;
	}

	EP2.t = *Depth2;
	EP2.f = Float_IsoSurface_Function(ISOSRF, Depth2);
	ISOSRF->fmax = min(EP2.f, ISOSRF->fmax);

	oldmg = ISOSRF->max_gradient;
	t21 = (*Depth2 - *Depth1);
	if((ISOSRF->eval == true) && (ISOSRF->max_gradient > ISOSRF->eval_param[0]))
		ISOSRF->max_gradient *= ISOSRF->eval_param[2];
	dt = ISOSRF->max_gradient * ISOSRF->Vlength * t21;
	if(IsoSurface_Function_Find_Root_R(ISOSRF, &EP1, &EP2, dt, t21, 1.0 / (ISOSRF->Vlength * t21), in_shadow_test))
	{
		if(ISOSRF->eval == true)
		{
			DBL curvar = fabs(ISOSRF->max_gradient - oldmg);

			if(curvar > ISOSRF->mginfo->eval_var)
				ISOSRF->mginfo->eval_var = curvar;

			ISOSRF->mginfo->eval_cnt++;
			ISOSRF->mginfo->eval_gradient_sum += ISOSRF->max_gradient;

			if(ISOSRF->max_gradient > ISOSRF->mginfo->eval_max)
				ISOSRF->mginfo->eval_max = ISOSRF->max_gradient;
		}

		*Depth1 = ISOSRF->tl;

		return true;
	}
	else if(!in_shadow_test)
	{
		ISOSRF->cache = true;
		VEvaluateRay(ISOSRF->P, P, EP1.t, D);
		VEvaluateRay(ISOSRF->D, P, EP2.t, D);

		return false;
	}

	return false;
}
示例#11
0
static int All_IsoSurface_Intersections(OBJECT* Object, RAY* Ray, ISTACK* Depth_Stack)
{
	ISOSURFACE * Isosrf = (ISOSURFACE *)Object;
	int Side1 = 0, Side2 = 0, itrace = 0, i_flg = 0;
	DBL Depth1 = 0.0, Depth2 = 0.0, len = 0.0;
	RAY New_Ray;
	VECTOR IPoint;
	VECTOR P, D;
	DBL tmax = 0.0, tmin = 0.0, tmp = 0.0;
	int i = 0 ; /* count of intervals in stack - 1      */
	int IFound = false;
	int begin = 0, end = 0;
	bool in_shadow_test = false;
	VECTOR VTmp;

	Increase_Counter(stats[Ray_IsoSurface_Bound_Tests]);

	in_shadow_test = ((Ray->Optimisiation_Flags & OPTIMISE_SHADOW_TEST) == OPTIMISE_SHADOW_TEST);

	if(Isosrf->container_shape)
	{
		if(Isosrf->Trans != NULL)
		{
			MInvTransPoint(New_Ray.Initial, Ray->Initial, Isosrf->Trans);
			MInvTransDirection(New_Ray.Direction, Ray->Direction, Isosrf->Trans);
			VLength(len, New_Ray.Direction);
			VInverseScaleEq(New_Ray.Direction, len);
			i_flg = Intersect_Sphere(&New_Ray, Isosrf->container.sphere.center, 
			                         (Isosrf->container.sphere.radius) * (Isosrf->container.sphere.radius),
			                         &Depth1, &Depth2);
			Depth1 = Depth1 / len;
			Depth2 = Depth2 / len;
		}
		else
		{
			i_flg = Intersect_Sphere(Ray, Isosrf->container.sphere.center, 
			                         (Isosrf->container.sphere.radius) * (Isosrf->container.sphere.radius), &Depth1, &Depth2);
		}
		Decrease_Counter(stats[Ray_Sphere_Tests]);
		if(i_flg)
			Decrease_Counter(stats[Ray_Sphere_Tests_Succeeded]);
	}
	else
	{
		i_flg = Intersect_Box(Ray, Isosrf->Trans, Isosrf->container.box.corner1, Isosrf->container.box.corner2,
		                      &Depth1, &Depth2, &Side1, &Side2);
	}

	if(Depth1 < 0.0)
		Depth1 = 0.0;

	if(i_flg)									/* IsoSurface_Bound_Tests */
	{
		Increase_Counter(stats[Ray_IsoSurface_Bound_Tests_Succeeded]);
		if(Isosrf->Trans != NULL)
		{
			MInvTransPoint(P, Ray->Initial, Isosrf->Trans);
			MInvTransDirection(D, Ray->Direction, Isosrf->Trans);
		}
		else
		{
			Assign_Vector(P, Ray->Initial);
			Assign_Vector(D, Ray->Direction);
		}
		Isosrf->Inv3 = 1;

		if(Isosrf->closed != false)
		{
			VEvaluateRay(VTmp, P, Depth1, D);
			tmp = Vector_IsoSurface_Function(Isosrf, VTmp);
			if(Depth1 > Isosrf->accuracy)
			{
				if(tmp < 0.0)					/* The ray hits the bounding shape */
				{
					VEvaluateRay(IPoint, Ray->Initial, Depth1, Ray->Direction);
					if(Point_In_Clip(IPoint, Object->Clip))
					{
						push_entry_i1(Depth1, IPoint, Object, Side1, Depth_Stack);
						IFound = true;
						itrace++;
						Isosrf->Inv3 *= -1;
					}
				}
			}
			else
			{
				if(tmp < (Isosrf->max_gradient * Isosrf->accuracy * 4.0))
				{
					Depth1 = Isosrf->accuracy * 5.0;
					VEvaluateRay(VTmp, P, Depth1, D);
					if(Vector_IsoSurface_Function(Isosrf, VTmp) < 0)
						Isosrf->Inv3 = -1;
					/* Change the sign of the function (IPoint is in the bounding shpae.)*/
				}
				VEvaluateRay(VTmp, P, Depth2, D);
				if(Vector_IsoSurface_Function(Isosrf, VTmp) < 0.0)
				{
					VEvaluateRay(IPoint, Ray->Initial, Depth2, Ray->Direction);
					if(Point_In_Clip(IPoint, Object->Clip))
					{
						push_entry_i1(Depth2, IPoint, Object, Side2, Depth_Stack);
						IFound = true;
					}
				}
			}
		}

		/*  METHOD 2   by R. Suzuki */
		tmax = Depth2 = min(Depth2, BOUND_HUGE);
		tmin = Depth1 = min(Depth2, Depth1);
		if((tmax - tmin) < Isosrf->accuracy)
			return (false);
		Increase_Counter(stats[Ray_IsoSurface_Tests]);
		if((Depth1 < Isosrf->accuracy) && (Isosrf->Inv3 == 1))
		{
			/* IPoint is on the isosurface */
			VEvaluateRay(VTmp, P, tmin, D);
			if(fabs(Vector_IsoSurface_Function(Isosrf, VTmp)) < (Isosrf->max_gradient * Isosrf->accuracy * 4.0))
			{
				tmin = Isosrf->accuracy * 5.0;
				VEvaluateRay(VTmp, P, tmin, D);
				if(Vector_IsoSurface_Function(Isosrf, VTmp) < 0)
					Isosrf->Inv3 = -1;
				/* change the sign and go into the isosurface */
			}
		}

		for (; itrace < Isosrf->max_trace; itrace++)
		{
			if(IsoSurface_Function_Find_Root(Isosrf, P, D, &tmin, &tmax, in_shadow_test) == false)
				break;
			else
			{
				VEvaluateRay(IPoint, Ray->Initial, tmin, Ray->Direction);
				if(Point_In_Clip(IPoint, Object->Clip))
				{
					push_entry_i1(tmin, IPoint, Object, 0 /*Side1*/, Depth_Stack);
					IFound = true;
				}
			}
			tmin += Isosrf->accuracy * 5.0;
			if((tmax - tmin) < Isosrf->accuracy)
				break;
			Isosrf->Inv3 *= -1;
		}

		if(IFound)
			Increase_Counter(stats[Ray_IsoSurface_Tests_Succeeded]);
	}

	return (IFound);
}
示例#12
0
static DBL ground_fog(RAY *Ray, DBL Depth, DBL  Width, FOG *Fog, COLOUR Colour)
{
  DBL fog_density, delta;
  DBL start, end;
  DBL y1, y2, k;
  VECTOR P, P1, P2;

  /* Get start point. */

  VEvaluateRay(P1, Ray->Initial, Depth, Ray->Direction);

  /* Get end point. */

  VLinComb2(P2, 1.0, P1, Width, Ray->Direction);

  /*
   * Could preform transfomation here to translate Start and End
   * points into ground fog space.
   */

  VDot(y1, P1, Fog->Up);
  VDot(y2, P2, Fog->Up);

  start = (y1 - Fog->Offset) / Fog->Alt;
  end   = (y2 - Fog->Offset) / Fog->Alt;

  /* Get integral along y-axis from start to end. */

  if (start <= 0.0)
  {
    if (end <= 0.0)
    {
      fog_density = 1.0;
    }
    else
    {
      fog_density = (atan(end) - start) / (end - start);
    }
  }
  else
  {
    if (end <= 0.0)
    {
      fog_density = (atan(start) - end) / (start - end);
    }
    else
    {
      delta = start - end;

      if (fabs(delta) > EPSILON)
      {
        fog_density = (atan(start) - atan(end)) / delta;
      }
      else
      {
        fog_density = 1.0 / (Sqr(start) + 1.0);
      }
    }
  }

  /* Apply turbulence. */

  if (Fog->Turb != NULL)
  {
    VHalf(P, P1, P2);

    VEvaluateEq(P, Fog->Turb->Turbulence);

    /* The further away the less influence turbulence has. */

    k = exp(-Width / Fog->Distance);

    Width *= 1.0 - k * min(1.0, Turbulence(P, Fog->Turb, NULL)*Fog->Turb_Depth);
  }

  Assign_Colour(Colour, Fog->Colour);

  return (exp(-Width * fog_density / Fog->Distance));
}