void PhotonEstimationTask::SearchThroughObjectsEstimatePhotons(vector<ObjectPtr>& Objects, LightSource *Light) { ViewThreadData *renderDataPtr = GetViewDataPtr(); shared_ptr<SceneData> sceneData = GetSceneData(); /* check this object and all siblings */ for(vector<ObjectPtr>::iterator Sib = Objects.begin(); Sib != Objects.end(); Sib++) { if(Test_Flag((*Sib), PH_TARGET_FLAG) && !((*Sib)->Type & LIGHT_SOURCE_OBJECT)) { /* do not shoot photons if global lights are turned off for ObjectPtr */ if(!Test_Flag((*Sib), NO_GLOBAL_LIGHTS_FLAG)) { EstimatePhotonsForObjectAndLight((*Sib), Light); } Cooperate(); } /* if it has children, check them too */ else if(((*Sib)->Type & IS_COMPOUND_OBJECT)) { SearchThroughObjectsEstimatePhotons(((CSG *)(*Sib))->children, Light); } } }
bool Sphere::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const { DBL OCSquared; Vector3d Origin_To_Center; if(Do_Ellipsoid) { DBL OCSquared; Vector3d New_Point; /* Transform the point into the sphere's space */ MInvTransPoint(New_Point, IPoint, Trans); Origin_To_Center = Center - New_Point; OCSquared = Origin_To_Center.lengthSqr(); if (Test_Flag(this, INVERTED_FLAG)) return(OCSquared > Sqr(Radius)); else return(OCSquared < Sqr(Radius)); } else { Origin_To_Center = Center - IPoint; OCSquared = Origin_To_Center.lengthSqr(); if(Test_Flag(this, INVERTED_FLAG)) return(OCSquared > Sqr(Radius)); else return(OCSquared < Sqr(Radius)); } }
bool Sor::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const { int i; DBL r0, r; Vector3d P; SOR_SPLINE_ENTRY *Entry=NULL; /* Transform the point into the surface of revolution space. */ MInvTransPoint(P, IPoint, Trans); /* Test if we are inside the cylindrical bound. */ if ((P[Y] >= Height1) && (P[Y] <= Height2)) { r0 = P[X] * P[X] + P[Z] * P[Z]; /* Test if we are inside the cylindrical bound. */ if (r0 <= Sqr(Radius2)) { /* Now find the segment the point is in. */ for (i = 0; i < Number; i++) { Entry = &Spline->Entry[i]; if ((P[Y] >= Spline->BCyl->height[Spline->BCyl->entry[i].h1]) && (P[Y] <= Spline->BCyl->height[Spline->BCyl->entry[i].h2])) { break; } } /* Have we found any segment? */ if (i < Number) { r = P[Y] * (P[Y] * (P[Y] * Entry->A + Entry->B) + Entry->C) + Entry->D; if (r0 <= r) { /* We're inside. */ return(!Test_Flag(this, INVERTED_FLAG)); } } } } /* We're outside. */ return(Test_Flag(this, INVERTED_FLAG)); }
bool Lemon::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const { DBL OCSquared; DBL horizontal, vertical; bool INSide = false; Vector3d New_Point; MInvTransPoint(New_Point, IPoint, Trans); vertical = New_Point[Z]; if ((vertical >= 0.0) && (vertical <= 1.0)) { horizontal = sqrt(Sqr(New_Point[X]) + Sqr(New_Point[Y])); OCSquared = Sqr(horizontal - HorizontalPosition) + Sqr((vertical - VerticalPosition)); if (OCSquared < Sqr(inner_radius)) { INSide = true; } } if (Test_Flag(this, INVERTED_FLAG)) { return !INSide; } else { return INSide; } }
static void Transform_Smooth_Triangle(OBJECT *Object, TRANSFORM *Trans) { SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object; if (!Test_Flag(Object, DEGENERATE_FLAG)) { /* BEG ROSE This is useless, because Compute_Triange recalculates this anyway: MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans); END ROSE */ MTransPoint(Triangle->P1, Triangle->P1, Trans); MTransPoint(Triangle->P2, Triangle->P2, Trans); MTransPoint(Triangle->P3, Triangle->P3, Trans); /* BEG ROSE This code is definitely wrong: MTransPoint(Triangle->N1, Triangle->N1, Trans); MTransPoint(Triangle->N2, Triangle->N2, Trans); MTransPoint(Triangle->N3, Triangle->N3, Trans); Bug fix for this: */ MTransNormal(Triangle->N1,Triangle->N1,Trans); MTransNormal(Triangle->N2,Triangle->N2,Trans); MTransNormal(Triangle->N3,Triangle->N3,Trans); /* END ROSE */ Compute_Triangle((TRIANGLE *)Triangle, true); } }
bool Fractal::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const { bool Result; Vector3d New_Point; if (Trans != NULL) { MInvTransPoint(New_Point, IPoint, Trans); Result = Iteration(New_Point, this, Thread->Fractal_IStack); } else { Result = Iteration(IPoint, this, Thread->Fractal_IStack); } if (Test_Flag(this, INVERTED_FLAG)) { return (!Result); } else { return (Result); } }
static void Rotate_Triangle(OBJECT *Object, VECTOR, TRANSFORM *Trans) { if (!Test_Flag(Object, DEGENERATE_FLAG)) { Transform_Triangle(Object, Trans); } }
static void Scale_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM * /*Trans*/) { /*DBL Length;*/ TRIANGLE *Triangle = (TRIANGLE *)Object; if (!Test_Flag(Object, DEGENERATE_FLAG)) { /* BEG ROSE this is useless, because Compute_Triangle recalculates this anyway: Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X]; Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y]; Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z]; VLength(Length, Triangle->Normal_Vector); VInverseScaleEq(Triangle->Normal_Vector, Length); Triangle->Distance /= Length; END ROSE */ VEvaluateEq(Triangle->P1, Vector); VEvaluateEq(Triangle->P2, Vector); VEvaluateEq(Triangle->P3, Vector); Compute_Triangle(Triangle, false); } }
void Transform_Object (ObjectPtr Object, const TRANSFORM *Trans) { if (Object == NULL) return; for(vector<ObjectPtr>::iterator Sib = Object->Bound.begin(); Sib != Object->Bound.end(); Sib++) { Transform_Object(*Sib, Trans); } if (Object->Clip != Object->Bound) { for(vector<ObjectPtr>::iterator Sib = Object->Clip.begin(); Sib != Object->Clip.end(); Sib++) { Transform_Object(*Sib, Trans); } } /* NK 1998 added if */ if (!Test_Flag(Object, UV_FLAG)) { Transform_Textures(Object->Texture, Trans); Transform_Textures(Object->Interior_Texture, Trans); } if(Object->interior != NULL) Object->interior->Transform(Trans); Object->Transform(Trans); }
void Scale_Object (ObjectPtr Object, const VECTOR Vector, const TRANSFORM *Trans) { if (Object == NULL) return; for(vector<ObjectPtr>::iterator Sib = Object->Bound.begin(); Sib != Object->Bound.end(); Sib++) { Scale_Object(*Sib, Vector, Trans); } if (Object->Clip != Object->Bound) { for(vector<ObjectPtr>::iterator Sib = Object->Clip.begin(); Sib != Object->Clip.end(); Sib++) Scale_Object(*Sib, Vector, Trans); } /* NK 1998 added if */ if (!Test_Flag(Object, UV_FLAG)) { Transform_Textures(Object->Texture, Trans); Transform_Textures(Object->Interior_Texture, Trans); } if (Object->UV_Trans == NULL) Object->UV_Trans = Create_Transform(); Compose_Transforms(Object->UV_Trans, Trans); if(Object->interior != NULL) Object->interior->Transform(Trans); Object->Scale(Vector, Trans); }
void Triangle::Rotate(const Vector3d&, const TRANSFORM *tr) { if (!Test_Flag(this, DEGENERATE_FLAG)) { Transform(tr); } }
static void project_object(PROJECT *Project, OBJECT *Object, int Axis, VECTOR Origin, int proj_thru, PROJECT *proj_proj) { int visible, Number; VECTOR Points[8]; /* Do not project infinite objects (always visible!) */ if (Test_Flag(Object, INFINITE_FLAG)) { Project->x1 = Project->y1 = MIN_BUFFER_ENTRY; Project->x2 = Project->y2 = MAX_BUFFER_ENTRY; return; } /* Get points to project */ calc_points(Axis, Object, &Number, Points, Origin); visible = false; Project->x1 = Project->y1 = MAX_BUFFER_ENTRY; Project->x2 = Project->y2 = MIN_BUFFER_ENTRY; if (Number == 3) { project_triangle(Project, Points[0], Points[1], Points[2], &visible); } else { project_bbox(Project, Points, &visible); } if ( visible && proj_thru ) { visible = intersect_projects( Project, proj_proj ); if ( visible ) { if (Project->x1 < proj_proj->x1 ) Project->x1 = proj_proj->x1; if (Project->x2 > proj_proj->x2 ) Project->x2 = proj_proj->x2; if (Project->y1 < proj_proj->y1 ) Project->y1 = proj_proj->y1; if (Project->y2 > proj_proj->y2 ) Project->y2 = proj_proj->y2; } } if (!visible) { /* Object is invisible */ Project->x1 = Project->y1 = MAX_BUFFER_ENTRY; Project->x2 = Project->y2 = MIN_BUFFER_ENTRY; } else { /* We don't want to miss something */ Project->x1 -= 2; Project->x2 += 2; Project->y1 -= 2; Project->y2 += 2; } }
static int intersect_poylgon(RAY *Ray, POLYGON *Polyg, DBL *Depth) { DBL x, y, len; VECTOR p, d; /* Don't test degenerate polygons. */ if (Test_Flag(Polyg, DEGENERATE_FLAG)) { return(false); } Increase_Counter(stats[Ray_Polygon_Tests]); /* Transform the ray into the polygon space. */ MInvTransPoint(p, Ray->Initial, Polyg->Trans); MInvTransDirection(d, Ray->Direction, Polyg->Trans); VLength(len, d); VInverseScaleEq(d, len); /* Intersect ray with the plane in which the polygon lies. */ if (fabs(d[Z]) < ZERO_TOLERANCE) { return(false); } *Depth = -p[Z] / d[Z]; if ((*Depth < DEPTH_TOLERANCE) || (*Depth > Max_Distance)) { return(false); } /* Does the intersection point lie inside the polygon? */ x = p[X] + *Depth * d[X]; y = p[Y] + *Depth * d[Y]; if (in_polygon(Polyg->Data->Number, Polyg->Data->Points, x, y)) { Increase_Counter(stats[Ray_Polygon_Tests_Succeeded]); *Depth /= len; return (true); } else { return (false); } }
bool IsoSurface::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const { Vector3d New_Point; /* Transform the point into box space. */ if(Trans != NULL) MInvTransPoint(New_Point, IPoint, Trans); else New_Point = IPoint; if(!container->Inside(New_Point)) return (Test_Flag(this, INVERTED_FLAG)); if(Vector_Function(Thread->functionContext, New_Point) > 0) return (Test_Flag(this, INVERTED_FLAG)); /* Inside the box. */ return (!Test_Flag(this, INVERTED_FLAG)); }
void Triangle::Transform(const TRANSFORM *tr) { if(!Test_Flag(this, DEGENERATE_FLAG)) { MTransPoint(P1, P1, tr); MTransPoint(P2, P2, tr); MTransPoint(P3, P3, tr); Compute_Triangle(); } }
bool Superellipsoid::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const { DBL val; Vector3d P; /* Transform the point into the superellipsoid space. */ MInvTransPoint(P, IPoint, Trans); val = evaluate_superellipsoid(P); if (val < EPSILON) { return(!Test_Flag(this, INVERTED_FLAG)); } else { return(Test_Flag(this, INVERTED_FLAG)); } }
void Triangle::Scale(const Vector3d& Vector, const TRANSFORM *) { if(!Test_Flag(this, DEGENERATE_FLAG)) { P1 *= Vector; P2 *= Vector; P3 *= Vector; Compute_Triangle(); } }
void Triangle::Translate(const Vector3d& Vector, const TRANSFORM *) { if(!Test_Flag(this, DEGENERATE_FLAG)) { P1 += Vector; P2 += Vector; P3 += Vector; Compute_Triangle(); } }
void PhotonEstimationTask::EstimatePhotonsForObjectAndLight(ObjectPtr Object, LightSource *Light) { int mergedFlags=0; /* merged flags to see if we should shoot photons */ ViewThreadData *renderDataPtr = GetViewDataPtr(); /* first, check on various flags... make sure all is a go for this ObjectPtr */ LightTargetCombo combo(Light,Object); mergedFlags = combo.computeMergedFlags(); if (!( ((mergedFlags & PH_RFR_ON_FLAG) && !(mergedFlags & PH_RFR_OFF_FLAG)) || ((mergedFlags & PH_RFL_ON_FLAG) && !(mergedFlags & PH_RFL_OFF_FLAG)) )) /* it is a no-go for this object... bail out now */ return; if(!Object) return; ShootingDirection shootingDirection(Light,Object); shootingDirection.compute(); /* calculate the spacial separation (spread) */ renderDataPtr->photonSpread = combo.target->Ph_Density*GetSceneData()->photonSettings.surfaceSeparation; /* if rays aren't parallel, divide by dist so we get separation at a distance of 1 unit */ if (!combo.light->Parallel) { renderDataPtr->photonSpread /= shootingDirection.dist; } /* try to guess the number of photons */ DBL x=shootingDirection.rad / (combo.target->Ph_Density*GetSceneData()->photonSettings.surfaceSeparation); x=x*x*M_PI; if ( ((mergedFlags & PH_RFR_ON_FLAG) && !(mergedFlags & PH_RFR_OFF_FLAG)) && ((mergedFlags & PH_RFL_ON_FLAG) && !(mergedFlags & PH_RFL_OFF_FLAG)) ) { x *= 1.5; /* assume 2 times as many photons with both reflection & refraction */ } if ( !Test_Flag(combo.target, PH_IGNORE_PHOTONS_FLAG) ) { if ( ((mergedFlags & PH_RFR_ON_FLAG) && !(mergedFlags & PH_RFR_OFF_FLAG)) ) { if ( ((mergedFlags & PH_RFL_ON_FLAG) && !(mergedFlags & PH_RFL_OFF_FLAG)) ) x *= 3; /* assume 3 times as many photons if ignore_photons not used */ else x *= 2; /* assume less for only refraction */ } } x *= 0.5; /* assume 1/2 of photons hit target ObjectPtr */ photonCountEstimate += x; }
bool Disc::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const { Vector3d New_Point; /* Transform the point into the discs space */ MInvTransPoint(New_Point, IPoint, Trans); if (New_Point[Z] >= 0.0) { /* We are outside. */ return (Test_Flag(this, INVERTED_FLAG)); } else { /* We are inside. */ return (!Test_Flag(this, INVERTED_FLAG)); } }
static int Inside_Disc (VECTOR IPoint, OBJECT *Object) { VECTOR New_Point; DISC *disc = (DISC *) Object; /* Transform the point into the discs space */ MInvTransPoint(New_Point, IPoint, disc->Trans); if (New_Point[Z] >= 0.0) { /* We are outside. */ return (Test_Flag(disc, INVERTED_FLAG)); } else { /* We are inside. */ return (!Test_Flag(disc, INVERTED_FLAG)); } }
bool Torus::Inside(const VECTOR IPoint, TraceThreadData *Thread) const { DBL r, r2; VECTOR P; /* Transform the point into the torus space. */ MInvTransPoint(P, IPoint, Trans); r = sqrt(Sqr(P[X]) + Sqr(P[Z])); r2 = Sqr(P[Y]) + Sqr(r - MajorRadius); if (r2 <= Sqr(MinorRadius)) { return(!Test_Flag(this, INVERTED_FLAG)); } else { return(Test_Flag(this, INVERTED_FLAG)); } }
static int Inside_Box(VECTOR IPoint, OBJECT *Object) { VECTOR New_Point; BOX *box = (BOX *) Object; /* Transform the point into box space. */ if (box->Trans != NULL) { MInvTransPoint(New_Point, IPoint, box->Trans); } else { Assign_Vector(New_Point,IPoint); } /* Test to see if we are outside the box. */ if ((New_Point[X] < box->bounds[0][X]) || (New_Point[X] > box->bounds[1][X])) { return (Test_Flag(box, INVERTED_FLAG)); } if ((New_Point[Y] < box->bounds[0][Y]) || (New_Point[Y] > box->bounds[1][Y])) { return (Test_Flag(box, INVERTED_FLAG)); } if ((New_Point[Z] < box->bounds[0][Z]) || (New_Point[Z] > box->bounds[1][Z])) { return (Test_Flag(box, INVERTED_FLAG)); } /* Inside the box. */ return (!Test_Flag(box, INVERTED_FLAG)); }
SceneObjects(vector<ObjectPtr>& objects) { numLights = 0; for(vector<ObjectPtr>::iterator i(objects.begin()); i != objects.end(); i++) { if(Test_Flag((*i), INFINITE_FLAG)) { infinite.push_back(*i); if (((*i)->Type & LIGHT_SOURCE_OBJECT) != 0) numLights++; } else finite.push_back(*i); } }
bool SpindleTorus::Inside(const Vector3d& IPoint, TraceThreadData *Thread) const { DBL r, r2; Vector3d P; bool inside; /* Transform the point into the torus space. */ MInvTransPoint(P, IPoint, Trans); r = sqrt(Sqr(P[X]) + Sqr(P[Z])); r2 = Sqr(P[Y]) + Sqr(r - MajorRadius); if (r2 <= Sqr(MinorRadius)) { if (mSpindleMode & SpindleRelevantForInside) { bool insideSpindle = ( Sqr(P[Y]) + Sqr(r + MajorRadius) <= Sqr(MinorRadius) ); if (mSpindleMode & SpindleInside) inside = insideSpindle; else inside = !insideSpindle; } else inside = true; } else inside = false; if (inside) return(!Test_Flag(this, INVERTED_FLAG)); else return(Test_Flag(this, INVERTED_FLAG)); }
bool Polygon::Intersect(const BasicRay& ray, DBL *Depth, TraceThreadData *Thread) const { DBL x, y, len; Vector3d p, d; /* Don't test degenerate polygons. */ if (Test_Flag(this, DEGENERATE_FLAG)) return(false); Thread->Stats()[Ray_Polygon_Tests]++; /* Transform the ray into the polygon space. */ MInvTransPoint(p, ray.Origin, Trans); MInvTransDirection(d, ray.Direction, Trans); len = d.length(); d /= len; /* Intersect ray with the plane in which the polygon lies. */ if (fabs(d[Z]) < ZERO_TOLERANCE) return(false); *Depth = -p[Z] / d[Z]; if ((*Depth < DEPTH_TOLERANCE) || (*Depth > MAX_DISTANCE)) return(false); /* Does the intersection point lie inside the polygon? */ x = p[X] + *Depth * d[X]; y = p[Y] + *Depth * d[Y]; if (in_polygon(Data->Number, Data->Points, x, y)) { Thread->Stats()[Ray_Polygon_Tests_Succeeded]++; *Depth /= len; return (true); } else return (false); }
static void Transform_Triangle(OBJECT *Object, TRANSFORM *Trans) { TRIANGLE *Triangle = (TRIANGLE *)Object; if (!Test_Flag(Object, DEGENERATE_FLAG)) { /* ROSE BEG this is useless, because Compute_Triangle recalculates this anyway: MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans); END ROSE */ MTransPoint(Triangle->P1, Triangle->P1, Trans); MTransPoint(Triangle->P2, Triangle->P2, Trans); MTransPoint(Triangle->P3, Triangle->P3, Trans); Compute_Triangle(Triangle, false); } }
void SmoothTriangle::Scale(const Vector3d& Vector, const TRANSFORM *) { if(!Test_Flag(this, DEGENERATE_FLAG)) { P1 *= Vector; P2 *= Vector; P3 *= Vector; N1 /= Vector; N1.normalize(); N2 /= Vector; N2.normalize(); N3 /= Vector; N3.normalize(); Compute_Triangle(); } }
static void Cone_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter) { CONE *Cone = (CONE *)Object; /* Transform the point into the cones space */ MInvTransPoint(Result, Inter->IPoint, Cone->Trans); /* Calculating the normal is real simple in canonical cone space */ switch (Inter->i1) { case SIDE_HIT: if (Test_Flag(Cone, CYLINDER_FLAG)) { Result[Z] = 0.0; } else { Result[Z] = -Result[Z]; } break; case BASE_HIT: Make_Vector(Result, 0.0, 0.0, -1.0); break; case CAP_HIT: Make_Vector(Result, 0.0, 0.0, 1.0); break; } /* Transform the point out of the cones space */ MTransNormal(Result, Result, Cone->Trans); VNormalize(Result, Result); }
static void Scale_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM * /*Trans*/) { DBL Length; SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object; if (!Test_Flag(Object, DEGENERATE_FLAG)) { /* BEG ROSE this is useless, because Compute_Triange recalculates this anyway: Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X]; Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y]; Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z]; VLength(Length, Triangle->Normal_Vector); VScaleEq(Triangle->Normal_Vector, 1.0 / Length); Triangle->Distance /= Length; END ROSE */ VEvaluateEq(Triangle->P1, Vector); VEvaluateEq(Triangle->P2, Vector); VEvaluateEq(Triangle->P3, Vector); /* BEG ROSE The normal vectors also have to be transformed (BUG fix): */ Triangle->N1[X] /= Vector[X]; Triangle->N1[Y] /= Vector[Y]; Triangle->N1[Z] /= Vector[Z]; VLength(Length,Triangle->N1); VScaleEq(Triangle->N1,1.0/Length); Triangle->N2[X] /= Vector[X]; Triangle->N2[Y] /= Vector[Y]; Triangle->N2[Z] /= Vector[Z]; VLength(Length,Triangle->N2); VScaleEq(Triangle->N2,1.0/Length); Triangle->N3[X] /= Vector[X]; Triangle->N3[Y] /= Vector[Y]; Triangle->N3[Z] /= Vector[Z]; VLength(Length,Triangle->N3); VScaleEq(Triangle->N3,1.0/Length); /* END ROSE */ Compute_Triangle((TRIANGLE *)Triangle,true); } }