1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "../common/scene.h"
7#include "../common/primref.h"
8
9namespace embree
10{
11 namespace isa
12 {
13 template<size_t N>
14 __forceinline void splitPolygon(const BBox3fa& bounds,
15 const size_t dim,
16 const float pos,
17 const Vec3fa (&v)[N+1],
18 const Vec3fa (&inv_length)[N],
19 BBox3fa& left_o,
20 BBox3fa& right_o)
21 {
22 BBox3fa left = empty, right = empty;
23 /* clip triangle to left and right box by processing all edges */
24 for (size_t i=0; i<N; i++)
25 {
26 const Vec3fa &v0 = v[i];
27 const Vec3fa &v1 = v[i+1];
28 const float v0d = v0[dim];
29 const float v1d = v1[dim];
30
31 if (v0d <= pos) left. extend(other: v0); // this point is on left side
32 if (v0d >= pos) right.extend(other: v0); // this point is on right side
33
34 if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
35 {
36 assert((v1d-v0d) != 0.0f);
37 const Vec3fa c = madd(a: Vec3fa((pos-v0d)*inv_length[i][dim]),b: v1-v0,c: v0);
38 left.extend(other: c);
39 right.extend(other: c);
40 }
41 }
42
43 /* clip against current bounds */
44 left_o = intersect(a: left,b: bounds);
45 right_o = intersect(a: right,b: bounds);
46 }
47
48 template<size_t N>
49 __forceinline void splitPolygon(const PrimRef& prim,
50 const size_t dim,
51 const float pos,
52 const Vec3fa (&v)[N+1],
53 PrimRef& left_o,
54 PrimRef& right_o)
55 {
56 BBox3fa left = empty, right = empty;
57 for (size_t i=0; i<N; i++)
58 {
59 const Vec3fa &v0 = v[i];
60 const Vec3fa &v1 = v[i+1];
61 const float v0d = v0[dim];
62 const float v1d = v1[dim];
63
64 if (v0d <= pos) left. extend(other: v0); // this point is on left side
65 if (v0d >= pos) right.extend(other: v0); // this point is on right side
66
67 if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location
68 {
69 assert((v1d-v0d) != 0.0f);
70 const float inv_length = 1.0f/(v1d-v0d);
71 const Vec3fa c = madd(a: Vec3fa((pos-v0d)*inv_length),b: v1-v0,c: v0);
72 left.extend(other: c);
73 right.extend(other: c);
74 }
75 }
76
77 /* clip against current bounds */
78 new (&left_o ) PrimRef(intersect(a: left ,b: prim.bounds()),prim.geomID(), prim.primID());
79 new (&right_o) PrimRef(intersect(a: right,b: prim.bounds()),prim.geomID(), prim.primID());
80 }
81
82 struct TriangleSplitter
83 {
84 __forceinline TriangleSplitter(const Scene* scene, const PrimRef& prim)
85 {
86 const unsigned int mask = 0xFFFFFFFF >> RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS;
87 const TriangleMesh* mesh = (const TriangleMesh*) scene->get(i: prim.geomID() & mask );
88 TriangleMesh::Triangle tri = mesh->triangle(i: prim.primID());
89 v[0] = mesh->vertex(i: tri.v[0]);
90 v[1] = mesh->vertex(i: tri.v[1]);
91 v[2] = mesh->vertex(i: tri.v[2]);
92 v[3] = mesh->vertex(i: tri.v[0]);
93 inv_length[0] = Vec3fa(1.0f) / (v[1]-v[0]);
94 inv_length[1] = Vec3fa(1.0f) / (v[2]-v[1]);
95 inv_length[2] = Vec3fa(1.0f) / (v[0]-v[2]);
96 }
97
98 __forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
99 splitPolygon<3>(prim,dim,pos,v,left_o,right_o);
100 }
101
102 __forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
103 splitPolygon<3>(bounds: prim,dim,pos,v,inv_length,left_o,right_o);
104 }
105
106 private:
107 Vec3fa v[4];
108 Vec3fa inv_length[3];
109 };
110
111 struct TriangleSplitterFactory
112 {
113 __forceinline TriangleSplitterFactory(const Scene* scene)
114 : scene(scene) {}
115
116 __forceinline TriangleSplitter operator() (const PrimRef& prim) const {
117 return TriangleSplitter(scene,prim);
118 }
119
120 private:
121 const Scene* scene;
122 };
123
124 struct QuadSplitter
125 {
126 __forceinline QuadSplitter(const Scene* scene, const PrimRef& prim)
127 {
128 const unsigned int mask = 0xFFFFFFFF >> RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS;
129 const QuadMesh* mesh = (const QuadMesh*) scene->get(i: prim.geomID() & mask );
130 QuadMesh::Quad quad = mesh->quad(i: prim.primID());
131 v[0] = mesh->vertex(i: quad.v[0]);
132 v[1] = mesh->vertex(i: quad.v[1]);
133 v[2] = mesh->vertex(i: quad.v[2]);
134 v[3] = mesh->vertex(i: quad.v[3]);
135 v[4] = mesh->vertex(i: quad.v[0]);
136 inv_length[0] = Vec3fa(1.0f) / (v[1]-v[0]);
137 inv_length[1] = Vec3fa(1.0f) / (v[2]-v[1]);
138 inv_length[2] = Vec3fa(1.0f) / (v[3]-v[2]);
139 inv_length[3] = Vec3fa(1.0f) / (v[0]-v[3]);
140 }
141
142 __forceinline void operator() (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const {
143 splitPolygon<4>(prim,dim,pos,v,left_o,right_o);
144 }
145
146 __forceinline void operator() (const BBox3fa& prim, const size_t dim, const float pos, BBox3fa& left_o, BBox3fa& right_o) const {
147 splitPolygon<4>(bounds: prim,dim,pos,v,inv_length,left_o,right_o);
148 }
149
150 private:
151 Vec3fa v[5];
152 Vec3fa inv_length[4];
153 };
154
155 struct QuadSplitterFactory
156 {
157 __forceinline QuadSplitterFactory(const Scene* scene)
158 : scene(scene) {}
159
160 __forceinline QuadSplitter operator() (const PrimRef& prim) const {
161 return QuadSplitter(scene,prim);
162 }
163
164 private:
165 const Scene* scene;
166 };
167
168
169 struct DummySplitter
170 {
171 __forceinline DummySplitter(const Scene* scene, const PrimRef& prim)
172 {
173 }
174 };
175
176 struct DummySplitterFactory
177 {
178 __forceinline DummySplitterFactory(const Scene* scene)
179 : scene(scene) {}
180
181 __forceinline DummySplitter operator() (const PrimRef& prim) const {
182 return DummySplitter(scene,prim);
183 }
184
185 private:
186 const Scene* scene;
187 };
188
189 }
190}
191
192

source code of qtquick3d/src/3rdparty/embree/kernels/builders/splitter.h