Ejemplo n.º 1
0
void Perturb_Normal(Vector3d& Layer_Normal, const TNORMAL *Tnormal, const Vector3d& EPoint, Intersection *Intersection, const Ray *ray, TraceThreadData *Thread)
{
    Vector3d TPoint,P1;
    DBL value1,Amount;
    int i;
    shared_ptr<NormalBlendMap> Blend_Map;

    if (Tnormal==NULL)
    {
        return;
    }

    /* If normal_map present, use it and return */

    Blend_Map = std::tr1::dynamic_pointer_cast<NormalBlendMap>(Tnormal->Blend_Map);
    if (Blend_Map != NULL)
    {
        if (Tnormal->Type == UV_MAP_PATTERN)
        {
            Vector2d UV_Coords;

            /* Don't bother warping, simply get the UV vect of the intersection */
            Intersection->Object->UVCoord(UV_Coords, Intersection, Thread);
            TPoint[X] = UV_Coords[U];
            TPoint[Y] = UV_Coords[V];
            TPoint[Z] = 0;

            Perturb_Normal(Layer_Normal,Blend_Map->Blend_Map_Entries[0].Vals,TPoint,Intersection,ray,Thread);
            Layer_Normal.normalize();
            Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */

            return;
        }
        else if (Tnormal->Type != AVERAGE_PATTERN)
        {
            const NormalBlendMapEntry *Prev, *Cur;
            DBL prevWeight, curWeight;

            /* NK 19 Nov 1999 added Warp_EPoint */
            Warp_EPoint (TPoint, EPoint, Tnormal);
            value1 = Evaluate_TPat(Tnormal, TPoint, Intersection, ray, Thread);

            Blend_Map->Search (value1,Prev,Cur,prevWeight,curWeight);

            Warp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));
            P1 = Layer_Normal;

            Warp_EPoint (TPoint, EPoint, Tnormal);

            Perturb_Normal(Layer_Normal,Cur->Vals,TPoint,Intersection,ray,Thread);

            if (Prev != Cur)
            {
                Perturb_Normal(P1,Prev->Vals,TPoint,Intersection,ray,Thread);

                Layer_Normal = prevWeight * P1 + curWeight * Layer_Normal;
            }

            UnWarp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

            Layer_Normal.normalize();

            Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */

            return;
        }
        // TODO - what if Tnormal->Type == AVERAGE_PATTERN?
    }

    /* No normal_map. */

    if (Tnormal->Type <= LAST_NORM_ONLY_PATTERN)
    {
        Warp_Normal(Layer_Normal,Layer_Normal, Tnormal,
                    Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

        Warp_EPoint (TPoint, EPoint, Tnormal);

        switch (Tnormal->Type)
        {
        case BITMAP_PATTERN:
            bump_map    (TPoint, Tnormal, Layer_Normal);
            break;
        case BUMPS_PATTERN:
            bumps       (TPoint, Tnormal, Layer_Normal);
            break;
        case DENTS_PATTERN:
            dents       (TPoint, Tnormal, Layer_Normal, Thread);
            break;
        case RIPPLES_PATTERN:
            ripples     (TPoint, Tnormal, Layer_Normal, Thread);
            break;
        case WAVES_PATTERN:
            waves       (TPoint, Tnormal, Layer_Normal, Thread);
            break;
        case WRINKLES_PATTERN:
            wrinkles    (TPoint, Tnormal, Layer_Normal);
            break;
        case QUILTED_PATTERN:
            quilted     (TPoint, Tnormal, Layer_Normal);
            break;
        case FACETS_PATTERN:
            facets      (TPoint, Tnormal, Layer_Normal, Thread);
            break;
        case AVERAGE_PATTERN:
            Do_Average_Normals (TPoint, Tnormal, Layer_Normal, Intersection, ray, Thread);
            break;
        default:
            throw POV_EXCEPTION_STRING("Normal pattern not yet implemented.");
        }

        UnWarp_Normal(Layer_Normal,Layer_Normal, Tnormal,
                      Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));
    }
    else
    {
        shared_ptr<SlopeBlendMap> slopeMap = std::tr1::dynamic_pointer_cast<SlopeBlendMap>(Tnormal->Blend_Map);

        Warp_Normal(Layer_Normal,Layer_Normal, Tnormal,
                    Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

        // TODO FIXME - two magic fudge factors
        Amount=Tnormal->Amount * -5.0; /*fudge factor*/
        Amount*=0.02/Tnormal->Delta; /* NK delta */

        /* warp the center point first - this is the last warp */
        Warp_EPoint(TPoint,EPoint,Tnormal);

        for(i=0; i<=3; i++)
        {
            P1 = TPoint + (DBL)Tnormal->Delta * Pyramid_Vect[i]; /* NK delta */
            value1 = Do_Slope_Map(Evaluate_TPat(Tnormal, P1, Intersection, ray, Thread), slopeMap.get());
            Layer_Normal += (value1*Amount) * Pyramid_Vect[i];
        }

        UnWarp_Normal(Layer_Normal,Layer_Normal,Tnormal,
                      Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

    }

    if ( Intersection )
        Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */
}
Ejemplo n.º 2
0
bool Compute_Pigment (Colour& colour, const PIGMENT *Pigment, const VECTOR EPoint, const Intersection *Intersect, const Ray *ray, TraceThreadData *Thread)
{
	int Colour_Found;
	VECTOR TPoint;
	DBL value;
	register DBL fraction;
	const BLEND_MAP_ENTRY *Cur, *Prev;
	Colour Temp_Colour;
	const BLEND_MAP *Blend_Map = Pigment->Blend_Map;
	UV_VECT UV_Coords;

	if ((Thread->qualityFlags & Q_QUICKC) != 0 && Pigment->Quick_Colour[pRED] != -1.0 && Pigment->Quick_Colour[pGREEN] != -1.0 && Pigment->Quick_Colour[pBLUE] != -1.0)
	{
		colour = Pigment->Quick_Colour;
		return (true);
	}

	if (Pigment->Type <= LAST_SPECIAL_PATTERN)
	{
		Colour_Found = true;

		switch (Pigment->Type)
		{
			case NO_PATTERN:

				colour.clear();

				break;

			case PLAIN_PATTERN:

				colour = Pigment->colour;

				break;

			case AVERAGE_PATTERN:

				Warp_EPoint (TPoint, EPoint, reinterpret_cast<const TPATTERN *>(Pigment));

				Do_Average_Pigments(colour, Pigment, TPoint, Intersect, ray, Thread);

				break;

			case UV_MAP_PATTERN:
				if(Intersect == NULL)
					throw POV_EXCEPTION_STRING("The 'uv_mapping' pattern cannot be used as part of a pigment function!");

				Cur = &(Pigment->Blend_Map->Blend_Map_Entries[0]);

				if (Blend_Map->Type == COLOUR_TYPE)
				{
					Colour_Found = true;

					Assign_Colour(*colour, Cur->Vals.colour);
				}
				else
				{
					/* Don't bother warping, simply get the UV vect of the intersection */
					Intersect->Object->UVCoord(UV_Coords, Intersect, Thread);
					TPoint[X] = UV_Coords[U];
					TPoint[Y] = UV_Coords[V];
					TPoint[Z] = 0;

					if (Compute_Pigment(colour, Cur->Vals.Pigment,TPoint,Intersect, ray, Thread))
						Colour_Found = true;
				}

				break;

			case BITMAP_PATTERN:

				Warp_EPoint (TPoint, EPoint, reinterpret_cast<const TPATTERN *>(Pigment));

				colour.clear();

				Colour_Found = image_map (TPoint, Pigment, colour);

				break;

			default:

				throw POV_EXCEPTION_STRING("Pigment type not yet implemented.");
		}

		return(Colour_Found);
	}

	Colour_Found = false;

	/* NK 19 Nov 1999 added Warp_EPoint */
	Warp_EPoint (TPoint, EPoint, reinterpret_cast<const TPATTERN *>(Pigment));
	value = Evaluate_TPat (reinterpret_cast<const TPATTERN *>(Pigment),TPoint,Intersect, ray, Thread);

	Search_Blend_Map (value, Blend_Map, &Prev, &Cur);

	if (Blend_Map->Type == COLOUR_TYPE)
	{
		Colour_Found = true;

		Assign_Colour(*colour, Cur->Vals.colour);
	}
	else
	{
		Warp_EPoint (TPoint, EPoint, reinterpret_cast<const TPATTERN *>(Pigment));

		if (Compute_Pigment(colour, Cur->Vals.Pigment,TPoint,Intersect, ray, Thread))
			Colour_Found = true;
	}

	if (Prev != Cur)
	{
		if (Blend_Map->Type == COLOUR_TYPE)
		{
			Colour_Found = true;

			Assign_Colour(*Temp_Colour, Prev->Vals.colour);
		}
		else
		{
			if (Compute_Pigment(Temp_Colour, Prev->Vals.Pigment, TPoint, Intersect, ray, Thread))
				Colour_Found = true;
		}

		fraction = (value - Prev->value) / (Cur->value - Prev->value);

		colour = Temp_Colour + fraction * (colour - Temp_Colour);
	}

	return(Colour_Found);
}
Ejemplo n.º 3
0
int Compute_Pigment (COLOUR Colour, PIGMENT *Pigment, VECTOR EPoint, INTERSECTION *Intersect)
{
  int Colour_Found;
  VECTOR TPoint;
  DBL value;
  register DBL fraction;
  BLEND_MAP_ENTRY *Cur, *Prev;
  COLOUR Temp_Colour;
  BLEND_MAP *Blend_Map = Pigment->Blend_Map;
  UV_VECT UV_Coords;

  if (Pigment->Type <= LAST_SPECIAL_PATTERN)
  {
    Colour_Found = true;

    switch (Pigment->Type)
    {
      case NO_PATTERN:

        Make_Colour(Colour, 0.0, 0.0, 0.0);

        break;

      case PLAIN_PATTERN:

        Assign_Colour(Colour,Pigment->Colour);

        break;

      case AVERAGE_PATTERN:

        Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment);

        Do_Average_Pigments(Colour,Pigment,TPoint,Intersect);

        break;

      case UV_MAP_PATTERN:
        if(Intersect == NULL)
           Error("The 'uv_mapping' pattern cannot be used as part of a pigment function!");

        Cur = &(Pigment->Blend_Map->Blend_Map_Entries[0]);

        if (Blend_Map->Type == COLOUR_TYPE)
        {
          Colour_Found = true;

          Assign_Colour(Colour, Cur->Vals.Colour);
        }
        else
        {
          /* Don't bother warping, simply get the UV vect of the intersection */
          UVCoord(UV_Coords, Intersect->Object, Intersect);
          TPoint[X] = UV_Coords[U];
          TPoint[Y] = UV_Coords[V];
          TPoint[Z] = 0;

          if (Compute_Pigment(Colour, Cur->Vals.Pigment,TPoint,Intersect))
          {
            Colour_Found = true;
          }
        }

        break;

      case BITMAP_PATTERN:

        Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment);

        Make_Colour(Colour, 0.0, 0.0, 0.0);

        Colour_Found = image_map (TPoint, Pigment, Colour);

        break;

      default:

        Error("Pigment type %d not yet implemented",Pigment->Type);
    }

    return(Colour_Found);
  }

  Colour_Found = false;

  /* NK 19 Nov 1999 added Warp_EPoint */
	Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment);
	value = Evaluate_TPat ((TPATTERN *)Pigment,TPoint,Intersect);

  Search_Blend_Map (value, Blend_Map, &Prev, &Cur);

  if (Blend_Map->Type == COLOUR_TYPE)
  {
    Colour_Found = true;

    Assign_Colour(Colour, Cur->Vals.Colour);
  }
  else
  {
    Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment);

    if (Compute_Pigment(Colour, Cur->Vals.Pigment,TPoint,Intersect))
    {
      Colour_Found = true;
    }
  }

  if (Prev != Cur)
  {
    if (Blend_Map->Type == COLOUR_TYPE)
    {
      Colour_Found = true;

      Assign_Colour(Temp_Colour, Prev->Vals.Colour);
    }
    else
    {
      if (Compute_Pigment(Temp_Colour, Prev->Vals.Pigment, TPoint,Intersect))
      {
        Colour_Found = true;
      }
    }

    fraction = (value - Prev->value) / (Cur->value - Prev->value);

    Colour[pRED]    = Temp_Colour[pRED]    + fraction * (Colour[pRED]    - Temp_Colour[pRED]);
    Colour[pGREEN]  = Temp_Colour[pGREEN]  + fraction * (Colour[pGREEN]  - Temp_Colour[pGREEN]);
    Colour[pBLUE]   = Temp_Colour[pBLUE]   + fraction * (Colour[pBLUE]   - Temp_Colour[pBLUE]);
    Colour[pFILTER] = Temp_Colour[pFILTER] + fraction * (Colour[pFILTER] - Temp_Colour[pFILTER]);
    Colour[pTRANSM] = Temp_Colour[pTRANSM] + fraction * (Colour[pTRANSM] - Temp_Colour[pTRANSM]);
  }

  return(Colour_Found);
}
Ejemplo n.º 4
0
void Perturb_Normal(VECTOR Layer_Normal, const TNORMAL *Tnormal, const VECTOR EPoint, Intersection *Intersection, const Ray *ray, TraceThreadData *Thread)
{
	VECTOR TPoint,P1;
	DBL value1,value2,Amount;
	int i;
	BLEND_MAP *Blend_Map;
	BLEND_MAP_ENTRY *Prev, *Cur;

	if (Tnormal==NULL)
	{
		return;
	}

	/* If normal_map present, use it and return */

	if ((Blend_Map=Tnormal->Blend_Map) != NULL)
	{
		if ((Blend_Map->Type == NORMAL_TYPE) && (Tnormal->Type == UV_MAP_PATTERN))
		{
			UV_VECT UV_Coords;

			Cur = &(Tnormal->Blend_Map->Blend_Map_Entries[0]);

			/* Don't bother warping, simply get the UV vect of the intersection */
			Intersection->Object->UVCoord(UV_Coords, Intersection, Thread);
			TPoint[X] = UV_Coords[U];
			TPoint[Y] = UV_Coords[V];
			TPoint[Z] = 0;

			Perturb_Normal(Layer_Normal,Cur->Vals.Tnormal,TPoint,Intersection,ray,Thread);
			VNormalizeEq(Layer_Normal);
			Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */

			return;
		}
		else if ((Blend_Map->Type == NORMAL_TYPE) && (Tnormal->Type != AVERAGE_PATTERN))
		{
			/* NK 19 Nov 1999 added Warp_EPoint */
			Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal);
			value1 = Evaluate_TPat((TPATTERN *)Tnormal,TPoint,Intersection,ray,Thread);

			Search_Blend_Map (value1,Blend_Map,&Prev,&Cur);

			Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));
			Assign_Vector(P1,Layer_Normal);

			Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal);

			Perturb_Normal(Layer_Normal,Cur->Vals.Tnormal,TPoint,Intersection,ray,Thread);

			if (Prev != Cur)
			{
				Perturb_Normal(P1,Prev->Vals.Tnormal,TPoint,Intersection,ray,Thread);

				value2 = (value1-Prev->value)/(Cur->value-Prev->value);
				value1 = 1.0-value2;

				VLinComb2(Layer_Normal,value1,P1,value2,Layer_Normal);
			}

			UnWarp_Normal(Layer_Normal,Layer_Normal,(TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

			VNormalizeEq(Layer_Normal);

			Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */

			return;
		}
	}

	/* No normal_map. */

	if (Tnormal->Type <= LAST_NORM_ONLY_PATTERN)
	{
		Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal,
		            Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

		Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal);

		switch (Tnormal->Type)
		{
			case BITMAP_PATTERN:    bump_map    (TPoint, Tnormal, Layer_Normal);            break;
			case BUMPS_PATTERN:     bumps       (TPoint, Tnormal, Layer_Normal);            break;
			case DENTS_PATTERN:     dents       (TPoint, Tnormal, Layer_Normal, Thread);    break;
			case RIPPLES_PATTERN:   ripples     (TPoint, Tnormal, Layer_Normal, Thread);    break;
			case WAVES_PATTERN:     waves       (TPoint, Tnormal, Layer_Normal, Thread);    break;
			case WRINKLES_PATTERN:  wrinkles    (TPoint, Tnormal, Layer_Normal);            break;
			case QUILTED_PATTERN:   quilted     (TPoint, Tnormal, Layer_Normal);            break;
			case FACETS_PATTERN:    facets      (TPoint, Tnormal, Layer_Normal, Thread);    break;
			case AVERAGE_PATTERN:   Do_Average_Normals (TPoint, Tnormal, Layer_Normal, Intersection, ray, Thread); break;
			default:
				throw POV_EXCEPTION_STRING("Normal pattern not yet implemented.");
		}

		UnWarp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal,
		              Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));
	}
	else
	{
		Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal,
		            Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

		Amount=Tnormal->Amount * -5.0; /*fudge factor*/
		Amount*=0.02/Tnormal->Delta; /* NK delta */

		/* warp the center point first - this is the last warp */
		Warp_EPoint(TPoint,EPoint,(TPATTERN *)Tnormal);

		for(i=0; i<=3; i++)
		{
			VAddScaled(P1,TPoint,Tnormal->Delta,Pyramid_Vect[i]); /* NK delta */
			value1 = Do_Slope_Map(Evaluate_TPat((TPATTERN *)Tnormal,P1,Intersection,ray,Thread),Blend_Map);
			VAddScaledEq(Layer_Normal,value1*Amount,Pyramid_Vect[i]);
		}

		UnWarp_Normal(Layer_Normal,Layer_Normal,(TPATTERN *)Tnormal,
		              Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG));

	}

	if ( Intersection )
		Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */
}
Ejemplo n.º 5
0
bool Compute_Pigment (TransColour& colour, const PIGMENT *Pigment, const Vector3d& EPoint, const Intersection *Intersect, const Ray *ray, TraceThreadData *Thread)
{
    bool Colour_Found;
    Vector3d TPoint;
    DBL value;

    if (Thread->qualityFlags.quickColour && Pigment->Quick_Colour.IsValid())
    {
        colour = Pigment->Quick_Colour;
        return (true);
    }

    if (Pigment->Type <= LAST_SPECIAL_PATTERN)
    {
        Colour_Found = true;

        switch (Pigment->Type)
        {
            case NO_PATTERN:

                assert(false); // should have been forced to PLAIN_PATTERN in Post_Pigment
                colour.Clear();

                break;

            case PLAIN_PATTERN:

                colour = Pigment->colour;

                break;

            case AVERAGE_PATTERN:

                Warp_EPoint (TPoint, EPoint, Pigment);

                Do_Average_Pigments(colour, Pigment, TPoint, Intersect, ray, Thread);

                break;

            case UV_MAP_PATTERN:
                if(Intersect == NULL)
                    throw POV_EXCEPTION_STRING("The 'uv_mapping' pattern cannot be used as part of a pigment function!");

                Colour_Found = Pigment->Blend_Map->ComputeUVMapped(colour, Intersect, ray, Thread);
                break;

            case BITMAP_PATTERN:

                Warp_EPoint (TPoint, EPoint, Pigment);

                colour.Clear();

                Colour_Found = image_map (TPoint, Pigment, colour);

                break;

            default:

                throw POV_EXCEPTION_STRING("Pigment type not yet implemented.");
        }

        return(Colour_Found);
    }

    /* NK 19 Nov 1999 added Warp_EPoint */
    Warp_EPoint (TPoint, EPoint, Pigment);
    value = Evaluate_TPat (Pigment, TPoint, Intersect, ray, Thread);

    return Pigment->Blend_Map->Compute (colour, value, TPoint, Intersect, ray, Thread);
}