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; }
PIGMENT *Create_Pigment () { PIGMENT *New; New = (PIGMENT *)POV_MALLOC(sizeof (PIGMENT), "pigment"); Init_TPat_Fields((TPATTERN *)New); Make_Colour(New->Colour, 0.0,0.0,0.0) ; New->Blend_Map = NULL; return (New); }
INTERIOR *Create_Interior() { INTERIOR *New; New = (INTERIOR *)POV_MALLOC(sizeof(INTERIOR), "interior"); New->References = 1; New->IOR = 0.0; New->Old_Refract = 1.0; New->Dispersion = 1.0; New->Disp_NElems = DEFAULT_DISP_NELEMS; New->Caustics = 0.0; New->Fade_Distance = 0.0; New->Fade_Power = 0.0; Make_Colour(New->Fade_Colour, 0.0, 0.0, 0.0); New->IMedia = NULL; return(New); }
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); }
int Post_Pigment(PIGMENT *Pigment) { int i, Has_Filter; BLEND_MAP *Map; if (Pigment == NULL) { Error("Missing pigment"); } if (Pigment->Flags & POST_DONE) { return(Pigment->Flags & HAS_FILTER); } if (Pigment->Type == NO_PATTERN) { Pigment->Type = PLAIN_PATTERN; Make_Colour(Pigment->Colour, 0.0, 0.0, 0.0) ; Warning(150, "No pigment type given."); } Pigment->Flags |= POST_DONE; switch (Pigment->Type) { case PLAIN_PATTERN: Destroy_Warps (Pigment->Warps); Pigment->Warps = NULL; break; case NO_PATTERN: case BITMAP_PATTERN: break; default: if (Pigment->Blend_Map == NULL) { switch (Pigment->Type) { case BOZO_PATTERN: Pigment->Blend_Map = &Bozo_Default_Map; break; case BRICK_PATTERN: Pigment->Blend_Map = &Brick_Default_Map; break; case WOOD_PATTERN: Pigment->Blend_Map = &Wood_Default_Map; break; case MANDEL_PATTERN: Pigment->Blend_Map = &Mandel_Default_Map;break; case RADIAL_PATTERN: Pigment->Blend_Map = &Radial_Default_Map;break; case AGATE_PATTERN: Pigment->Blend_Map = &Agate_Default_Map; break; case MARBLE_PATTERN: Pigment->Blend_Map = &Marble_Default_Map;break; case HEXAGON_PATTERN: Pigment->Blend_Map = &Hex_Default_Map; break; case CHECKER_PATTERN: Pigment->Blend_Map = &Check_Default_Map; break; case AVERAGE_PATTERN: Error("Missing pigment_map in average pigment"); break; case OBJECT_PATTERN: Pigment->Blend_Map = &Check_Default_Map; break; default: Pigment->Blend_Map = &Gray_Default_Map; break; } } break; } /* Now we test wether this pigment is opaque or not. [DB 8/94] */ Has_Filter = false; if ((fabs(Pigment->Colour[pFILTER]) > EPSILON) || (fabs(Pigment->Colour[pTRANSM]) > EPSILON)) { Has_Filter = true; } if ((Map = Pigment->Blend_Map) != NULL) { if ((Map->Type == PIGMENT_TYPE) || (Map->Type == DENSITY_TYPE)) { for (i = 0; i < Map->Number_Of_Entries; i++) { Has_Filter |= Post_Pigment(Map->Blend_Map_Entries[i].Vals.Pigment); } } else { for (i = 0; i < Map->Number_Of_Entries; i++) { Has_Filter |= fabs(Map->Blend_Map_Entries[i].Vals.Colour[pFILTER])>EPSILON; Has_Filter |= fabs(Map->Blend_Map_Entries[i].Vals.Colour[pTRANSM])>EPSILON; } } } if (Has_Filter) { Pigment->Flags |= HAS_FILTER; } if (Pigment->Next != NULL) { Post_Pigment((PIGMENT *)Pigment->Next); } return(Has_Filter); }
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]; } }