int BicubicPatch::bezier_subpatch_intersect(const BasicRay &ray, const ControlPoints *Patch, DBL u0, DBL u1, DBL v0, DBL v1, IStack& Depth_Stack, TraceThreadData *Thread) { int cnt = 0; TripleVector3d V1; DBL u, v, Depth; DBL uu[3], vv[3]; Vector3d P, N; Vector2d UV; Vector2d uv_point, tpoint; V1[0] = (*Patch)[0][0]; V1[1] = (*Patch)[0][3]; V1[2] = (*Patch)[3][3]; uu[0] = u0; uu[1] = u0; uu[2] = u1; vv[0] = v0; vv[1] = v1; vv[2] = v1; 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] = (*Patch)[3][0]; uu[1] = uu[2]; uu[2] = u1; vv[1] = vv[2]; vv[2] = v0; 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++; } } return (cnt); }
static int bezier_subpatch_intersect(RAY *ray, BICUBIC_PATCH *Shape, VECTOR (*Patch)[4][4], DBL u0, DBL u1, DBL v0, DBL v1, ISTACK *Depth_Stack) { int cnt = 0; VECTOR V1[3]; DBL u, v, Depth; DBL uu[3], vv[3]; VECTOR P, N; UV_VECT UV; DBL uv_point[2], tpoint[2]; Assign_Vector(V1[0], (*Patch)[0][0]); Assign_Vector(V1[1], (*Patch)[0][3]); Assign_Vector(V1[2], (*Patch)[3][3]); uu[0] = u0; uu[1] = u0; uu[2] = u1; vv[0] = v0; vv[1] = v1; vv[2] = v1; 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], (*Patch)[3][0]); uu[1] = uu[2]; uu[2] = u1; vv[1] = vv[2]; vv[2] = v0; 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++; } return (cnt); }
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); }