summaryrefslogtreecommitdiff
path: root/src/mesh.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh.h')
-rw-r--r--src/mesh.h273
1 files changed, 125 insertions, 148 deletions
diff --git a/src/mesh.h b/src/mesh.h
index f466470..0622144 100644
--- a/src/mesh.h
+++ b/src/mesh.h
@@ -2,187 +2,164 @@
#define __MESH_H__
#include "intersect.h"
+#include "geometry.h"
#define STACK_SIZE 500
-/* flattened triangle mesh */
-__device__ float3 *g_vertices;
-__device__ uint4 *g_triangles;
-__device__ unsigned int *g_colors;
-__device__ unsigned int g_start_node;
-__device__ unsigned int g_first_node;
-
-/* lower/upper bounds for the bounding box associated with each node/leaf */
-__device__ float3 *g_lower_bounds;
-__device__ float3 *g_upper_bounds;
-
-/* map to child node/triangle indices */
-texture<unsigned int, 1, cudaReadModeElementType> node_map;
-texture<unsigned int, 1, cudaReadModeElementType> node_map_end;
-
-__device__ float3 make_float3(const float4 &a)
+/* Tests the intersection between a ray and a node in the bounding volume
+ hierarchy. If the ray intersects the bounding volume and `min_distance`
+ is less than zero or the distance from `origin` to the intersection is
+ less than `min_distance`, return true, else return false. */
+__device__ bool
+intersect_node(const float3 &origin, const float3 &direction,
+ Geometry *geometry, const int &i, const float &min_distance)
{
- return make_float3(a.x, a.y, a.z);
-}
+ /* assigning these to local variables is faster for some reason */
+ float3 lower_bound = geometry->lower_bounds[i];
+ float3 upper_bound = geometry->upper_bounds[i];
-__device__ int convert(int c)
-{
- if (c & 0x80)
- return (0xFFFFFF00 | c);
- else
- return c;
-}
+ float distance_to_box;
-/* Test the intersection between a ray starting at `origin` traveling in the
- direction `direction` and the bounding box around node `i`. If the ray
- intersects the bounding box return true, else return false. */
-__device__ bool intersect_node(const float3 &origin, const float3 &direction, const int &i, const float &min_distance)
-{
- float3 lower_bound = g_lower_bounds[i];
- float3 upper_bound = g_upper_bounds[i];
+ if (intersect_box(origin, direction, lower_bound, upper_bound,
+ distance_to_box)) {
+ if (min_distance < 0.0f)
+ return true;
- float distance_to_box;
+ if (distance_to_box > min_distance)
+ return false;
- if (intersect_box(origin, direction, lower_bound, upper_bound, distance_to_box))
- {
- if (min_distance < 0.0f)
- return true;
+ return true;
+ }
+ else {
+ return false;
+ }
- if (distance_to_box > min_distance)
- return false;
-
- return true;
- }
- else
- {
- return false;
- }
-
-} // intersect_node
+}
-/* Find the intersection between a ray starting at `origin` traveling in the
- direction `direction` and the global mesh texture. If the ray intersects
- the texture return the index of the triangle which the ray intersected,
- else return -1. */
-__device__ int intersect_mesh(const float3 &origin, const float3& direction, float &min_distance, int last_hit_triangle = -1)
+/* Finds the intersection between a ray and `geometry`. If the ray does
+ intersect the mesh and the index of the intersected triangle is not equal
+ to `last_hit_triangle`, set `min_distance` to the distance from `origin` to
+ the intersection and return the index of the triangle which the ray
+ intersected, else return -1. */
+__device__ int
+intersect_mesh(const float3 &origin, const float3& direction,
+ Geometry *geometry, float &min_distance,
+ int last_hit_triangle = -1)
{
- int triangle_index = -1;
+ int triangle_index = -1;
- float distance;
- min_distance = -1.0f;
+ float distance;
+ min_distance = -1.0f;
- if (!intersect_node(origin, direction, g_start_node, min_distance))
- return -1;
+ if (!intersect_node(origin, direction, geometry, geometry->start_node,
+ min_distance))
+ return -1;
- unsigned int stack[STACK_SIZE];
+ unsigned int stack[STACK_SIZE];
- unsigned int *head = &stack[0];
- unsigned int *node = &stack[1];
- unsigned int *tail = &stack[STACK_SIZE-1];
- *node = g_start_node;
+ unsigned int *head = &stack[0];
+ unsigned int *node = &stack[1];
+ unsigned int *tail = &stack[STACK_SIZE-1];
+ *node = geometry->start_node;
- unsigned int i;
+ unsigned int i;
- do
- {
- unsigned int first_child = tex1Dfetch(node_map, *node);
- unsigned int stop = tex1Dfetch(node_map_end, *node);
+ do
+ {
+ unsigned int first_child = geometry->node_map[*node];
+ unsigned int stop = geometry->node_map_end[*node];
- while (*node >= g_first_node && stop == first_child+1)
- {
- *node = first_child;
- first_child = tex1Dfetch(node_map, *node);
- stop = tex1Dfetch(node_map_end, *node);
- }
+ while (*node >= geometry->first_node && stop == first_child+1) {
+ *node = first_child;
+ first_child = geometry->node_map[*node];
+ stop = geometry->node_map_end[*node];
+ }
- if (*node >= g_first_node)
- {
- for (i=first_child; i < stop; i++)
- {
- if (intersect_node(origin, direction, i, min_distance))
- {
- *node = i;
- node++;
- }
- }
-
- node--;
+ if (*node >= geometry->first_node) {
+ for (i=first_child; i < stop; i++) {
+ if (intersect_node(origin, direction, geometry, i,
+ min_distance)) {
+ *node = i;
+ node++;
+ }
+ }
+
+ node--;
+ }
+ else {
+ // node is a leaf
+ for (i=first_child; i < stop; i++) {
+ if (last_hit_triangle == i)
+ continue;
+
+ Triangle triangle = get_triangle(geometry, i);
+
+ if (intersect_triangle(origin, direction, triangle,
+ distance)) {
+ if (triangle_index == -1) {
+ triangle_index = i;
+ min_distance = distance;
+ continue;
+ }
+
+ if (distance < min_distance) {
+ triangle_index = i;
+ min_distance = distance;
+ }
}
- else // node is a leaf
- {
- for (i=first_child; i < stop; i++)
- {
- if (last_hit_triangle == i)
- continue;
-
- uint4 triangle_data = g_triangles[i];
-
- float3 v0 = g_vertices[triangle_data.x];
- float3 v1 = g_vertices[triangle_data.y];
- float3 v2 = g_vertices[triangle_data.z];
-
- if (intersect_triangle(origin, direction, v0, v1, v2, distance))
- {
- if (triangle_index == -1)
- {
- triangle_index = i;
- min_distance = distance;
- continue;
- }
-
- if (distance < min_distance)
- {
- triangle_index = i;
- min_distance = distance;
- }
- }
- } // triangle loop
-
- node--;
-
- } // node is a leaf
-
- } // while loop
- while (node != head);
-
- return triangle_index;
+ } // triangle loop
+
+ node--;
+
+ } // node is a leaf
+
+ } // while loop
+ while (node != head);
+
+ return triangle_index;
}
extern "C"
{
-__global__ void set_global_mesh_variables(uint4 *triangles, float3 *vertices, unsigned int *colors, unsigned int start_node, unsigned int first_node, float3 *lower_bounds, float3 *upper_bounds)
+__global__ void
+distance_to_mesh(int nthreads, float3 *positions, float3 *directions,
+ Geometry *g, float *distances)
{
- g_triangles = triangles;
- g_vertices = vertices;
- g_colors = colors;
- g_start_node = start_node;
- g_first_node = first_node;
- g_lower_bounds = lower_bounds;
- g_upper_bounds = upper_bounds;
-}
+ int id = blockIdx.x*blockDim.x + threadIdx.x;
-__global__ void set_colors(unsigned int *colors)
-{
- g_colors = colors;
+ if (id >= nthreads)
+ return;
+
+ float3 position = positions[id];
+ float3 direction = directions[id];
+ direction /= norm(direction);
+
+ float distance;
+
+ int triangle_index = intersect_mesh(position, direction, g, distance);
+
+ if (triangle_index == -1)
+ distances[id] = 1e9;
+ else
+ distances[id] = distance;
}
-__global__ void color_solids(int first_triangle, int nthreads,
- int *solid_id_map,
- bool *solid_hit,
- unsigned int *solid_colors)
+__global__ void
+color_solids(int first_triangle, int nthreads, int *solid_id_map,
+ bool *solid_hit, unsigned int *solid_colors, Geometry *geometry)
{
- int id = blockIdx.x*blockDim.x + threadIdx.x;
+ int id = blockIdx.x*blockDim.x + threadIdx.x;
- if (id >= nthreads)
- return;
+ if (id >= nthreads)
+ return;
- int triangle_id = first_triangle + id;
- int solid_id = solid_id_map[triangle_id];
- if (solid_hit[solid_id])
- g_colors[triangle_id] = solid_colors[solid_id];
+ int triangle_id = first_triangle + id;
+ int solid_id = solid_id_map[triangle_id];
+ if (solid_hit[solid_id])
+ geometry->colors[triangle_id] = solid_colors[solid_id];
}
-} // extern "c"
+} // extern "C"
#endif