mesh_datastructure.glsl 4.71 KB
Newer Older
1
2
#ifndef INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL
#define INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL
unknown's avatar
unknown committed
3

4
5
6
#include <pathtracer/buffers.glsl>
#include <util/scene/mesh.glsl>
#include <util/tracing/bvh_node.glsl>
unknown's avatar
unknown committed
7

8
9
#include <pathtracer/data/mesh_bvh.glsl>
#include <pathtracer/data/mesh_linespace.glsl>
unknown's avatar
unknown committed
10

11
uniform bool use_global_bvh;
unknown's avatar
unknown committed
12

13
bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false);
unknown's avatar
unknown committed
14

unknown's avatar
unknown committed
15
16
bool nearestIntersection(const in Ray ray, inout Hit hit, bool force_bvh = false)
{
17
18
	float t_min = FLT_MAX;
	return traverseObjects(ray, false, FLT_MAX, hit, t_min, force_bvh);
unknown's avatar
unknown committed
19
20
21
22
}

bool intersectsAny(const in Ray ray, const in float max_distance, bool force_bvh = false)
{
23
24
25
	float t_min = max_distance;
	Hit unused_hit;
	return traverseObjects(ray, true, max_distance, unused_hit, t_min, force_bvh);
unknown's avatar
unknown committed
26
27
}

28
bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false)
unknown's avatar
unknown committed
29
{
30
	if(!use_global_bvh)
unknown's avatar
unknown committed
31
	{
32
33
34
35
		float current_t = t_min;
		bool hit_triangle = false;
		Hit unused;
		for(int i=0; i<meshes_data.length(); ++i)
unknown's avatar
unknown committed
36
		{
37
38
			const Mesh mesh = meshes_data[i];
			if(force_bvh)
unknown's avatar
unknown committed
39
			{
40
41
42
43
44
45
46
				if(mesh.traverseBVH(ray.makeRelative(mesh), use_first, current_t, false, hit, unused, t_min)){
					hit_triangle = true;
					if (use_first)
					{
						return true;
					}
				}
unknown's avatar
unknown committed
47
			}
48
			else
unknown's avatar
unknown committed
49
			{
Johannes Braun's avatar
Johannes Braun committed
50
51
				for(int ls = 0; ls < mesh.num_linespaces; ++ls)
				{
52
53
54
55
56
					Hit bla;
					float mint = t_min;
					if(mesh.traverseLineSpace(ls, ray.makeRelative(mesh), use_first, current_t, bla, mint) && mint < t_min){
						hit = bla;
						t_min = mint;
Johannes Braun's avatar
Johannes Braun committed
57
58
59
60
61
						hit_triangle = true;
						if (use_first)
						{
							return true;
						}
62
63
					}
				}
unknown's avatar
unknown committed
64
65
			}
		}
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

		return hit_triangle;
	}
	else
	{
		float t = t_min;
		float max_dist = max_distance;
		// Check once the AABB for the whole scene
		bool hit_scene = global_bvh_nodes_data.length() != 0 && ray.intersectsBounds(global_bvh_nodes_data[0].bounds, max_distance);
		bool hit_triangle = false;

		int current_node = 0;
		int bitstack = 0;

		Hit unused;

		while (hit_scene)
unknown's avatar
unknown committed
83
		{
84
85
86
87
			if (global_bvh_nodes_data[current_node].type == 0) //Inner node.
			{
				int id_left = int(global_bvh_nodes_data[current_node].left_idx);
				bool hit_left = ray.intersectsBounds(global_bvh_nodes_data[id_left].bounds, max_distance);
unknown's avatar
unknown committed
88

89
90
				int id_right = int(global_bvh_nodes_data[current_node].right_idx);
				bool hit_right = ray.intersectsBounds(global_bvh_nodes_data[id_right].bounds, max_distance);
91

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
				//both hit
				if (hit_left && hit_right)
				{
					// shift bitstack and mark as branched, so we can use the marker
					// when backtracking to stop here and use the right child.
					bitstack = bitstack << 1;
					current_node = id_left;
					bitstack = bitstack | 1;
					continue;
				}
				// only left hit
				else if (hit_left && !hit_right)
				{
					// Not branching here, the other sibling-check won't be needed here.
					bitstack = bitstack << 1;
					current_node = id_left;
					continue;
				}
				// only right hit
				else if (!hit_left && hit_right)
				{
					// Not branching here, the other sibling-check won't be needed here.
					bitstack = bitstack << 1;
					current_node = id_right;
					continue;
				}
			}
			else
unknown's avatar
unknown committed
120
			{
121
122
123
124
125
126
127
128
				//Is leaf
				// intersect ray with primitives.
				//shorten ray if closer intersection found.
				//intersect triangles

				int start = int(global_bvh_nodes_data[current_node].left_idx);
				int end = int(global_bvh_nodes_data[current_node].right_idx);

129
				float current_t = t_min;
130
				for (int i = start; i <= end; i++)
unknown's avatar
unknown committed
131
				{
132
133
134
135
136
137
138
139
140
					const Mesh mesh = meshes_data[i];
					if(force_bvh)
					{
						if(mesh.traverseBVH(ray.makeRelative(mesh), use_first, current_t, false, hit, unused, t_min)){
							hit_triangle = true;
							if (use_first)
							{
								return true;
							}
unknown's avatar
unknown committed
141
142
						}
					}
143
144
					else
					{
Johannes Braun's avatar
Johannes Braun committed
145
146
147
148
149
150
151
152
						for(int ls = 0; ls < mesh.num_linespaces; ++ls)
						{
							if(mesh.traverseLineSpace(ls, ray.makeRelative(mesh), use_first, current_t, hit, t_min)){
								hit_triangle = true;
								if (use_first)
								{
									return true;
								}
153
							}
unknown's avatar
unknown committed
154
155
156
157
						}
					}
				}

158
			}
unknown's avatar
unknown committed
159

160
161
			//Backtrace on bitstack until we find a branching point (where bit value is 1)
			while ((bitstack & 1) == 0)
unknown's avatar
unknown committed
162
			{
163
164
165
166
167
168
169
170
				//Empty bitstack
				if (bitstack == 0)
				{
					return hit_triangle;
				}

				current_node = int(global_bvh_nodes_data[current_node].parent);
				bitstack = bitstack >> 1;
unknown's avatar
unknown committed
171
172
			}

173
174
175
			//Use other (right) sibling from the left child of the branched tree node.
			current_node = int(global_bvh_nodes_data[global_bvh_nodes_data[current_node].parent].right_idx);
			bitstack = bitstack ^ 1;
unknown's avatar
unknown committed
176
177
		}

178
		return hit_triangle;
unknown's avatar
unknown committed
179
	}
unknown's avatar
unknown committed
180
181
}

182
#endif //INCLUDE_PATHTRACER_DATASTRUCTURE_GLSL