static void merge_spheres(VECTOR C, DBL *r, VECTOR C1, DBL r1, VECTOR C2, DBL r2) { DBL l, r1r, r2r, k1, k2; VECTOR D; VSub(D, C1, C2); VLength(l, D); /* Check if one sphere encloses the other. */ r1r = sqrt(r1); r2r = sqrt(r2); if (l + r1r <= r2r) { Assign_Vector(C, C2); *r = r2; return; } if (l + r2r <= r1r) { Assign_Vector(C, C1); *r = r1; return; } k1 = (1.0 + (r1r - r2r) / l) / 2.0; k2 = (1.0 + (r2r - r1r) / l) / 2.0; VLinComb2(C, k1, C1, k2, C2); *r = Sqr((l + r1r + r2r) / 2.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 */ }
static DBL ground_fog(RAY *Ray, DBL Depth, DBL Width, FOG *Fog, COLOUR Colour) { DBL fog_density, delta; DBL start, end; DBL y1, y2, k; VECTOR P, P1, P2; /* Get start point. */ VEvaluateRay(P1, Ray->Initial, Depth, Ray->Direction); /* Get end point. */ VLinComb2(P2, 1.0, P1, Width, Ray->Direction); /* * Could preform transfomation here to translate Start and End * points into ground fog space. */ VDot(y1, P1, Fog->Up); VDot(y2, P2, Fog->Up); start = (y1 - Fog->Offset) / Fog->Alt; end = (y2 - Fog->Offset) / Fog->Alt; /* Get integral along y-axis from start to end. */ if (start <= 0.0) { if (end <= 0.0) { fog_density = 1.0; } else { fog_density = (atan(end) - start) / (end - start); } } else { if (end <= 0.0) { fog_density = (atan(start) - end) / (start - end); } else { delta = start - end; if (fabs(delta) > EPSILON) { fog_density = (atan(start) - atan(end)) / delta; } else { fog_density = 1.0 / (Sqr(start) + 1.0); } } } /* Apply turbulence. */ if (Fog->Turb != NULL) { VHalf(P, P1, P2); VEvaluateEq(P, Fog->Turb->Turbulence); /* The further away the less influence turbulence has. */ k = exp(-Width / Fog->Distance); Width *= 1.0 - k * min(1.0, Turbulence(P, Fog->Turb, NULL)*Fog->Turb_Depth); } Assign_Colour(Colour, Fog->Colour); return (exp(-Width * fog_density / Fog->Distance)); }