Blender
V5.0
intern
dualcon
intern
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
#include "
Projections.h
"
6
#include <cmath>
7
8
#include <algorithm>
9
10
const
int
vertmap
[8][3] = {
11
{0, 0, 0},
12
{0, 0, 1},
13
{0, 1, 0},
14
{0, 1, 1},
15
{1, 0, 0},
16
{1, 0, 1},
17
{1, 1, 0},
18
{1, 1, 1},
19
};
20
21
const
int
centmap
[3][3][3][2] = {
22
{{{0, 0}, {0, 1}, {1, 1}}, {{0, 2}, {0, 3}, {1, 3}}, {{2, 2}, {2, 3}, {3, 3}}},
23
24
{{{0, 4}, {0, 5}, {1, 5}}, {{0, 6}, {0, 7}, {1, 7}}, {{2, 6}, {2, 7}, {3, 7}}},
25
26
{{{4, 4}, {4, 5}, {5, 5}}, {{4, 6}, {4, 7}, {5, 7}}, {{6, 6}, {6, 7}, {7, 7}}}};
27
28
const
int
edgemap
[12][2] = {
29
{0, 4},
30
{1, 5},
31
{2, 6},
32
{3, 7},
33
{0, 2},
34
{1, 3},
35
{4, 6},
36
{5, 7},
37
{0, 1},
38
{2, 3},
39
{4, 5},
40
{6, 7},
41
};
42
43
const
int
facemap
[6][4] = {
44
{0, 1, 2, 3},
45
{4, 5, 6, 7},
46
{0, 1, 4, 5},
47
{2, 3, 6, 7},
48
{0, 2, 4, 6},
49
{1, 3, 5, 7},
50
};
51
55
static
void
crossProduct
(
int64_t
res[3],
const
int64_t
a[3],
const
int64_t
b
[3])
56
{
57
res[0] = a[1] *
b
[2] - a[2] *
b
[1];
58
res[1] = a[2] *
b
[0] - a[0] *
b
[2];
59
res[2] = a[0] *
b
[1] - a[1] *
b
[0];
60
}
61
62
static
void
crossProduct
(
double
res[3],
const
double
a[3],
const
double
b
[3])
63
{
64
res[0] = a[1] *
b
[2] - a[2] *
b
[1];
65
res[1] = a[2] *
b
[0] - a[0] *
b
[2];
66
res[2] = a[0] *
b
[1] - a[1] *
b
[0];
67
}
68
72
static
int64_t
dotProduct
(
const
int64_t
a[3],
const
int64_t
b
[3])
73
{
74
return
a[0] *
b
[0] + a[1] *
b
[1] + a[2] *
b
[2];
75
}
76
77
static
void
normalize
(
double
a[3])
78
{
79
double
mag = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
80
if
(mag > 0) {
81
mag =
sqrt
(mag);
82
a[0] /= mag;
83
a[1] /= mag;
84
a[2] /= mag;
85
}
86
}
87
88
/* Create projection axes for cube+triangle intersection testing.
89
* 0, 1, 2: cube face normals
90
*
91
* 3: triangle normal
92
*
93
* 4, 5, 6,
94
* 7, 8, 9,
95
* 10, 11, 12: cross of each triangle edge vector with each cube
96
* face normal
97
*/
98
static
void
create_projection_axes
(
int64_t
axes[
NUM_AXES
][3],
const
int64_t
tri[3][3])
99
{
100
/* Cube face normals */
101
axes[0][0] = 1;
102
axes[0][1] = 0;
103
axes[0][2] = 0;
104
axes[1][0] = 0;
105
axes[1][1] = 1;
106
axes[1][2] = 0;
107
axes[2][0] = 0;
108
axes[2][1] = 0;
109
axes[2][2] = 1;
110
111
/* Get triangle edge vectors */
112
int64_t
tri_edges[3][3];
113
for
(
int
i
= 0;
i
< 3;
i
++) {
114
for
(
int
j = 0; j < 3; j++) {
115
tri_edges[
i
][j] = tri[(
i
+ 1) % 3][j] - tri[
i
][j];
116
}
117
}
118
119
/* Triangle normal */
120
crossProduct
(axes[3], tri_edges[0], tri_edges[1]);
121
122
// Face edges and triangle edges
123
int
ct = 4;
124
for
(
int
i
= 0;
i
< 3;
i
++) {
125
for
(
int
j = 0; j < 3; j++) {
126
crossProduct
(axes[ct], axes[j], tri_edges[
i
]);
127
ct++;
128
}
129
}
130
}
131
135
CubeTriangleIsect::CubeTriangleIsect
(
int64_t
cube[2][3],
136
int64_t
tri[3][3],
137
int64_t
/*error*/
,
138
int
triind)
139
{
140
int
i
;
141
inherit
=
new
TriangleProjection
;
142
inherit
->index = triind;
143
144
int64_t
axes[
NUM_AXES
][3];
145
create_projection_axes
(axes, tri);
146
147
/* Normalize face normal and store */
148
double
dedge1[] = {(double)tri[1][0] - (
double
)tri[0][0],
149
(double)tri[1][1] - (
double
)tri[0][1],
150
(double)tri[1][2] - (
double
)tri[0][2]};
151
double
dedge2[] = {(double)tri[2][0] - (
double
)tri[1][0],
152
(double)tri[2][1] - (
double
)tri[1][1],
153
(double)tri[2][2] - (
double
)tri[1][2]};
154
crossProduct
(
inherit
->norm, dedge1, dedge2);
155
normalize
(
inherit
->norm);
156
157
int64_t
cubeedge[3][3];
158
for
(
i
= 0;
i
< 3;
i
++) {
159
for
(
int
j = 0; j < 3; j++) {
160
cubeedge[
i
][j] = 0;
161
}
162
cubeedge[
i
][
i
] = cube[1][
i
] - cube[0][
i
];
163
}
164
165
/* Project the cube on to each axis */
166
for
(
int
axis = 0; axis <
NUM_AXES
; axis++) {
167
CubeProjection
&cube_proj =
cubeProj
[axis];
168
169
/* Origin */
170
cube_proj.
origin
=
dotProduct
(axes[axis], cube[0]);
171
172
/* 3 direction vectors */
173
for
(
i
= 0;
i
< 3;
i
++) {
174
cube_proj.
edges
[
i
] =
dotProduct
(axes[axis], cubeedge[
i
]);
175
}
176
177
/* Offsets of 2 ends of cube projection */
178
int64_t
max
= 0;
179
int64_t
min
= 0;
180
for
(
i
= 1;
i
< 8;
i
++) {
181
int64_t
proj = (
vertmap
[
i
][0] * cube_proj.
edges
[0] +
vertmap
[
i
][1] * cube_proj.
edges
[1] +
182
vertmap
[
i
][2] * cube_proj.
edges
[2]);
183
max
= std::max(proj,
max
);
184
min
= std::min(proj,
min
);
185
}
186
cube_proj.
min
=
min
;
187
cube_proj.
max
=
max
;
188
}
189
190
/* Project the triangle on to each axis */
191
for
(
int
axis = 0; axis <
NUM_AXES
; axis++) {
192
const
int64_t
vts[3] = {
dotProduct
(axes[axis], tri[0]),
193
dotProduct
(axes[axis], tri[1]),
194
dotProduct
(axes[axis], tri[2])};
195
196
// Triangle
197
inherit
->tri_proj[axis][0] = vts[0];
198
inherit
->tri_proj[axis][1] = vts[0];
199
for
(
i
= 1;
i
< 3;
i
++) {
200
inherit
->tri_proj[axis][0] = std::min(vts[
i
],
inherit
->tri_proj[axis][0]);
201
inherit
->tri_proj[axis][1] = std::max(vts[
i
],
inherit
->tri_proj[axis][1]);
202
}
203
}
204
}
205
210
CubeTriangleIsect::CubeTriangleIsect
(
CubeTriangleIsect
*parent)
211
{
212
// Copy inheritable projections
213
this->
inherit
= parent->
inherit
;
214
215
// Shrink cube projections
216
for
(
int
i
= 0;
i
<
NUM_AXES
;
i
++) {
217
cubeProj
[
i
].origin = parent->
cubeProj
[
i
].
origin
;
218
219
for
(
int
j = 0; j < 3; j++) {
220
cubeProj
[
i
].edges[j] = parent->
cubeProj
[
i
].
edges
[j] >> 1;
221
}
222
223
cubeProj
[
i
].min = parent->
cubeProj
[
i
].
min
>> 1;
224
cubeProj
[
i
].max = parent->
cubeProj
[
i
].
max
>> 1;
225
}
226
}
227
228
unsigned
char
CubeTriangleIsect::getBoxMask
()
229
{
230
int
i
, j, k;
231
int
bmask[3][2] = {{0, 0}, {0, 0}, {0, 0}};
232
unsigned
char
boxmask = 0;
233
int64_t
child_len =
cubeProj
[0].edges[0] >> 1;
234
235
for
(
i
= 0;
i
< 3;
i
++) {
236
int64_t
mid =
cubeProj
[
i
].origin + child_len;
237
238
// Check bounding box
239
if
(mid >=
inherit
->tri_proj[
i
][0]) {
240
bmask[
i
][0] = 1;
241
}
242
if
(mid < inherit->tri_proj[
i
][1]) {
243
bmask[
i
][1] = 1;
244
}
245
}
246
247
// Fill in masks
248
int
ct = 0;
249
for
(
i
= 0;
i
< 2;
i
++) {
250
for
(j = 0; j < 2; j++) {
251
for
(k = 0; k < 2; k++) {
252
boxmask |= ((bmask[0][
i
] & bmask[1][j] & bmask[2][k]) << ct);
253
ct++;
254
}
255
}
256
}
257
258
// Return bounding box masks
259
return
boxmask;
260
}
261
265
void
CubeTriangleIsect::shift
(
const
int
off[3])
266
{
267
for
(
int
i
= 0;
i
<
NUM_AXES
;
i
++) {
268
cubeProj
[
i
].origin += (off[0] *
cubeProj
[
i
].edges[0] + off[1] *
cubeProj
[
i
].edges[1] +
269
off[2] *
cubeProj
[
i
].edges[2]);
270
}
271
}
272
276
int
CubeTriangleIsect::isIntersecting
()
const
277
{
278
for
(
int
i
= 0;
i
<
NUM_AXES
;
i
++) {
279
/*
280
int64_t proj0 = cubeProj[i][0] +
281
vertmap[inherit->cubeEnds[i][0]][0] * cubeProj[i][1] +
282
vertmap[inherit->cubeEnds[i][0]][1] * cubeProj[i][2] +
283
vertmap[inherit->cubeEnds[i][0]][2] * cubeProj[i][3] ;
284
int64_t proj1 = cubeProj[i][0] +
285
vertmap[inherit->cubeEnds[i][1]][0] * cubeProj[i][1] +
286
vertmap[inherit->cubeEnds[i][1]][1] * cubeProj[i][2] +
287
vertmap[inherit->cubeEnds[i][1]][2] * cubeProj[i][3] ;
288
*/
289
290
int64_t
proj0 =
cubeProj
[
i
].origin +
cubeProj
[
i
].min;
291
int64_t
proj1 =
cubeProj
[
i
].origin +
cubeProj
[
i
].max;
292
293
if
(proj0 >
inherit
->tri_proj[
i
][1] || proj1 < inherit->tri_proj[
i
][0]) {
294
return
0;
295
}
296
}
297
298
return
1;
299
}
300
301
int
CubeTriangleIsect::isIntersectingPrimary
(
int
edgeInd)
const
302
{
303
for
(
int
i
= 0;
i
<
NUM_AXES
;
i
++) {
304
305
int64_t
proj0 =
cubeProj
[
i
].origin;
306
int64_t
proj1 =
cubeProj
[
i
].origin +
cubeProj
[
i
].edges[edgeInd];
307
308
if
(proj0 < proj1) {
309
if
(proj0 >
inherit
->tri_proj[
i
][1] || proj1 < inherit->tri_proj[
i
][0]) {
310
return
0;
311
}
312
}
313
else
{
314
if
(proj1 >
inherit
->tri_proj[
i
][1] || proj0 < inherit->tri_proj[
i
][0]) {
315
return
0;
316
}
317
}
318
}
319
320
// printf( "Intersecting: %d %d\n", edgemap[edgeInd][0], edgemap[edgeInd][1] ) ;
321
return
1;
322
}
323
324
float
CubeTriangleIsect::getIntersectionPrimary
(
int
edgeInd)
const
325
{
326
int
i
= 3;
327
328
int64_t
proj0 =
cubeProj
[
i
].origin;
329
int64_t
proj1 =
cubeProj
[
i
].origin +
cubeProj
[
i
].edges[edgeInd];
330
int64_t
proj2 =
inherit
->tri_proj[
i
][1];
331
int64_t
d = proj1 - proj0;
332
double
alpha;
333
334
if
(d == 0) {
335
alpha = 0.5;
336
}
337
else
{
338
alpha = (double)((proj2 - proj0)) / (double)d;
339
340
if
(alpha < 0 || alpha > 1) {
341
alpha = 0.5;
342
}
343
}
344
345
return
(
float
)alpha;
346
}
edgemap
const int edgemap[12][2]
Definition
Projections.cpp:28
centmap
const int centmap[3][3][3][2]
Definition
Projections.cpp:21
dotProduct
static int64_t dotProduct(const int64_t a[3], const int64_t b[3])
Definition
Projections.cpp:72
vertmap
const int vertmap[8][3]
Definition
Projections.cpp:10
create_projection_axes
static void create_projection_axes(int64_t axes[NUM_AXES][3], const int64_t tri[3][3])
Definition
Projections.cpp:98
facemap
const int facemap[6][4]
Definition
Projections.cpp:43
crossProduct
static void crossProduct(int64_t res[3], const int64_t a[3], const int64_t b[3])
Definition
Projections.cpp:55
Projections.h
NUM_AXES
#define NUM_AXES
Definition
Projections.h:45
vertmap
const int vertmap[8][3]
Definition
Projections.cpp:10
int64_t
long long int int64_t
Definition
btConvexHullComputer.cpp:31
CubeTriangleIsect::CubeTriangleIsect
CubeTriangleIsect()=default
CubeTriangleIsect::shift
void shift(const int off[3])
Definition
Projections.cpp:265
CubeTriangleIsect::isIntersecting
int isIntersecting() const
Definition
Projections.cpp:276
CubeTriangleIsect::isIntersectingPrimary
int isIntersectingPrimary(int edgeInd) const
Definition
Projections.cpp:301
CubeTriangleIsect::cubeProj
CubeProjection cubeProj[NUM_AXES]
Projections of the cube vertices.
Definition
Projections.h:78
CubeTriangleIsect::getBoxMask
unsigned char getBoxMask()
Definition
Projections.cpp:228
CubeTriangleIsect::inherit
TriangleProjection * inherit
Inheritable portion.
Definition
Projections.h:75
CubeTriangleIsect::getIntersectionPrimary
float getIntersectionPrimary(int edgeInd) const
Definition
Projections.cpp:324
b
b
Definition
compositor_morphological_distance_infos.hh:24
normalize
VecBase< float, D > normalize(VecOp< float, D >) RET
sqrt
#define sqrt
Definition
gpu_shader_cxx_builtin.hh:119
min
#define min(a, b)
Definition
sort.cc:36
CubeProjection
Definition
Projections.h:63
CubeProjection::origin
int64_t origin
Definition
Projections.h:64
CubeProjection::max
int64_t max
Definition
Projections.h:66
CubeProjection::min
int64_t min
Definition
Projections.h:66
CubeProjection::edges
int64_t edges[3]
Definition
Projections.h:65
TriangleProjection
Definition
Projections.h:50
i
i
Definition
text_draw.cc:230
max
max
Definition
text_draw.cc:251
Generated on
for Blender by
doxygen
1.16.1