示例#1
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);
}
示例#2
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);
}
示例#3
0
void Warp_Normal (VECTOR TNorm, VECTOR ENorm, TPATTERN *TPat, int DontScaleBumps)
{
   WARP *Warp=TPat->Warps;
   TRANS *Tr;

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

   while(Warp != NULL)
   {
      switch(Warp->Warp_Type)
      {
        default:
        case NO_WARP:
          break;
        case TRANSFORM_WARP:
          Tr=(TRANS *)Warp;
          MInvTransNormal(TNorm, TNorm, &(Tr->Trans));
          break;
        /*
        default:
          Error("Warp type %d not yet implemented",Warp->Warp_Type);
        */
      }
      Warp=Warp->Next_Warp;
   }

   if(!DontScaleBumps)
      VNormalizeEq(TNorm);
}
示例#4
0
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);
}
示例#5
0
void Compute_Axis_Rotation_Transform (TRANSFORM *transform, const VECTOR AxisVect, DBL angle)
{
	DBL cosx, sinx;
	VECTOR V1;

	VNormalize(V1, AxisVect);

	MIdentity(transform->matrix);

	cosx = cos(angle);
	sinx = sin(angle);

	transform->matrix[0][0] = V1[X] * V1[X] + cosx * (1.0 - V1[X] * V1[X]);
	transform->matrix[0][1] = V1[X] * V1[Y] * (1.0 - cosx) + V1[Z] * sinx;
	transform->matrix[0][2] = V1[X] * V1[Z] * (1.0 - cosx) - V1[Y] * sinx;

	transform->matrix[1][0] = V1[X] * V1[Y] * (1.0 - cosx) - V1[Z] * sinx;
	transform->matrix[1][1] = V1[Y] * V1[Y] + cosx * (1.0 - V1[Y] * V1[Y]);
	transform->matrix[1][2] = V1[Y] * V1[Z] * (1.0 - cosx) + V1[X] * sinx;

	transform->matrix[2][0] = V1[X] * V1[Z] * (1.0 - cosx) + V1[Y] * sinx;
	transform->matrix[2][1] = V1[Y] * V1[Z] * (1.0 - cosx) - V1[X] * sinx;
	transform->matrix[2][2] = V1[Z] * V1[Z] + cosx * (1.0 - V1[Z] * V1[Z]);

	MTranspose(transform->inverse, transform->matrix);
}
示例#6
0
static void Smooth_Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
{
  int Axis;
  DBL u, v;
  VECTOR PIMinusP1;
  SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;

  VSub(PIMinusP1, Inter->IPoint, Triangle->P1);

  VDot(u, PIMinusP1, Triangle->Perp);

  if (u < EPSILON)
  {
    Assign_Vector(Result, Triangle->N1);

    return;
  }

  Axis = Triangle->vAxis;

  v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]);

  /* This is faster. [DB 8/94] */

  Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X]));
  Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y]));
  Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z]));

  VNormalize(Result, Result);
}
示例#7
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);
}
示例#8
0
static int compute_smooth_triangle(SMOOTH_TRIANGLE *Triangle)
{
  VECTOR P3MinusP2, VTemp1, VTemp2;
  DBL x, y, z, uDenominator, Proj;

  VSub(P3MinusP2, Triangle->P3, Triangle->P2);

  x = fabs(P3MinusP2[X]);
  y = fabs(P3MinusP2[Y]);
  z = fabs(P3MinusP2[Z]);

  Triangle->vAxis = max3_coordinate(x, y, z);

  VSub(VTemp1, Triangle->P2, Triangle->P3);

  VNormalize(VTemp1, VTemp1);

  VSub(VTemp2, Triangle->P1, Triangle->P3);

  VDot(Proj, VTemp2, VTemp1);

  VScaleEq(VTemp1, Proj);

  VSub(Triangle->Perp, VTemp1, VTemp2);

  VNormalize(Triangle->Perp, Triangle->Perp);

  VDot(uDenominator, VTemp2, Triangle->Perp);

  VInverseScaleEq(Triangle->Perp, -uDenominator);
  
  /* Degenerate if smooth normals are more than 90 from actual normal
     or its inverse. */
  VDot(x,Triangle->Normal_Vector,Triangle->N1);
  VDot(y,Triangle->Normal_Vector,Triangle->N2);
  VDot(z,Triangle->Normal_Vector,Triangle->N3);
  if ( ((x<0.0) && (y<0.0) && (z<0.0)) ||
       ((x>0.0) && (y>0.0) && (z>0.0)) )
  {
    return(true);
  }
  Set_Flag(Triangle, DEGENERATE_FLAG);
  return(false);
}
示例#9
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);
  }
}
示例#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
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);
}
示例#12
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);
}
示例#13
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);
  }
}
示例#14
0
void Compute_Polygon(POLYGON *Polyg, int Number, VECTOR *Points)
{
  int i;
  DBL x, y, z, d;
  VECTOR o, u, v, w, N;
  MATRIX a, b;

  /* Create polygon data. */

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

    Polyg->Data->References = 1;

    Polyg->Data->Number = Number;

    Polyg->Data->Points = (UV_VECT *)POV_MALLOC(Number*sizeof(UV_VECT), "polygon points");
  }
  else
  {
    Error("Polygon data already computed.");
  }

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

  Assign_Vector(o, Points[0]);

  /* Find valid, i.e. non-zero u vector. */
  
  for (i = 1; i < Number; i++)
  {
    VSub(u, Points[i], o);

    if (VSumSqr(u) > EPSILON)
    {
      break;
    }
  }

  if (i == Number)
  {
    Set_Flag(Polyg, DEGENERATE_FLAG);

    Warning(0, "Points in polygon are co-linear. Ignoring polygon.");
  }

  /* Find valid, i.e. non-zero v and w vectors. */
  
  for (i++; i < Number; i++)
  {
    VSub(v, Points[i], o);
    
    VCross(w, u, v);

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

  if (i == Number)
  {
    Set_Flag(Polyg, DEGENERATE_FLAG);

    Warning(0, "Points in polygon are co-linear. Ignoring polygon.");
  }

  VCross(u, v, w);
  VCross(v, w, u);

  VNormalize(u, u);
  VNormalize(v, v);
  VNormalize(w, w);

  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(Polyg->Trans->inverse, a, b);

  MInvers(Polyg->Trans->matrix, Polyg->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(Polyg, DEGENERATE_FLAG);

      Warning(0, "Points in polygon are not co-planar. Ignoring polygons.");
    }

    Polyg->Data->Points[i][X] = x * u[X] + y * u[Y] + z * u[Z];
    Polyg->Data->Points[i][Y] = x * v[X] + y * v[Y] + z * v[Z];
  }
  
  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 facets (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal, TraceThreadData *Thread)
{
	int    i;
	int    thisseed;
	DBL    sum, minsum;
	VECTOR sv, tv, dv, t1, add, newnormal, pert;
	DBL    scale;
	int    UseSquare;
	int    UseUnity;
	DBL    Metric;

	VECTOR *cv = Thread->Facets_Cube;
	Metric = Tnormal->Vals.Facets.Metric;

	UseSquare = (Metric == 2 );
	UseUnity  = (Metric == 1 );

	VNormalize( normal, normal );

	if ( Tnormal->Vals.Facets.UseCoords )
	{
		Assign_Vector(tv,EPoint);
	}
	else
	{
		Assign_Vector(tv,normal);
	}

	if ( Tnormal->Vals.Facets.Size < 1e-6 )
	{
		scale = 1e6;
	}
	else
	{
		scale = 1. / Tnormal->Vals.Facets.Size;
	}

	VScaleEq( tv, scale );

	/*
	 * Check to see if the input point is in the same unit cube as the last
	 * call to this function, to use cache of cubelets for speed.
	 */

	thisseed = PickInCube(tv, t1);

	if (thisseed != Thread->Facets_Last_Seed)
	{
		/*
		 * No, not same unit cube.  Calculate the random points for this new
		 * cube and its 80 neighbours which differ in any axis by 1 or 2.
		 * Why distance of 2?  If there is 1 point in each cube, located
		 * randomly, it is possible for the closest random point to be in the
		 * cube 2 over, or the one two over and one up.  It is NOT possible
		 * for it to be two over and two up.  Picture a 3x3x3 cube with 9 more
		 * cubes glued onto each face.
		 */

		/* Now store a points for this cube and each of the 80 neighbour cubes. */

		int cvc = 0;

		for (add[X] = -2.0; add[X] < 2.5; add[X] +=1.0)
		{
			for (add[Y] = -2.0; add[Y] < 2.5; add[Y] += 1.0)
			{
				for (add[Z] = -2.0; add[Z] < 2.5; add[Z] += 1.0)
				{
					/* For each cubelet in a 5x5 cube. */

					if ((fabs(add[X])>1.5)+(fabs(add[Y])>1.5)+(fabs(add[Z])>1.5) <= 1.0)
					{
						/* Yes, it's within a 3d knight move away. */

						VAdd(sv, tv, add);

						PickInCube(sv, t1);

						cv[cvc][X] = t1[X];
						cv[cvc][Y] = t1[Y];
						cv[cvc][Z] = t1[Z];
						cvc++;
					}
				}
			}
		}

		Thread->Facets_Last_Seed = thisseed;
		Thread->Facets_CVC = cvc;
	}

	/*
	 * Find the point with the shortest distance from the input point.
	 */

	VSub(dv, cv[0], tv);
	if ( UseSquare )
	{
		minsum  = VSumSqr(dv);
	}
	else if ( UseUnity )
	{
		minsum = dv[X]+dv[Y]+dv[Z];
	}
	else
	{
		minsum = pow(fabs(dv[X]), Metric)+
		         pow(fabs(dv[Y]), Metric)+
		         pow(fabs(dv[Z]), Metric);
	}

	Assign_Vector( newnormal, cv[0] );

	/* Loop for the 81 cubelets to find closest. */

	for (i = 1; i < Thread->Facets_CVC; i++)
	{
		VSub(dv, cv[i], tv);

		if ( UseSquare )
		{
			sum  = VSumSqr(dv);
		}
		else
		{
			if ( UseUnity )
			{
				sum = dv[X]+dv[Y]+dv[Z];
			}
			else
			{
				sum = pow(fabs(dv[X]), Metric)+
				      pow(fabs(dv[Y]), Metric)+
				      pow(fabs(dv[Z]), Metric);
			}
		}

		if (sum < minsum)
		{
			minsum = sum;
			Assign_Vector( newnormal, cv[i] );
		}
	}

	if ( Tnormal->Vals.Facets.UseCoords )
	{
		DNoise( pert, newnormal );
		VDot( sum, pert, normal );
		VScale( newnormal, normal, sum );
		VSubEq( pert, newnormal );
		VAddScaledEq( normal, Tnormal->Vals.Facets.UseCoords, pert );
	}
	else
	{
		Assign_Vector( normal, newnormal );
	}
}
示例#16
0
void bump_map(VECTOR EPoint, TNORMAL *Tnormal, VECTOR normal)
{
  DBL xcoor = 0.0, ycoor = 0.0;
  int index, index2, index3;
  COLOUR colour1, colour2, colour3;
  VECTOR p1, p2, p3;
  VECTOR bump_normal;
  VECTOR xprime, yprime, zprime, Temp;
  DBL Length;
  DBL Amount = Tnormal->Amount;
  IMAGE *Image = Tnormal->Vals.Image;

  Make_ColourA(colour1, 0.0, 0.0, 0.0, 0.0, 0.0);
  Make_ColourA(colour2, 0.0, 0.0, 0.0, 0.0, 0.0);
  Make_ColourA(colour3, 0.0, 0.0, 0.0, 0.0, 0.0);

  /* going to have to change this */
  /* need to know if bump point is off of image for all 3 points */

  if (map(EPoint, (TPATTERN *) Tnormal, &xcoor, &ycoor))
  {
    return;
  }
  else
  {
    image_colour_at(Image, xcoor, ycoor, colour1, &index);
  }

  xcoor--;
  ycoor++;

  if (xcoor < 0.0)
  {
    xcoor += (DBL)Image->iwidth;
  }
  else
  {
    if (xcoor >= Image->iwidth)
    {
      xcoor -= (DBL)Image->iwidth;
    }
  }

  if (ycoor < 0.0)
  {
    ycoor += (DBL)Image->iheight;
  }
  else
  {
    if (ycoor >= (DBL)Image->iheight)
    {
      ycoor -= (DBL)Image->iheight;
    }
  }

  image_colour_at(Image, xcoor, ycoor, colour2, &index2);

  xcoor += 2.0;

  if (xcoor < 0.0)
  {
    xcoor += (DBL)Image->iwidth;
  }
  else
  {
    if (xcoor >= Image->iwidth)
    {
      xcoor -= (DBL)Image->iwidth;
    }
  }

  image_colour_at(Image, xcoor, ycoor, colour3, &index3);

  if (Image->Colour_Map == NULL || Image->Use_Colour_Flag)
  {
    p1[X] = 0;
    p1[Y] = Amount * (GREY_SCALE( colour1 ));
    p1[Z] = 0;

    p2[X] = -1;
    p2[Y] = Amount * (GREY_SCALE( colour2 ));
    p2[Z] = 1;

    p3[X] = 1;
    p3[Y] = Amount * (GREY_SCALE( colour3 ));
    p3[Z] = 1;
  }
  else
  {
    p1[X] = 0;
    p1[Y] = Amount * index;
    p1[Z] = 0;

    p2[X] = -1;
    p2[Y] = Amount * index2;
    p2[Z] = 1;

    p3[X] = 1;
    p3[Y] = Amount * index3;
    p3[Z] = 1;
  }

  /* we have points 1,2,3 for a triangle now we need the surface normal for it */

  VSub(xprime, p1, p2);
  VSub(yprime, p3, p2);
  VCross(bump_normal, yprime, xprime);
  VNormalize(bump_normal, bump_normal);

  Assign_Vector(yprime, normal);
  Make_Vector(Temp, 0.0, 1.0, 0.0);
  VCross(xprime, yprime, Temp);
  VLength(Length, xprime);

  if (Length < EPSILON)
  {
    if (fabs(normal[Y] - 1.0) < Small_Tolerance)
    {
      Make_Vector(yprime, 0.0, 1.0, 0.0);
      Make_Vector(xprime, 1.0, 0.0, 0.0);
      Length = 1.0;
    }
    else
    {
      Make_Vector(yprime, 0.0, -1.0, 0.0);
      Make_Vector(xprime, 1.0, 0.0, 0.0);
      Length = 1.0;
    }
  }

  VScaleEq(xprime, 1.0 / Length);
  VCross(zprime, xprime, yprime);
  VNormalizeEq(zprime);
  VScaleEq(xprime, bump_normal[X]);
  VScaleEq(yprime, bump_normal[Y]);
  VScaleEq(zprime, bump_normal[Z]);
  VAdd(Temp, xprime, yprime);
  VScaleEq(zprime, -1);
  VAdd(normal, Temp, zprime);
}
示例#17
0
static void IsoSurface_Normal(VECTOR Result, OBJECT* Object, INTERSECTION* Inter)
{
	VECTOR New_Point, TPoint;
	ISOSURFACE *Isosrf = (ISOSURFACE *)Object;
	FUNCTION Function = *(((ISOSURFACE *)Object)->Function);
	DBL funct;

	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:

			/* Transform the point into the isosurface space */
			if(((ISOSURFACE *)Object)->Trans != NULL)
				MInvTransPoint(New_Point, Inter->IPoint, Isosrf->Trans);
			else
				Assign_Vector(New_Point, Inter->IPoint);

			if(Isosrf->container_shape)
			{
				VSub(Result, New_Point, Isosrf->container.sphere.center);
				VLength(funct, Result);
				if(fabs(funct - Isosrf->container.sphere.radius) < EPSILON)
				{
					VInverseScaleEq(Result, Isosrf->container.sphere.radius);
					break;
				}
			}

			Assign_Vector(TPoint, New_Point);
			funct = Evaluate_Function(Function, TPoint);
			Assign_Vector(TPoint, New_Point);
			TPoint[X] += Isosrf->accuracy;
			Result[X] = Evaluate_Function(Function, TPoint) - funct;
			Assign_Vector(TPoint, New_Point);
			TPoint[Y] += Isosrf->accuracy;
			Result[Y] = Evaluate_Function(Function, TPoint) - funct;
			Assign_Vector(TPoint, New_Point);
			TPoint[Z] += Isosrf->accuracy;
			Result[Z] = Evaluate_Function(Function, TPoint) - funct;

			if((Result[X] == 0) && (Result[Y] == 0) && (Result[Z] == 0))
				Result[X] = 1.0;
			VNormalize(Result, Result);
	}


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

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

		VNormalize(Result, Result);
	}
}