Beispiel #1
0
static void Do_Average_Pigments (COLOUR Colour, PIGMENT *Pigment, VECTOR EPoint, INTERSECTION *Intersect)
{
   int i;
   COLOUR LC;
   BLEND_MAP *Map = Pigment->Blend_Map;
   SNGL Value;
   SNGL Total = 0.0;
   
   Make_Colour (Colour, 0.0, 0.0, 0.0);

   for (i = 0; i < Map->Number_Of_Entries; i++)
   {
     Value = Map->Blend_Map_Entries[i].value;

     Compute_Pigment (LC,Map->Blend_Map_Entries[i].Vals.Pigment,EPoint,Intersect);
     
     Colour[pRED]   += LC[pRED]   *Value;
     Colour[pGREEN] += LC[pGREEN] *Value;
     Colour[pBLUE]  += LC[pBLUE]  *Value;
     Colour[pFILTER]+= LC[pFILTER]*Value;
     Colour[pTRANSM]+= LC[pTRANSM]*Value;

     Total += Value;
   }
   Colour[pRED]   /= Total;
   Colour[pGREEN] /= Total;
   Colour[pBLUE]  /= Total;
   Colour[pFILTER]/= Total;
   Colour[pTRANSM]/= Total;
}
Beispiel #2
0
bool PigmentBlendMap::Compute(TransColour& colour, DBL value, const Vector3d& TPoint, const Intersection *Intersect, const Ray *ray, TraceThreadData *Thread)
{
    const BlendMapEntry<PIGMENT*>* Prev;
    const BlendMapEntry<PIGMENT*>* Cur;
    DBL prevWeight;
    DBL curWeight;
    bool found = false;
    Search (value, Prev, Cur, prevWeight, curWeight);
    if (Compute_Pigment(colour, Cur->Vals, TPoint, Intersect, ray, Thread))
        found = true;
    if (Prev != Cur)
    {
        TransColour Temp_Colour;
        if (Compute_Pigment(Temp_Colour, Prev->Vals, TPoint, Intersect, ray, Thread))
            found = true;
        Blend(colour, Temp_Colour, prevWeight, colour, curWeight, Thread);
    }
    return found;
}
Beispiel #3
0
bool PigmentBlendMap::ComputeUVMapped(TransColour& colour, const Intersection *Intersect, const Ray *ray, TraceThreadData *Thread)
{
    Vector2d UV_Coords;
    Vector3d TPoint;
    const BlendMapEntry<PIGMENT*>* Cur = &(Blend_Map_Entries[0]);

    /* 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;

    return Compute_Pigment(colour, Cur->Vals, TPoint, Intersect, ray, Thread);
}
Beispiel #4
0
void PigmentBlendMap::ComputeAverage(TransColour& colour, const Vector3d& EPoint, const Intersection *Intersect, const Ray *ray, TraceThreadData *Thread)
{
    SNGL Total = 0.0;
    TransColour tempColour;

    colour.Clear();
    for(vector<PigmentBlendMapEntry>::const_iterator i = Blend_Map_Entries.begin(); i != Blend_Map_Entries.end(); i++)
    {
        Compute_Pigment (tempColour, i->Vals, EPoint, Intersect, ray, Thread);

        colour += i->value * tempColour;
        Total  += i->value;
    }
    colour /= Total;
}
Beispiel #5
0
void Evaluate_Density_Pigment(vector<PIGMENT*>& Density, const Vector3d& p, MathColour& c, TraceThreadData *ttd)
{
    TransColour lc;

    c.Set(1.0);

    // TODO - Reverse iterator may be less performant than forward iterator; we might want to
    //        compare performance with using forward iterators and decrement, or using random access.
    //        Alternatively, reversing the vector after parsing might be another option.
    for (vector<PIGMENT*>::reverse_iterator i = Density.rbegin(); i != Density.rend(); ++ i)
    {
        lc.Clear();

        Compute_Pigment(lc, *i, p, NULL, NULL, ttd);

        c *= lc.colour();
    }
}
Beispiel #6
0
void Evaluate_Density_Pigment(const PIGMENT *pigm, const Vector3d& p, RGBColour& c, TraceThreadData *ttd)
{
	Colour lc;

	c.set(1.0);

	while(pigm != NULL)
	{
		lc.clear();

		Compute_Pigment(lc, pigm, *p, NULL, NULL, ttd);

		c.red()   *= lc.red();
		c.green() *= lc.green();
		c.blue()  *= lc.blue();

		pigm = reinterpret_cast<const PIGMENT *>(pigm->Next);
	}
}
Beispiel #7
0
static void Do_Average_Pigments (Colour& colour, const PIGMENT *Pigment, const VECTOR EPoint, const Intersection *Intersect, const Ray *ray, TraceThreadData *Thread)
{
	int i;
	Colour LC;
	BLEND_MAP *Map = Pigment->Blend_Map;
	SNGL Value;
	SNGL Total = 0.0;

	colour.clear();

	for (i = 0; i < Map->Number_Of_Entries; i++)
	{
		Value = Map->Blend_Map_Entries[i].value;

		Compute_Pigment (LC, Map->Blend_Map_Entries[i].Vals.Pigment, EPoint, Intersect, ray, Thread);

		colour += LC * Value;
		Total  += Value;
	}
	colour /= Total;
}
Beispiel #8
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);
}
Beispiel #9
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);
}
static void do_skysphere(RAY *Ray, COLOUR Colour)
{
  int i;
  DBL att, trans;
  COLOUR Col, Col_Temp, Filter;
  VECTOR P;
  SKYSPHERE *Skysphere;

  /* Why are we here. */

  if (Frame.Skysphere == NULL)
  {
    return;
  }

  Make_Colour(Col, 0.0, 0.0, 0.0);

  if (((Skysphere = Frame.Skysphere) != NULL) && (Skysphere->Pigments != NULL))
  {
    Make_ColourA(Filter, 1.0, 1.0, 1.0, 1.0, 1.0);

    trans = 1.0;

    /* Transform point on unit sphere. */

    if (Skysphere->Trans != NULL)
    {
      MInvTransPoint(P, Ray->Direction, Skysphere->Trans);
    }
    else
    {
      Assign_Vector(P, Ray->Direction);
    }

    for (i = Skysphere->Count-1; i >= 0; i--)
    {
      /* Compute sky colour from colour map. */

      /* NK 1998 - added NULL as final parameter */
      Compute_Pigment(Col_Temp, Skysphere->Pigments[i], P, NULL);
      /* NK ---- */

      att = trans * (1.0 - Col_Temp[pFILTER] - Col_Temp[pTRANSM]);

      CRGBAddScaledEq(Col, att, Col_Temp);

      Filter[pRED]    *= Col_Temp[pRED];
      Filter[pGREEN]  *= Col_Temp[pGREEN];
      Filter[pBLUE]   *= Col_Temp[pBLUE];
      Filter[pFILTER] *= Col_Temp[pFILTER];
      Filter[pTRANSM] *= Col_Temp[pTRANSM];

      trans = fabs(Filter[pFILTER]) + fabs(Filter[pTRANSM]);
    }

    Colour[pRED]    = Col[pRED]    + Colour[pRED]   * (Filter[pRED]   * Filter[pFILTER] + Filter[pTRANSM]);
    Colour[pGREEN]  = Col[pGREEN]  + Colour[pGREEN] * (Filter[pGREEN] * Filter[pFILTER] + Filter[pTRANSM]);
    Colour[pBLUE]   = Col[pBLUE]   + Colour[pBLUE]  * (Filter[pBLUE]  * Filter[pFILTER] + Filter[pTRANSM]);
    Colour[pFILTER] = Colour[pFILTER] * Filter[pFILTER];
    Colour[pTRANSM] = Colour[pTRANSM] * Filter[pTRANSM];
  }
}
static void do_rainbow(RAY *Ray, INTERSECTION *Intersection, COLOUR Colour)
{
  int n;
  DBL dot, k, ki, index, x, y, l, angle, fade, f;
  VECTOR Temp;
  COLOUR Cr, Ct;
  RAINBOW *Rainbow;

  /* Why are we here. */

  if (Frame.Rainbow == NULL)
  {
    return;
  }

  Make_ColourA(Ct, 0.0, 0.0, 0.0, 1.0, 1.0);

  n = 0;

  for (Rainbow = Frame.Rainbow; Rainbow != NULL; Rainbow = Rainbow->Next)
  {
    if ((Rainbow->Pigment != NULL) && (Rainbow->Distance != 0.0) && (Rainbow->Width != 0.0))
    {
      /* Get angle between ray direction and rainbow's up vector. */

      VDot(x, Ray->Direction, Rainbow->Right_Vector);
      VDot(y, Ray->Direction, Rainbow->Up_Vector);

      l = Sqr(x) + Sqr(y);

      if (l > 0.0)
      {
        l = sqrt(l);

        y /= l;
      }

      angle = fabs(acos(y));

      if (angle <= Rainbow->Arc_Angle)
      {
        /* Get dot product between ray direction and antisolar vector. */

        VDot(dot, Ray->Direction, Rainbow->Antisolar_Vector);

        if (dot >= 0.0)
        {
          /* Get index ([0;1]) into rainbow's colour map. */

          index = (acos(dot) - Rainbow->Angle) / Rainbow->Width;

          /* Jitter index. */

          if (Rainbow->Jitter > 0.0)
          {
            index += (2.0 * FRAND() - 1.0) * Rainbow->Jitter;
          }

          if ((index >= 0.0) && (index <= 1.0 - EPSILON))
          {
            /* Get colour from rainbow's colour map. */

            Make_Vector(Temp, index, 0.0, 0.0);

            Compute_Pigment(Cr, Rainbow->Pigment, Temp, Intersection);

            /* Get fading value for falloff. */

            if ((Rainbow->Falloff_Width > 0.0) && (angle > Rainbow->Falloff_Angle))
            {
              fade = (angle - Rainbow->Falloff_Angle) / Rainbow->Falloff_Width;

              fade = (3.0 - 2.0 * fade) * fade * fade;
            }
            else
            {
              fade = 0.0;
            }

            /* Get attenuation factor due to distance. */

            k = exp(-Intersection->Depth / Rainbow->Distance);

            /* Colour's transm value is used as minimum attenuation value. */

            k = max(k, fade * (1.0 - Cr[pTRANSM]) + Cr[pTRANSM]);

            /* Now interpolate the colours. */

            ki = 1.0 - k;

            /* Attenuate filter value. */

            f = Cr[pFILTER] * ki;

            Ct[pRED]    += k * Colour[pRED]   * ((1.0 - f) + f * Cr[pRED])   + ki * Cr[pRED];
            Ct[pGREEN]  += k * Colour[pGREEN] * ((1.0 - f) + f * Cr[pGREEN]) + ki * Cr[pGREEN];
            Ct[pBLUE]   += k * Colour[pBLUE]  * ((1.0 - f) + f * Cr[pBLUE])  + ki * Cr[pBLUE];
            Ct[pFILTER] *= k * Cr[pFILTER];
            Ct[pTRANSM] *= k * Cr[pTRANSM];

            n++;
          }
        }
      }
    }
  }

  if (n > 0)
  {
    COLC tmp = 1.0 / n;

    Colour[pRED] = Ct[pRED] * tmp;
    Colour[pGREEN] = Ct[pGREEN] * tmp;
    Colour[pBLUE] = Ct[pBLUE] * tmp;

    Colour[pFILTER] *= Ct[pFILTER];
    Colour[pTRANSM] *= Ct[pTRANSM];
  }
}