/
edge_tree.h
124 lines (108 loc) · 3.25 KB
/
edge_tree.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
120
121
122
123
124
#pragma once
#include "redner.h"
#include "vector.h"
#include "buffer.h"
#include "aabb.h"
#include <iostream>
struct Camera;
struct Shape;
struct Edge;
struct BVHNode3 {
AABB3 bounds;
Real weighted_total_length; // \sum length * (pi - dihedral angle)
BVHNode3 *parent;
BVHNode3 *children[2];
int edge_id;
Real cost;
};
struct BVHNode6 {
AABB6 bounds;
Real weighted_total_length; // \sum length * (pi - dihedral angle)
BVHNode6 *parent;
BVHNode6 *children[2];
int edge_id;
Real cost;
};
struct BVHNodePtr {
DEVICE BVHNodePtr() {}
DEVICE BVHNodePtr(const BVHNode3 *ptr3)
: is_bvh_node3(true), ptr3(ptr3) {}
DEVICE BVHNodePtr(const BVHNode6 *ptr6)
: is_bvh_node3(false), ptr6(ptr6) {}
bool is_bvh_node3;
union {
const BVHNode3 *ptr3;
const BVHNode6 *ptr6;
};
};
DEVICE
inline bool is_leaf(const BVHNodePtr &node_ptr) {
if (node_ptr.is_bvh_node3) {
return node_ptr.ptr3->edge_id != -1;
} else {
return node_ptr.ptr6->edge_id != -1;
}
}
DEVICE
inline int get_edge_id(const BVHNodePtr &node_ptr) {
if (node_ptr.is_bvh_node3) {
return node_ptr.ptr3->edge_id;
} else {
return node_ptr.ptr6->edge_id;
}
}
DEVICE
inline void get_children(const BVHNodePtr &node_ptr, BVHNodePtr children[2]) {
if (node_ptr.is_bvh_node3) {
children[0] = BVHNodePtr(node_ptr.ptr3->children[0]);
children[1] = BVHNodePtr(node_ptr.ptr3->children[1]);
} else {
children[0] = BVHNodePtr(node_ptr.ptr6->children[0]);
children[1] = BVHNodePtr(node_ptr.ptr6->children[1]);
}
}
DEVICE
inline bool intersect(const BVHNodePtr &node_ptr, const Ray &ray,
const Real edge_bounds_expand = 0) {
if (node_ptr.is_bvh_node3) {
return intersect(node_ptr.ptr3->bounds, ray, edge_bounds_expand);
} else {
return intersect(node_ptr.ptr6->bounds, ray, edge_bounds_expand);
}
}
DEVICE
inline bool intersect(const BVHNodePtr &node_ptr, const Ray &ray,
const Vector3 &inv_dir, const TVector3<bool> dir_is_neg,
const Real edge_bounds_expand = 0) {
if (node_ptr.is_bvh_node3) {
return intersect(node_ptr.ptr3->bounds, ray,
inv_dir, dir_is_neg, edge_bounds_expand);
} else {
return intersect(node_ptr.ptr6->bounds, ray,
inv_dir, dir_is_neg, edge_bounds_expand);
}
}
struct EdgeTree {
EdgeTree(bool use_gpu,
const Camera &camera,
const BufferView<Shape> &shapes,
const BufferView<Edge> &edges);
Buffer<BVHNode3> cs_bvh_nodes;
Buffer<BVHNode3> cs_bvh_leaves;
Buffer<BVHNode6> ncs_bvh_nodes;
Buffer<BVHNode6> ncs_bvh_leaves;
Real edge_bounds_expand;
};
struct EdgeTreeRoots {
const BVHNode3 *cs_bvh_root;
const BVHNode6 *ncs_bvh_root;
};
inline EdgeTreeRoots get_edge_tree_roots(const EdgeTree *edge_tree) {
if (edge_tree == nullptr) {
return EdgeTreeRoots{nullptr, nullptr};
} else {
return EdgeTreeRoots{
edge_tree->cs_bvh_nodes.begin(),
edge_tree->ncs_bvh_nodes.begin()};
}
}