static DBL Do_Slope_Map (DBL value, const BLEND_MAP *Blend_Map) { DBL Result; BLEND_MAP_ENTRY *Prev, *Cur; if (Blend_Map == NULL) { return(value); } Search_Blend_Map (value,Blend_Map,&Prev,&Cur); if (Prev == Cur) { return(Cur->Vals.Point_Slope[0]); } Result = (value-Prev->value)/(Cur->value-Prev->value); return(Hermite_Cubic(Result, Prev->Vals.Point_Slope, Cur->Vals.Point_Slope)); }
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); }
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 */ }
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); }