31 #include <mesh/MeshStorage.h> 33 #include <cugar/linalg/vector.h> 38 struct __align__(8) UVBvh_node
40 typedef uint32_t Type;
41 const static uint32_t kLeaf = (1u << 31u);
42 const static uint32_t kInternal = 0x00000000u;
43 const static uint32_t kInvalid = uint32_t(-1);
44 const static uint32_t kIndexMask = ~(7u << 29u);
48 CUGAR_HOST_DEVICE UVBvh_node() {}
53 CUGAR_HOST_DEVICE UVBvh_node(
const Type type,
const uint32_t size,
const uint32_t index,
const uint32_t skip_node)
55 m_packed_data = (type | ((size-1) << 29) | index);
56 m_skip_node = skip_node;
61 CUGAR_HOST_DEVICE
bool is_leaf()
const {
return (m_packed_data & kLeaf) != 0u; }
65 CUGAR_HOST_DEVICE uint32_t get_index()
const {
return m_packed_data & kIndexMask; }
69 CUGAR_HOST_DEVICE uint32_t get_leaf_index()
const {
return m_packed_data & kIndexMask; }
73 CUGAR_HOST_DEVICE uint32_t get_child_count()
const {
return 1u + ((m_packed_data >> 29) & 3u); }
77 CUGAR_HOST_DEVICE uint32_t get_size()
const {
return 1u + ((m_packed_data >> 29) & 3u); }
82 CUGAR_HOST_DEVICE uint32_t get_child(
const uint32_t i)
const {
return get_index() + i; }
86 CUGAR_HOST_DEVICE uint32_t get_skip_node()
const {
return m_skip_node; }
88 uint32_t m_packed_data;
100 UVBvhView(
const UVBvh_node* _nodes = NULL,
const cugar::Bbox2f* _bboxes = NULL,
const uint32_t* _index = NULL) :
101 nodes(_nodes), bboxes(_bboxes), index(_index) {}
103 const UVBvh_node* nodes;
105 const uint32_t* index;
110 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
113 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
114 UVHit(
const uint32_t _triId,
const float _u,
const float _v) { triId = _triId; u = _u; v = _v; }
122 inline UVHit locate(
const UVBvhView& uvbvh,
const MeshView& mesh,
const uint32_t group_id,
const float2 st)
124 const MeshStorage::texture_triangle* triangle_indices =
reinterpret_cast<const MeshStorage::texture_triangle*
>(mesh.texture_indices);
125 const float2* triangle_data =
reinterpret_cast<const float2*
>(mesh.texture_data);
128 uint32_t node_index = group_id;
131 while (node_index != UVBvh_node::kInvalid)
134 const UVBvh_node node = uvbvh.nodes[node_index];
136 #define COMBINED_CHILDREN_TEST 137 #if defined(COMBINED_CHILDREN_TEST) 140 const uint32_t child_index = node.get_index();
142 const float4 child_bbox1 =
reinterpret_cast<const float4*
>(uvbvh.bboxes)[ child_index ];
143 const float4 child_bbox2 =
reinterpret_cast<const float4*
>(uvbvh.bboxes)[ child_index+1 ];
145 if (st.x >= child_bbox1.x && st.x <= child_bbox1.z &&
146 st.y >= child_bbox1.y && st.y <= child_bbox1.w)
148 node_index = child_index;
152 if (st.x >= child_bbox2.x && st.x <= child_bbox2.z &&
153 st.y >= child_bbox2.y && st.y <= child_bbox2.w)
155 node_index = child_index + 1;
161 const float4 node_bbox =
reinterpret_cast<const float4*
>(uvbvh.bboxes)[node_index];
163 if (st.x < node_bbox.x || st.x > node_bbox.z &&
164 st.y < node_bbox.y || st.y > node_bbox.w)
167 node_index = node.get_skip_node();
174 node_index = node.get_index();
181 const uint32_t leaf_begin = node.get_leaf_index();
182 const uint32_t leaf_end = leaf_begin + node.get_size();
184 for (uint32_t l = leaf_begin; l < leaf_end; ++l)
187 const uint32_t tri_idx = uvbvh.index[l];
188 const MeshStorage::texture_triangle tri = triangle_indices[ tri_idx ];
191 const float2 p1 = triangle_data[ tri.x ];
192 const float2 p2 = triangle_data[ tri.y ];
193 const float2 p0 = triangle_data[ tri.z ];
200 const double den = v0.x * v1.y - v1.x * v0.y;
201 const double inv_den = 1.0f / den;
202 const double u = (v2.x * v1.y - v1.x * v2.y) * inv_den;
203 const double v = (v0.x * v2.y - v2.x * v0.y) * inv_den;
209 const float den = v0.x * v1.y - v1.x * v0.y;
210 const float inv_den = 1.0f / den;
211 const float u = (v2.x * v1.y - v1.x * v2.y) * inv_den;
212 const float v = (v0.x * v2.y - v2.x * v0.y) * inv_den;
216 if (u >= 0.0f && v >= 0.0f && u + v <= 1.0f)
217 return UVHit( tri_idx,
float(u),
float(v) );
222 node_index = node.get_skip_node();
226 return UVHit(uint32_t(-1), -1.0f, -1.0f);
230 inline uint32 locate(
const UVBvhView& uvbvh,
const VTL* vtls,
const uint32_t prim_id,
const float2 uv)
233 const float2 st = make_float2( uv.x + prim_id, uv.y );
236 uint32_t node_index = 0u;
239 while (node_index != UVBvh_node::kInvalid)
242 const UVBvh_node node = uvbvh.nodes[node_index];
244 #define COMBINED_CHILDREN_TEST 245 #if defined(COMBINED_CHILDREN_TEST) 248 const uint32_t child_index = node.get_index();
250 const float4 child_bbox1 =
reinterpret_cast<const float4*
>(uvbvh.bboxes)[ child_index ];
251 const float4 child_bbox2 =
reinterpret_cast<const float4*
>(uvbvh.bboxes)[ child_index+1 ];
253 if (st.x >= child_bbox1.x && st.x <= child_bbox1.z &&
254 st.y >= child_bbox1.y && st.y <= child_bbox1.w)
256 node_index = child_index;
260 if (st.x >= child_bbox2.x && st.x <= child_bbox2.z &&
261 st.y >= child_bbox2.y && st.y <= child_bbox2.w)
263 node_index = child_index + 1;
269 const float4 node_bbox =
reinterpret_cast<const float4*
>(uvbvh.bboxes)[node_index];
271 if (st.x < node_bbox.x || st.x > node_bbox.z &&
272 st.y < node_bbox.y || st.y > node_bbox.w)
275 node_index = node.get_skip_node();
282 node_index = node.get_index();
289 const uint32_t leaf_begin = node.get_leaf_index();
290 const uint32_t leaf_end = leaf_begin + node.get_size();
292 for (uint32_t l = leaf_begin; l < leaf_end; ++l)
295 const uint32_t vtl_idx = uvbvh.index[l];
296 const VTL vtl = vtls[ vtl_idx ];
299 const float2 p1 = vtl.uv0;
300 const float2 p2 = vtl.uv1;
301 const float2 p0 = vtl.uv2;
308 const double den = v0.x * v1.y - v1.x * v0.y;
309 const double inv_den = 1.0f / den;
310 const double u = (v2.x * v1.y - v1.x * v2.y) * inv_den;
311 const double v = (v0.x * v2.y - v2.x * v0.y) * inv_den;
317 const float den = v0.x * v1.y - v1.x * v0.y;
318 const float inv_den = 1.0f / den;
319 const float u = (v2.x * v1.y - v1.x * v2.y) * inv_den;
320 const float v = (v0.x * v2.y - v2.x * v0.y) * inv_den;
324 if (u >= 0.0f && v >= 0.0f && u + v <= 1.0f)
330 node_index = node.get_skip_node();
Definition: uv_bvh_view.h:108
Defines an axis-aligned bounding box class.
Definition: MeshView.h:96
Definition: uv_bvh_view.h:97