Blender V4.3
Projections.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2002-2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#ifdef WITH_CXX_GUARDEDALLOC
6# include "MEM_guardedalloc.h"
7#endif
8
9#include "Projections.h"
10#include <math.h>
11
12const int vertmap[8][3] = {
13 {0, 0, 0},
14 {0, 0, 1},
15 {0, 1, 0},
16 {0, 1, 1},
17 {1, 0, 0},
18 {1, 0, 1},
19 {1, 1, 0},
20 {1, 1, 1},
21};
22
23const int centmap[3][3][3][2] = {
24 {{{0, 0}, {0, 1}, {1, 1}}, {{0, 2}, {0, 3}, {1, 3}}, {{2, 2}, {2, 3}, {3, 3}}},
25
26 {{{0, 4}, {0, 5}, {1, 5}}, {{0, 6}, {0, 7}, {1, 7}}, {{2, 6}, {2, 7}, {3, 7}}},
27
28 {{{4, 4}, {4, 5}, {5, 5}}, {{4, 6}, {4, 7}, {5, 7}}, {{6, 6}, {6, 7}, {7, 7}}}};
29
30const int edgemap[12][2] = {
31 {0, 4},
32 {1, 5},
33 {2, 6},
34 {3, 7},
35 {0, 2},
36 {1, 3},
37 {4, 6},
38 {5, 7},
39 {0, 1},
40 {2, 3},
41 {4, 5},
42 {6, 7},
43};
44
45const int facemap[6][4] = {
46 {0, 1, 2, 3},
47 {4, 5, 6, 7},
48 {0, 1, 4, 5},
49 {2, 3, 6, 7},
50 {0, 2, 4, 6},
51 {1, 3, 5, 7},
52};
53
57static void crossProduct(int64_t res[3], const int64_t a[3], const int64_t b[3])
58{
59 res[0] = a[1] * b[2] - a[2] * b[1];
60 res[1] = a[2] * b[0] - a[0] * b[2];
61 res[2] = a[0] * b[1] - a[1] * b[0];
62}
63
64static void crossProduct(double res[3], const double a[3], const double b[3])
65{
66 res[0] = a[1] * b[2] - a[2] * b[1];
67 res[1] = a[2] * b[0] - a[0] * b[2];
68 res[2] = a[0] * b[1] - a[1] * b[0];
69}
70
74static int64_t dotProduct(const int64_t a[3], const int64_t b[3])
75{
76 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
77}
78
79static void normalize(double a[3])
80{
81 double mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
82 if (mag > 0) {
83 mag = sqrt(mag);
84 a[0] /= mag;
85 a[1] /= mag;
86 a[2] /= mag;
87 }
88}
89
90/* Create projection axes for cube+triangle intersection testing.
91 * 0, 1, 2: cube face normals
92 *
93 * 3: triangle normal
94 *
95 * 4, 5, 6,
96 * 7, 8, 9,
97 * 10, 11, 12: cross of each triangle edge vector with each cube
98 * face normal
99 */
100static void create_projection_axes(int64_t axes[NUM_AXES][3], const int64_t tri[3][3])
101{
102 /* Cube face normals */
103 axes[0][0] = 1;
104 axes[0][1] = 0;
105 axes[0][2] = 0;
106 axes[1][0] = 0;
107 axes[1][1] = 1;
108 axes[1][2] = 0;
109 axes[2][0] = 0;
110 axes[2][1] = 0;
111 axes[2][2] = 1;
112
113 /* Get triangle edge vectors */
114 int64_t tri_edges[3][3];
115 for (int i = 0; i < 3; i++) {
116 for (int j = 0; j < 3; j++) {
117 tri_edges[i][j] = tri[(i + 1) % 3][j] - tri[i][j];
118 }
119 }
120
121 /* Triangle normal */
122 crossProduct(axes[3], tri_edges[0], tri_edges[1]);
123
124 // Face edges and triangle edges
125 int ct = 4;
126 for (int i = 0; i < 3; i++) {
127 for (int j = 0; j < 3; j++) {
128 crossProduct(axes[ct], axes[j], tri_edges[i]);
129 ct++;
130 }
131 }
132}
133
138 int64_t tri[3][3],
139 int64_t /*error*/,
140 int triind)
141{
142 int i;
144 inherit->index = triind;
145
146 int64_t axes[NUM_AXES][3];
147 create_projection_axes(axes, tri);
148
149 /* Normalize face normal and store */
150 double dedge1[] = {(double)tri[1][0] - (double)tri[0][0],
151 (double)tri[1][1] - (double)tri[0][1],
152 (double)tri[1][2] - (double)tri[0][2]};
153 double dedge2[] = {(double)tri[2][0] - (double)tri[1][0],
154 (double)tri[2][1] - (double)tri[1][1],
155 (double)tri[2][2] - (double)tri[1][2]};
156 crossProduct(inherit->norm, dedge1, dedge2);
158
159 int64_t cubeedge[3][3];
160 for (i = 0; i < 3; i++) {
161 for (int j = 0; j < 3; j++) {
162 cubeedge[i][j] = 0;
163 }
164 cubeedge[i][i] = cube[1][i] - cube[0][i];
165 }
166
167 /* Project the cube on to each axis */
168 for (int axis = 0; axis < NUM_AXES; axis++) {
169 CubeProjection &cube_proj = cubeProj[axis];
170
171 /* Origin */
172 cube_proj.origin = dotProduct(axes[axis], cube[0]);
173
174 /* 3 direction vectors */
175 for (i = 0; i < 3; i++) {
176 cube_proj.edges[i] = dotProduct(axes[axis], cubeedge[i]);
177 }
178
179 /* Offsets of 2 ends of cube projection */
180 int64_t max = 0;
181 int64_t min = 0;
182 for (i = 1; i < 8; i++) {
183 int64_t proj = (vertmap[i][0] * cube_proj.edges[0] + vertmap[i][1] * cube_proj.edges[1] +
184 vertmap[i][2] * cube_proj.edges[2]);
185 if (proj > max) {
186 max = proj;
187 }
188 if (proj < min) {
189 min = proj;
190 }
191 }
192 cube_proj.min = min;
193 cube_proj.max = max;
194 }
195
196 /* Project the triangle on to each axis */
197 for (int axis = 0; axis < NUM_AXES; axis++) {
198 const int64_t vts[3] = {dotProduct(axes[axis], tri[0]),
199 dotProduct(axes[axis], tri[1]),
200 dotProduct(axes[axis], tri[2])};
201
202 // Triangle
203 inherit->tri_proj[axis][0] = vts[0];
204 inherit->tri_proj[axis][1] = vts[0];
205 for (i = 1; i < 3; i++) {
206 if (vts[i] < inherit->tri_proj[axis][0]) {
207 inherit->tri_proj[axis][0] = vts[i];
208 }
209
210 if (vts[i] > inherit->tri_proj[axis][1]) {
211 inherit->tri_proj[axis][1] = vts[i];
212 }
213 }
214 }
215}
216
222{
223 // Copy inheritable projections
224 this->inherit = parent->inherit;
225
226 // Shrink cube projections
227 for (int i = 0; i < NUM_AXES; i++) {
228 cubeProj[i].origin = parent->cubeProj[i].origin;
229
230 for (int j = 0; j < 3; j++) {
231 cubeProj[i].edges[j] = parent->cubeProj[i].edges[j] >> 1;
232 }
233
234 cubeProj[i].min = parent->cubeProj[i].min >> 1;
235 cubeProj[i].max = parent->cubeProj[i].max >> 1;
236 }
237}
238
240{
241 int i, j, k;
242 int bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
243 unsigned char boxmask = 0;
244 int64_t child_len = cubeProj[0].edges[0] >> 1;
245
246 for (i = 0; i < 3; i++) {
247 int64_t mid = cubeProj[i].origin + child_len;
248
249 // Check bounding box
250 if (mid >= inherit->tri_proj[i][0]) {
251 bmask[i][0] = 1;
252 }
253 if (mid < inherit->tri_proj[i][1]) {
254 bmask[i][1] = 1;
255 }
256 }
257
258 // Fill in masks
259 int ct = 0;
260 for (i = 0; i < 2; i++) {
261 for (j = 0; j < 2; j++) {
262 for (k = 0; k < 2; k++) {
263 boxmask |= ((bmask[0][i] & bmask[1][j] & bmask[2][k]) << ct);
264 ct++;
265 }
266 }
267 }
268
269 // Return bounding box masks
270 return boxmask;
271}
272
277{
278 for (int i = 0; i < NUM_AXES; i++) {
279 cubeProj[i].origin += (off[0] * cubeProj[i].edges[0] + off[1] * cubeProj[i].edges[1] +
280 off[2] * cubeProj[i].edges[2]);
281 }
282}
283
288{
289 for (int i = 0; i < NUM_AXES; i++) {
290 /*
291 int64_t proj0 = cubeProj[i][0] +
292 vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
293 vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
294 vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
295 int64_t proj1 = cubeProj[i][0] +
296 vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
297 vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
298 vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
299 */
300
301 int64_t proj0 = cubeProj[i].origin + cubeProj[i].min;
302 int64_t proj1 = cubeProj[i].origin + cubeProj[i].max;
303
304 if (proj0 > inherit->tri_proj[i][1] || proj1 < inherit->tri_proj[i][0]) {
305 return 0;
306 }
307 }
308
309 return 1;
310}
311
313{
314 for (int i = 0; i < NUM_AXES; i++) {
315
316 int64_t proj0 = cubeProj[i].origin;
317 int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
318
319 if (proj0 < proj1) {
320 if (proj0 > inherit->tri_proj[i][1] || proj1 < inherit->tri_proj[i][0]) {
321 return 0;
322 }
323 }
324 else {
325 if (proj1 > inherit->tri_proj[i][1] || proj0 < inherit->tri_proj[i][0]) {
326 return 0;
327 }
328 }
329 }
330
331 // printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ;
332 return 1;
333}
334
336{
337 int i = 3;
338
339 int64_t proj0 = cubeProj[i].origin;
340 int64_t proj1 = cubeProj[i].origin + cubeProj[i].edges[edgeInd];
341 int64_t proj2 = inherit->tri_proj[i][1];
342 int64_t d = proj1 - proj0;
343 double alpha;
344
345 if (d == 0) {
346 alpha = 0.5;
347 }
348 else {
349 alpha = (double)((proj2 - proj0)) / (double)d;
350
351 if (alpha < 0 || alpha > 1) {
352 alpha = 0.5;
353 }
354 }
355
356 return (float)alpha;
357}
sqrt(x)+1/max(0
typedef double(DMatrix)[4][4]
Read Guarded memory(de)allocation.
const int edgemap[12][2]
const int centmap[3][3][3][2]
static int64_t dotProduct(const int64_t a[3], const int64_t b[3])
const int vertmap[8][3]
static void create_projection_axes(int64_t axes[NUM_AXES][3], const int64_t tri[3][3])
const int facemap[6][4]
static void crossProduct(int64_t res[3], const int64_t a[3], const int64_t b[3])
#define NUM_AXES
Definition Projections.h:44
const int vertmap[8][3]
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
void shift(int off[3])
int isIntersecting() const
int isIntersectingPrimary(int edgeInd) const
CubeProjection cubeProj[NUM_AXES]
Projections of the cube vertices.
Definition Projections.h:77
unsigned char getBoxMask()
TriangleProjection * inherit
Inheritable portion.
Definition Projections.h:74
float getIntersectionPrimary(int edgeInd) const
local_group_size(16, 16) .push_constant(Type b
#define min(a, b)
Definition sort.c:32
__int64 int64_t
Definition stdint.h:89
int64_t edges[3]
Definition Projections.h:64
int64_t tri_proj[NUM_AXES][2]
Projections of triangle (min and max)
Definition Projections.h:51
double norm[3]
Normal of the triangle.
Definition Projections.h:54
int index
Index of polygon.
Definition Projections.h:57
float max