Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/bvh/bvh_statistics.cpp
9912 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#include "bvh_statistics.h"
5
#include "../../common/algorithms/parallel_reduce.h"
6
7
namespace embree
8
{
9
template<int N>
10
BVHNStatistics<N>::BVHNStatistics (BVH* bvh) : bvh(bvh)
11
{
12
double A = max(0.0f,bvh->getLinearBounds().expectedHalfArea());
13
stat = statistics(bvh->root,A,BBox1f(0.0f,1.0f));
14
}
15
16
template<int N>
17
std::string BVHNStatistics<N>::str()
18
{
19
std::ostringstream stream;
20
stream.setf(std::ios::fixed, std::ios::floatfield);
21
stream << " primitives = " << bvh->numPrimitives << ", vertices = " << bvh->numVertices << ", depth = " << stat.depth << std::endl;
22
size_t totalBytes = stat.bytes(bvh);
23
double totalSAH = stat.sah(bvh);
24
stream << " total : sah = " << std::setw(7) << std::setprecision(3) << totalSAH << " (100.00%), ";
25
stream << "#bytes = " << std::setw(7) << std::setprecision(2) << totalBytes/1E6 << " MB (100.00%), ";
26
stream << "#nodes = " << std::setw(7) << stat.size() << " (" << std::setw(6) << std::setprecision(2) << 100.0*stat.fillRate(bvh) << "% filled), ";
27
stream << "#bytes/prim = " << std::setw(6) << std::setprecision(2) << double(totalBytes)/double(bvh->numPrimitives) << std::endl;
28
if (stat.statAABBNodes.numNodes ) stream << " getAABBNodes : " << stat.statAABBNodes.toString(bvh,totalSAH,totalBytes) << std::endl;
29
if (stat.statOBBNodes.numNodes ) stream << " ungetAABBNodes : " << stat.statOBBNodes.toString(bvh,totalSAH,totalBytes) << std::endl;
30
if (stat.statAABBNodesMB.numNodes ) stream << " getAABBNodesMB : " << stat.statAABBNodesMB.toString(bvh,totalSAH,totalBytes) << std::endl;
31
if (stat.statAABBNodesMB4D.numNodes) stream << " getAABBNodesMB4D : " << stat.statAABBNodesMB4D.toString(bvh,totalSAH,totalBytes) << std::endl;
32
if (stat.statOBBNodesMB.numNodes) stream << " ungetAABBNodesMB : " << stat.statOBBNodesMB.toString(bvh,totalSAH,totalBytes) << std::endl;
33
if (stat.statQuantizedNodes.numNodes ) stream << " quantizedNodes : " << stat.statQuantizedNodes.toString(bvh,totalSAH,totalBytes) << std::endl;
34
if (true) stream << " leaves : " << stat.statLeaf.toString(bvh,totalSAH,totalBytes) << std::endl;
35
if (true) stream << " histogram : " << stat.statLeaf.histToString() << std::endl;
36
return stream.str();
37
}
38
39
template<int N>
40
typename BVHNStatistics<N>::Statistics BVHNStatistics<N>::statistics(NodeRef node, const double A, const BBox1f t0t1)
41
{
42
Statistics s;
43
assert(t0t1.size() > 0.0f);
44
double dt = max(0.0f,t0t1.size());
45
if (node.isAABBNode())
46
{
47
AABBNode* n = node.getAABBNode();
48
s = s + parallel_reduce(0,N,Statistics(),[&] ( const int i ) {
49
if (n->child(i) == BVH::emptyNode) return Statistics();
50
const double Ai = max(0.0f,halfArea(n->extend(i)));
51
Statistics s = statistics(n->child(i),Ai,t0t1);
52
s.statAABBNodes.numChildren++;
53
return s;
54
}, Statistics::add);
55
s.statAABBNodes.numNodes++;
56
s.statAABBNodes.nodeSAH += dt*A;
57
s.depth++;
58
}
59
else if (node.isOBBNode())
60
{
61
OBBNode* n = node.ungetAABBNode();
62
s = s + parallel_reduce(0,N,Statistics(),[&] ( const int i ) {
63
if (n->child(i) == BVH::emptyNode) return Statistics();
64
const double Ai = max(0.0f,halfArea(n->extent(i)));
65
Statistics s = statistics(n->child(i),Ai,t0t1);
66
s.statOBBNodes.numChildren++;
67
return s;
68
}, Statistics::add);
69
s.statOBBNodes.numNodes++;
70
s.statOBBNodes.nodeSAH += dt*A;
71
s.depth++;
72
}
73
else if (node.isAABBNodeMB())
74
{
75
AABBNodeMB* n = node.getAABBNodeMB();
76
s = s + parallel_reduce(0,N,Statistics(),[&] ( const int i ) {
77
if (n->child(i) == BVH::emptyNode) return Statistics();
78
const double Ai = max(0.0f,n->expectedHalfArea(i,t0t1));
79
Statistics s = statistics(n->child(i),Ai,t0t1);
80
s.statAABBNodesMB.numChildren++;
81
return s;
82
}, Statistics::add);
83
s.statAABBNodesMB.numNodes++;
84
s.statAABBNodesMB.nodeSAH += dt*A;
85
s.depth++;
86
}
87
else if (node.isAABBNodeMB4D())
88
{
89
AABBNodeMB4D* n = node.getAABBNodeMB4D();
90
s = s + parallel_reduce(0,N,Statistics(),[&] ( const int i ) {
91
if (n->child(i) == BVH::emptyNode) return Statistics();
92
const BBox1f t0t1i = intersect(t0t1,n->timeRange(i));
93
assert(!t0t1i.empty());
94
const double Ai = n->AABBNodeMB::expectedHalfArea(i,t0t1i);
95
Statistics s = statistics(n->child(i),Ai,t0t1i);
96
s.statAABBNodesMB4D.numChildren++;
97
return s;
98
}, Statistics::add);
99
s.statAABBNodesMB4D.numNodes++;
100
s.statAABBNodesMB4D.nodeSAH += dt*A;
101
s.depth++;
102
}
103
else if (node.isOBBNodeMB())
104
{
105
OBBNodeMB* n = node.ungetAABBNodeMB();
106
s = s + parallel_reduce(0,N,Statistics(),[&] ( const int i ) {
107
if (n->child(i) == BVH::emptyNode) return Statistics();
108
const double Ai = max(0.0f,halfArea(n->extent0(i)));
109
Statistics s = statistics(n->child(i),Ai,t0t1);
110
s.statOBBNodesMB.numChildren++;
111
return s;
112
}, Statistics::add);
113
s.statOBBNodesMB.numNodes++;
114
s.statOBBNodesMB.nodeSAH += dt*A;
115
s.depth++;
116
}
117
else if (node.isQuantizedNode())
118
{
119
QuantizedNode* n = node.quantizedNode();
120
s = s + parallel_reduce(0,N,Statistics(),[&] ( const int i ) {
121
if (n->child(i) == BVH::emptyNode) return Statistics();
122
const double Ai = max(0.0f,halfArea(n->extent(i)));
123
Statistics s = statistics(n->child(i),Ai,t0t1);
124
s.statQuantizedNodes.numChildren++;
125
return s;
126
}, Statistics::add);
127
s.statQuantizedNodes.numNodes++;
128
s.statQuantizedNodes.nodeSAH += dt*A;
129
s.depth++;
130
}
131
else if (node.isLeaf())
132
{
133
size_t num; const char* tri = node.leaf(num);
134
if (num)
135
{
136
for (size_t i=0; i<num; i++)
137
{
138
const size_t bytes = bvh->primTy->getBytes(tri);
139
s.statLeaf.numPrimsActive += bvh->primTy->sizeActive(tri);
140
s.statLeaf.numPrimsTotal += bvh->primTy->sizeTotal(tri);
141
s.statLeaf.numBytes += bytes;
142
tri+=bytes;
143
}
144
s.statLeaf.numLeaves++;
145
s.statLeaf.numPrimBlocks += num;
146
s.statLeaf.leafSAH += dt*A*num;
147
if (num-1 < Statistics::LeafStat::NHIST) {
148
s.statLeaf.numPrimBlocksHistogram[num-1]++;
149
}
150
}
151
}
152
else {
153
abort(); //throw std::runtime_error("not supported node type in bvh_statistics");
154
}
155
return s;
156
}
157
158
#if defined(__AVX__)
159
template class BVHNStatistics<8>;
160
#endif
161
162
#if !defined(__AVX__) || (!defined(EMBREE_TARGET_SSE2) && !defined(EMBREE_TARGET_SSE42)) || defined(__aarch64__)
163
template class BVHNStatistics<4>;
164
#endif
165
}
166
167