bool BicubicPatch::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { int Found, cnt = 0; Found = false; Thread->Stats()[Ray_Bicubic_Tests]++; switch (Patch_Type) { case 0: cnt = intersect_bicubic_patch0(ray, Depth_Stack, Thread); break; case 1: cnt = bezier_tree_walker(ray, Node_Tree, Depth_Stack, Thread); break; default: throw POV_EXCEPTION_STRING("Bad patch type in All_Bicubic_Patch_Intersections."); } if (cnt > 0) { Thread->Stats()[Ray_Bicubic_Tests_Succeeded]++; Found = true; } return (Found); }
static int All_Bicubic_Patch_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack) { int Found, cnt = 0; Found = false; Increase_Counter(stats[Ray_Bicubic_Tests]); switch (((BICUBIC_PATCH *)Object)->Patch_Type) { case 0: cnt = intersect_bicubic_patch0(Ray, ((BICUBIC_PATCH *)Object), Depth_Stack); break; case 1: cnt = bezier_tree_walker(Ray, (BICUBIC_PATCH *)Object, ((BICUBIC_PATCH *)Object)->Node_Tree, Depth_Stack); break; default: Error("Bad patch type in All_Bicubic_Patch_Intersections."); } if (cnt > 0) { Increase_Counter(stats[Ray_Bicubic_Tests_Succeeded]); Found = true; } return (Found); }
int BicubicPatch::bezier_tree_walker(const BasicRay &ray, const BEZIER_NODE *Node, IStack& Depth_Stack, TraceThreadData *Thread) { int i, cnt = 0; DBL Depth, u, v; DBL uu[3], vv[3]; Vector3d N, P; TripleVector3d V1; Vector2d UV; Vector2d uv_point, tpoint; const BEZIER_CHILDREN *Children; const BEZIER_VERTICES *Vertices; /* * Make sure the ray passes through a sphere bounding * the control points of the patch. */ if (!spherical_bounds_check(ray, Node->Center, Node->Radius_Squared)) { return (0); } /* * If this is an interior node then continue the descent, * else do a check against the vertices. */ if (Node->Node_Type == BEZIER_INTERIOR_NODE) { Children = reinterpret_cast<const BEZIER_CHILDREN *>(Node->Data_Ptr); for (i = 0; i < Node->Count; i++) { cnt += bezier_tree_walker(ray, Children->Children[i], Depth_Stack, Thread); } } else if (Node->Node_Type == BEZIER_LEAF_NODE) { Vertices = reinterpret_cast<const BEZIER_VERTICES *>(Node->Data_Ptr); V1[0] = Vertices->Vertices[0]; V1[1] = Vertices->Vertices[1]; V1[2] = Vertices->Vertices[2]; uu[0] = Vertices->uvbnds[0]; uu[1] = Vertices->uvbnds[0]; uu[2] = Vertices->uvbnds[1]; vv[0] = Vertices->uvbnds[2]; vv[1] = Vertices->uvbnds[3]; vv[2] = Vertices->uvbnds[3]; /* * Triangulate this subpatch, then check for * intersections in the triangles. */ if (intersect_subpatch(ray, V1, uu, vv, &Depth, P, N, &u, &v)) { if (Clip.empty() || Point_In_Clip(P, Clip, Thread)) { /* transform current point from uv space to texture space */ uv_point[0] = v; uv_point[1] = u; Compute_Texture_UV(uv_point, ST, tpoint); UV[U] = tpoint[0]; UV[V] = tpoint[1]; Depth_Stack->push(Intersection(Depth, P, N, UV, this)); cnt++; } } V1[1] = V1[2]; V1[2] = Vertices->Vertices[3]; uu[1] = uu[2]; uu[2] = Vertices->uvbnds[1]; vv[1] = vv[2]; vv[2] = Vertices->uvbnds[2]; if (intersect_subpatch(ray, V1, uu, vv, &Depth, P, N, &u, &v)) { if (Clip.empty() || Point_In_Clip(P, Clip, Thread)) { /* transform current point from object space to texture space */ uv_point[0] = v; uv_point[1] = u; Compute_Texture_UV(uv_point, ST, tpoint); UV[U] = tpoint[0]; UV[V] = tpoint[1]; Depth_Stack->push(Intersection(Depth, P, N, UV, this)); cnt++; } } } else { throw POV_EXCEPTION_STRING("Bad Node type in bezier_tree_walker()."); } return (cnt); }
static int bezier_tree_walker(RAY *Ray, BICUBIC_PATCH *Shape, BEZIER_NODE *Node, ISTACK *Depth_Stack) { int i, cnt = 0; DBL Depth, u, v; DBL uu[3], vv[3]; VECTOR N, P; VECTOR V1[3]; UV_VECT UV; DBL uv_point[2], tpoint[2]; BEZIER_CHILDREN *Children; BEZIER_VERTICES *Vertices; /* * Make sure the ray passes through a sphere bounding * the control points of the patch. */ if (!spherical_bounds_check(Ray, Node->Center, Node->Radius_Squared)) { return (0); } /* * If this is an interior node then continue the descent, * else do a check against the vertices. */ if (Node->Node_Type == BEZIER_INTERIOR_NODE) { Children = (BEZIER_CHILDREN *)Node->Data_Ptr; for (i = 0; i < Node->Count; i++) { cnt += bezier_tree_walker(Ray, Shape, Children->Children[i], Depth_Stack); } } else if (Node->Node_Type == BEZIER_LEAF_NODE) { Vertices = (BEZIER_VERTICES *)Node->Data_Ptr; Assign_Vector(V1[0], Vertices->Vertices[0]); Assign_Vector(V1[1], Vertices->Vertices[1]); Assign_Vector(V1[2], Vertices->Vertices[2]); uu[0] = Vertices->uvbnds[0]; uu[1] = Vertices->uvbnds[0]; uu[2] = Vertices->uvbnds[1]; vv[0] = Vertices->uvbnds[2]; vv[1] = Vertices->uvbnds[3]; vv[2] = Vertices->uvbnds[3]; /* * Triangulate this subpatch, then check for * intersections in the triangles. */ if (intersect_subpatch(Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v)) { /* transform current point from uv space to texture space */ uv_point[0] = v; uv_point[1] = u; Compute_Texture_UV(uv_point, Shape->ST, tpoint); UV[U] = tpoint[0]; UV[V] = tpoint[1]; push_normal_uv_entry(Depth, P, N, UV, (OBJECT *)Shape, Depth_Stack); cnt++; } Assign_Vector(V1[1], V1[2]); Assign_Vector(V1[2], Vertices->Vertices[3]); uu[1] = uu[2]; uu[2] = Vertices->uvbnds[1]; vv[1] = vv[2]; vv[2] = Vertices->uvbnds[2]; if (intersect_subpatch(Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v)) { /* transform current point from object space to texture space */ uv_point[0] = v; uv_point[1] = u; Compute_Texture_UV(uv_point, Shape->ST, tpoint); UV[U] = tpoint[0]; UV[V] = tpoint[1]; push_normal_uv_entry(Depth, P, N, UV, (OBJECT *)Shape, Depth_Stack); cnt++; } } else { Error("Bad Node type in bezier_tree_walker()."); } return (cnt); }