/src/tinyobjloader/tobj_tess_impl.inc
Line | Count | Source |
1 | | /* |
2 | | * tobj_tess_impl.inc -- per-precision projection + dispatch. |
3 | | * Included twice from tobj_tess.c. Do not include directly. |
4 | | */ |
5 | | |
6 | | /* Project the 3D ring into w->p2d (double). Returns 1 normally, 0 if the |
7 | | * polygon is fully degenerate (collinear/zero-area) and a bbox fallback was |
8 | | * used. Never fails. */ |
9 | | static int TOBJ_TESS_T(tobj_tess_project)(const TOBJ_TESS_REAL *pts, uint32_t n, |
10 | | const TOBJ_TESS_REAL *given_normal, |
11 | 32.3k | uint32_t flags, tobj_tess_work *w) { |
12 | 32.3k | double cx = (double)pts[0], cy = (double)pts[1], cz = (double)pts[2]; |
13 | 32.3k | double coordmax = 0.0; |
14 | 6.30M | for (uint32_t i = 0; i < 3u * n; i++) { |
15 | 6.27M | double a = tobj_dabs((double)pts[i]); |
16 | 6.27M | if (a > coordmax) coordmax = a; |
17 | 6.27M | } |
18 | | |
19 | 32.3k | double nx = 0, ny = 0, nz = 0; |
20 | 32.3k | if (flags & TOBJ_TESS_FLAG_NORMAL_GIVEN) { |
21 | 0 | nx = (double)given_normal[0]; |
22 | 0 | ny = (double)given_normal[1]; |
23 | 0 | nz = (double)given_normal[2]; |
24 | 32.3k | } else { |
25 | 2.12M | for (uint32_t k = 0; k < n; k++) { |
26 | 2.09M | uint32_t j = (k + 1u) % n; |
27 | 2.09M | double ax = (double)pts[3 * k], ay = (double)pts[3 * k + 1], |
28 | 2.09M | az = (double)pts[3 * k + 2]; |
29 | 2.09M | double bx = (double)pts[3 * j], by = (double)pts[3 * j + 1], |
30 | 2.09M | bz = (double)pts[3 * j + 2]; |
31 | 2.09M | nx += (ay - by) * (az + bz); |
32 | 2.09M | ny += (az - bz) * (ax + bx); |
33 | 2.09M | nz += (ax - bx) * (ay + by); |
34 | 2.09M | } |
35 | 32.3k | } |
36 | 32.3k | double len2 = nx * nx + ny * ny + nz * nz; |
37 | 32.3k | double cm2 = coordmax * coordmax; |
38 | 32.3k | double thresh = cm2 * cm2 * TOBJ_TESS_REL_N; |
39 | | |
40 | 32.3k | if (tobj_is_finite(len2) && len2 > thresh && len2 > 0.0) { |
41 | | /* in-plane basis (unnormalized: only orientation signs matter) */ |
42 | 9.92k | double wx = nx, wy = ny, wz = nz; |
43 | 9.92k | double ax = tobj_dabs(wx), ay = tobj_dabs(wy), az = tobj_dabs(wz); |
44 | 9.92k | double sx = 0, sy = 0, sz = 0; |
45 | 9.92k | if (ax <= ay && ax <= az) |
46 | 4.36k | sx = 1; |
47 | 5.56k | else if (ay <= az) |
48 | 5.11k | sy = 1; |
49 | 455 | else |
50 | 455 | sz = 1; |
51 | | /* u = w x s, v = w x u */ |
52 | 9.92k | double ux = wy * sz - wz * sy; |
53 | 9.92k | double uy = wz * sx - wx * sz; |
54 | 9.92k | double uz = wx * sy - wy * sx; |
55 | 9.92k | double vx = wy * uz - wz * uy; |
56 | 9.92k | double vy = wz * ux - wx * uz; |
57 | 9.92k | double vz = wx * uy - wy * ux; |
58 | 1.89M | for (uint32_t k = 0; k < n; k++) { |
59 | 1.88M | double dx = (double)pts[3 * k] - cx; |
60 | 1.88M | double dy = (double)pts[3 * k + 1] - cy; |
61 | 1.88M | double dz = (double)pts[3 * k + 2] - cz; |
62 | 1.88M | w->p2d[2 * k] = dx * ux + dy * uy + dz * uz; |
63 | 1.88M | w->p2d[2 * k + 1] = dx * vx + dy * vy + dz * vz; |
64 | 1.88M | } |
65 | 9.92k | return 1; |
66 | 9.92k | } |
67 | | |
68 | | /* Fallback: drop the smallest-extent axis, keep the other two raw axes. */ |
69 | 22.4k | double mn[3], mx[3]; |
70 | 22.4k | mn[0] = mx[0] = (double)pts[0]; |
71 | 22.4k | mn[1] = mx[1] = (double)pts[1]; |
72 | 22.4k | mn[2] = mx[2] = (double)pts[2]; |
73 | 227k | for (uint32_t k = 0; k < n; k++) { |
74 | 818k | for (int c = 0; c < 3; c++) { |
75 | 614k | double v = (double)pts[3 * k + c]; |
76 | 614k | if (v < mn[c]) mn[c] = v; |
77 | 614k | if (v > mx[c]) mx[c] = v; |
78 | 614k | } |
79 | 204k | } |
80 | 22.4k | double span[3] = {mx[0] - mn[0], mx[1] - mn[1], mx[2] - mn[2]}; |
81 | 22.4k | int drop = 0; |
82 | 22.4k | if (span[1] < span[0]) drop = 1; |
83 | 22.4k | if (span[2] < span[drop]) drop = 2; |
84 | 22.4k | int a0 = (drop == 0) ? 1 : 0; |
85 | 22.4k | int a1 = (drop == 2) ? 1 : 2; |
86 | 227k | for (uint32_t k = 0; k < n; k++) { |
87 | 204k | w->p2d[2 * k] = (double)pts[3 * k + a0] - (drop == 0 ? cy : cx); |
88 | 204k | w->p2d[2 * k + 1] = |
89 | 204k | (double)pts[3 * k + a1] - ((drop == 2) ? cy : cz); |
90 | 204k | } |
91 | 22.4k | return 0; |
92 | 32.3k | } tobj_tess.c:tobj_tess_project_f Line | Count | Source | 11 | 32.3k | uint32_t flags, tobj_tess_work *w) { | 12 | 32.3k | double cx = (double)pts[0], cy = (double)pts[1], cz = (double)pts[2]; | 13 | 32.3k | double coordmax = 0.0; | 14 | 6.30M | for (uint32_t i = 0; i < 3u * n; i++) { | 15 | 6.27M | double a = tobj_dabs((double)pts[i]); | 16 | 6.27M | if (a > coordmax) coordmax = a; | 17 | 6.27M | } | 18 | | | 19 | 32.3k | double nx = 0, ny = 0, nz = 0; | 20 | 32.3k | if (flags & TOBJ_TESS_FLAG_NORMAL_GIVEN) { | 21 | 0 | nx = (double)given_normal[0]; | 22 | 0 | ny = (double)given_normal[1]; | 23 | 0 | nz = (double)given_normal[2]; | 24 | 32.3k | } else { | 25 | 2.12M | for (uint32_t k = 0; k < n; k++) { | 26 | 2.09M | uint32_t j = (k + 1u) % n; | 27 | 2.09M | double ax = (double)pts[3 * k], ay = (double)pts[3 * k + 1], | 28 | 2.09M | az = (double)pts[3 * k + 2]; | 29 | 2.09M | double bx = (double)pts[3 * j], by = (double)pts[3 * j + 1], | 30 | 2.09M | bz = (double)pts[3 * j + 2]; | 31 | 2.09M | nx += (ay - by) * (az + bz); | 32 | 2.09M | ny += (az - bz) * (ax + bx); | 33 | 2.09M | nz += (ax - bx) * (ay + by); | 34 | 2.09M | } | 35 | 32.3k | } | 36 | 32.3k | double len2 = nx * nx + ny * ny + nz * nz; | 37 | 32.3k | double cm2 = coordmax * coordmax; | 38 | 32.3k | double thresh = cm2 * cm2 * TOBJ_TESS_REL_N; | 39 | | | 40 | 32.3k | if (tobj_is_finite(len2) && len2 > thresh && len2 > 0.0) { | 41 | | /* in-plane basis (unnormalized: only orientation signs matter) */ | 42 | 9.92k | double wx = nx, wy = ny, wz = nz; | 43 | 9.92k | double ax = tobj_dabs(wx), ay = tobj_dabs(wy), az = tobj_dabs(wz); | 44 | 9.92k | double sx = 0, sy = 0, sz = 0; | 45 | 9.92k | if (ax <= ay && ax <= az) | 46 | 4.36k | sx = 1; | 47 | 5.56k | else if (ay <= az) | 48 | 5.11k | sy = 1; | 49 | 455 | else | 50 | 455 | sz = 1; | 51 | | /* u = w x s, v = w x u */ | 52 | 9.92k | double ux = wy * sz - wz * sy; | 53 | 9.92k | double uy = wz * sx - wx * sz; | 54 | 9.92k | double uz = wx * sy - wy * sx; | 55 | 9.92k | double vx = wy * uz - wz * uy; | 56 | 9.92k | double vy = wz * ux - wx * uz; | 57 | 9.92k | double vz = wx * uy - wy * ux; | 58 | 1.89M | for (uint32_t k = 0; k < n; k++) { | 59 | 1.88M | double dx = (double)pts[3 * k] - cx; | 60 | 1.88M | double dy = (double)pts[3 * k + 1] - cy; | 61 | 1.88M | double dz = (double)pts[3 * k + 2] - cz; | 62 | 1.88M | w->p2d[2 * k] = dx * ux + dy * uy + dz * uz; | 63 | 1.88M | w->p2d[2 * k + 1] = dx * vx + dy * vy + dz * vz; | 64 | 1.88M | } | 65 | 9.92k | return 1; | 66 | 9.92k | } | 67 | | | 68 | | /* Fallback: drop the smallest-extent axis, keep the other two raw axes. */ | 69 | 22.4k | double mn[3], mx[3]; | 70 | 22.4k | mn[0] = mx[0] = (double)pts[0]; | 71 | 22.4k | mn[1] = mx[1] = (double)pts[1]; | 72 | 22.4k | mn[2] = mx[2] = (double)pts[2]; | 73 | 227k | for (uint32_t k = 0; k < n; k++) { | 74 | 818k | for (int c = 0; c < 3; c++) { | 75 | 614k | double v = (double)pts[3 * k + c]; | 76 | 614k | if (v < mn[c]) mn[c] = v; | 77 | 614k | if (v > mx[c]) mx[c] = v; | 78 | 614k | } | 79 | 204k | } | 80 | 22.4k | double span[3] = {mx[0] - mn[0], mx[1] - mn[1], mx[2] - mn[2]}; | 81 | 22.4k | int drop = 0; | 82 | 22.4k | if (span[1] < span[0]) drop = 1; | 83 | 22.4k | if (span[2] < span[drop]) drop = 2; | 84 | 22.4k | int a0 = (drop == 0) ? 1 : 0; | 85 | 22.4k | int a1 = (drop == 2) ? 1 : 2; | 86 | 227k | for (uint32_t k = 0; k < n; k++) { | 87 | 204k | w->p2d[2 * k] = (double)pts[3 * k + a0] - (drop == 0 ? cy : cx); | 88 | 204k | w->p2d[2 * k + 1] = | 89 | 204k | (double)pts[3 * k + a1] - ((drop == 2) ? cy : cz); | 90 | 204k | } | 91 | 22.4k | return 0; | 92 | 32.3k | } |
Unexecuted instantiation: tobj_tess.c:tobj_tess_project_d |
93 | | |
94 | | tobj_tess_status TOBJ_TESS_T(tobj_tess_polygon)( |
95 | 36.6k | const TOBJ_TESS_T(tobj_tess_desc) * desc, tobj_tess_result *result) { |
96 | 36.6k | result->indices = NULL; |
97 | 36.6k | result->num_triangles = 0; |
98 | 36.6k | result->indices_allocated = 0; |
99 | 36.6k | result->status = TOBJ_TESS_INVALID; |
100 | | |
101 | 36.6k | if (!desc || !desc->points) return TOBJ_TESS_INVALID; |
102 | 36.6k | uint32_t n = desc->n; |
103 | 36.6k | if (n < 3) return TOBJ_TESS_INVALID; |
104 | | |
105 | | /* reject non-finite coordinates */ |
106 | 6.33M | for (uint32_t i = 0; i < 3u * n; i++) { |
107 | 6.29M | if (!tobj_is_finite((double)desc->points[i])) return TOBJ_TESS_INVALID; |
108 | 6.29M | } |
109 | | |
110 | 32.3k | uint32_t tri = n - 2u; |
111 | 32.3k | uint32_t need_out = tri * 3u; |
112 | | |
113 | | /* resolve output buffer */ |
114 | 32.3k | uint32_t *out = NULL; |
115 | 32.3k | int out_alloc = 0; |
116 | 32.3k | if (desc->out_indices && desc->out_cap >= need_out) { |
117 | 32.3k | out = desc->out_indices; |
118 | 32.3k | } else if (desc->alloc && desc->alloc->alloc) { |
119 | 0 | out = (uint32_t *)desc->alloc->alloc(desc->alloc->ud, |
120 | 0 | need_out * sizeof(uint32_t)); |
121 | 0 | if (!out) { |
122 | 0 | result->status = TOBJ_TESS_OOM; |
123 | 0 | return TOBJ_TESS_OOM; |
124 | 0 | } |
125 | 0 | out_alloc = 1; |
126 | 0 | } else { |
127 | 0 | result->status = TOBJ_TESS_OOM; |
128 | 0 | return TOBJ_TESS_OOM; |
129 | 0 | } |
130 | | |
131 | | /* resolve scratch */ |
132 | 32.3k | size_t need_scratch = tobj_tess_scratch_size(n); |
133 | 32.3k | void *scratch = NULL; |
134 | 32.3k | int scratch_alloc = 0; |
135 | 32.3k | unsigned char stackbuf[TOBJ_TESS_STACK_BYTES]; |
136 | 32.3k | if (desc->scratch && desc->scratch_size >= need_scratch) { |
137 | 32.3k | scratch = desc->scratch; |
138 | 32.3k | } else if (n <= TOBJ_TESS_STACK_N && need_scratch <= sizeof(stackbuf)) { |
139 | 0 | scratch = stackbuf; |
140 | 0 | } else if (desc->alloc && desc->alloc->alloc) { |
141 | 0 | scratch = desc->alloc->alloc(desc->alloc->ud, need_scratch); |
142 | 0 | if (!scratch) { |
143 | 0 | if (out_alloc) desc->alloc->free(desc->alloc->ud, out); |
144 | 0 | result->status = TOBJ_TESS_OOM; |
145 | 0 | return TOBJ_TESS_OOM; |
146 | 0 | } |
147 | 0 | scratch_alloc = 1; |
148 | 0 | } else { |
149 | 0 | if (out_alloc && desc->alloc) desc->alloc->free(desc->alloc->ud, out); |
150 | 0 | result->status = TOBJ_TESS_OOM; |
151 | 0 | return TOBJ_TESS_OOM; |
152 | 0 | } |
153 | | |
154 | 32.3k | tobj_tess_work w; |
155 | 32.3k | tobj_tess_work_bind(&w, scratch, need_scratch, n); |
156 | | |
157 | 32.3k | int proj_ok = |
158 | 32.3k | TOBJ_TESS_T(tobj_tess_project)(desc->points, n, desc->normal, |
159 | 32.3k | desc->flags, &w); |
160 | | |
161 | 32.3k | tobj_tess_status status; |
162 | 32.3k | uint32_t k = 0; |
163 | | |
164 | 32.3k | if (n == 3) { |
165 | 0 | tobj_tess_emit(out, &k, 0, 1, 2); |
166 | 0 | double ar = tobj_dabs(tobj_orient2d(&w.p2d[0], &w.p2d[2], &w.p2d[4])); |
167 | 0 | double scale = tobj_tess_scale2d(w.p2d, n); |
168 | 0 | status = ar <= scale * scale * TOBJ_TESS_REL ? TOBJ_TESS_DEGENERATE_BESTEFFORT |
169 | 0 | : TOBJ_TESS_OK; |
170 | 32.3k | } else if (n == 4) { |
171 | 17.1k | double scale = tobj_tess_scale2d(w.p2d, n); |
172 | 17.1k | double eps = scale * scale * TOBJ_TESS_REL; |
173 | 17.1k | const double *p0 = &w.p2d[0], *p1 = &w.p2d[2], *p2 = &w.p2d[4], |
174 | 17.1k | *p3 = &w.p2d[6]; |
175 | 17.1k | double o012 = tobj_orient2d(p0, p1, p2); |
176 | 17.1k | double o023 = tobj_orient2d(p0, p2, p3); |
177 | 17.1k | double o123 = tobj_orient2d(p1, p2, p3); |
178 | 17.1k | double o130 = tobj_orient2d(p1, p3, p0); |
179 | 17.1k | int d02 = (tobj_dabs(o012) > eps && tobj_dabs(o023) > eps && |
180 | 4.51k | ((o012 > 0) == (o023 > 0))); |
181 | 17.1k | int d13 = (tobj_dabs(o123) > eps && tobj_dabs(o130) > eps && |
182 | 5.22k | ((o123 > 0) == (o130 > 0))); |
183 | 17.1k | int split02; |
184 | 17.1k | status = TOBJ_TESS_OK; |
185 | 17.1k | if (d02 && !d13) { |
186 | 564 | split02 = 1; |
187 | 16.5k | } else if (d13 && !d02) { |
188 | 1.11k | split02 = 0; |
189 | 15.4k | } else { |
190 | | /* convex (both internal) or degenerate (neither): shorter 3D diagonal */ |
191 | 15.4k | const TOBJ_TESS_REAL *q = desc->points; |
192 | 15.4k | double e02x = (double)q[6] - (double)q[0]; |
193 | 15.4k | double e02y = (double)q[7] - (double)q[1]; |
194 | 15.4k | double e02z = (double)q[8] - (double)q[2]; |
195 | 15.4k | double e13x = (double)q[9] - (double)q[3]; |
196 | 15.4k | double e13y = (double)q[10] - (double)q[4]; |
197 | 15.4k | double e13z = (double)q[11] - (double)q[5]; |
198 | 15.4k | double s02 = e02x * e02x + e02y * e02y + e02z * e02z; |
199 | 15.4k | double s13 = e13x * e13x + e13y * e13y + e13z * e13z; |
200 | 15.4k | split02 = s02 <= s13; |
201 | 15.4k | if (!d02 && !d13) status = TOBJ_TESS_DEGENERATE_BESTEFFORT; |
202 | 15.4k | } |
203 | 17.1k | if (split02) { |
204 | 8.31k | tobj_tess_emit(out, &k, 0, 1, 2); |
205 | 8.31k | tobj_tess_emit(out, &k, 0, 2, 3); |
206 | 8.83k | } else { |
207 | 8.83k | tobj_tess_emit(out, &k, 0, 1, 3); |
208 | 8.83k | tobj_tess_emit(out, &k, 1, 2, 3); |
209 | 8.83k | } |
210 | 17.1k | } else { |
211 | 15.2k | status = tobj_tess_run2d(&w, n, out, desc->flags); |
212 | 15.2k | } |
213 | | |
214 | 32.3k | if (!proj_ok && status == TOBJ_TESS_OK) status = TOBJ_TESS_DEGENERATE_BESTEFFORT; |
215 | | |
216 | 32.3k | if (scratch_alloc) desc->alloc->free(desc->alloc->ud, scratch); |
217 | | |
218 | 32.3k | result->indices = out; |
219 | 32.3k | result->num_triangles = tri; |
220 | 32.3k | result->indices_allocated = out_alloc; |
221 | 32.3k | result->status = status; |
222 | 32.3k | return status; |
223 | 32.3k | } Line | Count | Source | 95 | 36.6k | const TOBJ_TESS_T(tobj_tess_desc) * desc, tobj_tess_result *result) { | 96 | 36.6k | result->indices = NULL; | 97 | 36.6k | result->num_triangles = 0; | 98 | 36.6k | result->indices_allocated = 0; | 99 | 36.6k | result->status = TOBJ_TESS_INVALID; | 100 | | | 101 | 36.6k | if (!desc || !desc->points) return TOBJ_TESS_INVALID; | 102 | 36.6k | uint32_t n = desc->n; | 103 | 36.6k | if (n < 3) return TOBJ_TESS_INVALID; | 104 | | | 105 | | /* reject non-finite coordinates */ | 106 | 6.33M | for (uint32_t i = 0; i < 3u * n; i++) { | 107 | 6.29M | if (!tobj_is_finite((double)desc->points[i])) return TOBJ_TESS_INVALID; | 108 | 6.29M | } | 109 | | | 110 | 32.3k | uint32_t tri = n - 2u; | 111 | 32.3k | uint32_t need_out = tri * 3u; | 112 | | | 113 | | /* resolve output buffer */ | 114 | 32.3k | uint32_t *out = NULL; | 115 | 32.3k | int out_alloc = 0; | 116 | 32.3k | if (desc->out_indices && desc->out_cap >= need_out) { | 117 | 32.3k | out = desc->out_indices; | 118 | 32.3k | } else if (desc->alloc && desc->alloc->alloc) { | 119 | 0 | out = (uint32_t *)desc->alloc->alloc(desc->alloc->ud, | 120 | 0 | need_out * sizeof(uint32_t)); | 121 | 0 | if (!out) { | 122 | 0 | result->status = TOBJ_TESS_OOM; | 123 | 0 | return TOBJ_TESS_OOM; | 124 | 0 | } | 125 | 0 | out_alloc = 1; | 126 | 0 | } else { | 127 | 0 | result->status = TOBJ_TESS_OOM; | 128 | 0 | return TOBJ_TESS_OOM; | 129 | 0 | } | 130 | | | 131 | | /* resolve scratch */ | 132 | 32.3k | size_t need_scratch = tobj_tess_scratch_size(n); | 133 | 32.3k | void *scratch = NULL; | 134 | 32.3k | int scratch_alloc = 0; | 135 | 32.3k | unsigned char stackbuf[TOBJ_TESS_STACK_BYTES]; | 136 | 32.3k | if (desc->scratch && desc->scratch_size >= need_scratch) { | 137 | 32.3k | scratch = desc->scratch; | 138 | 32.3k | } else if (n <= TOBJ_TESS_STACK_N && need_scratch <= sizeof(stackbuf)) { | 139 | 0 | scratch = stackbuf; | 140 | 0 | } else if (desc->alloc && desc->alloc->alloc) { | 141 | 0 | scratch = desc->alloc->alloc(desc->alloc->ud, need_scratch); | 142 | 0 | if (!scratch) { | 143 | 0 | if (out_alloc) desc->alloc->free(desc->alloc->ud, out); | 144 | 0 | result->status = TOBJ_TESS_OOM; | 145 | 0 | return TOBJ_TESS_OOM; | 146 | 0 | } | 147 | 0 | scratch_alloc = 1; | 148 | 0 | } else { | 149 | 0 | if (out_alloc && desc->alloc) desc->alloc->free(desc->alloc->ud, out); | 150 | 0 | result->status = TOBJ_TESS_OOM; | 151 | 0 | return TOBJ_TESS_OOM; | 152 | 0 | } | 153 | | | 154 | 32.3k | tobj_tess_work w; | 155 | 32.3k | tobj_tess_work_bind(&w, scratch, need_scratch, n); | 156 | | | 157 | 32.3k | int proj_ok = | 158 | 32.3k | TOBJ_TESS_T(tobj_tess_project)(desc->points, n, desc->normal, | 159 | 32.3k | desc->flags, &w); | 160 | | | 161 | 32.3k | tobj_tess_status status; | 162 | 32.3k | uint32_t k = 0; | 163 | | | 164 | 32.3k | if (n == 3) { | 165 | 0 | tobj_tess_emit(out, &k, 0, 1, 2); | 166 | 0 | double ar = tobj_dabs(tobj_orient2d(&w.p2d[0], &w.p2d[2], &w.p2d[4])); | 167 | 0 | double scale = tobj_tess_scale2d(w.p2d, n); | 168 | 0 | status = ar <= scale * scale * TOBJ_TESS_REL ? TOBJ_TESS_DEGENERATE_BESTEFFORT | 169 | 0 | : TOBJ_TESS_OK; | 170 | 32.3k | } else if (n == 4) { | 171 | 17.1k | double scale = tobj_tess_scale2d(w.p2d, n); | 172 | 17.1k | double eps = scale * scale * TOBJ_TESS_REL; | 173 | 17.1k | const double *p0 = &w.p2d[0], *p1 = &w.p2d[2], *p2 = &w.p2d[4], | 174 | 17.1k | *p3 = &w.p2d[6]; | 175 | 17.1k | double o012 = tobj_orient2d(p0, p1, p2); | 176 | 17.1k | double o023 = tobj_orient2d(p0, p2, p3); | 177 | 17.1k | double o123 = tobj_orient2d(p1, p2, p3); | 178 | 17.1k | double o130 = tobj_orient2d(p1, p3, p0); | 179 | 17.1k | int d02 = (tobj_dabs(o012) > eps && tobj_dabs(o023) > eps && | 180 | 4.51k | ((o012 > 0) == (o023 > 0))); | 181 | 17.1k | int d13 = (tobj_dabs(o123) > eps && tobj_dabs(o130) > eps && | 182 | 5.22k | ((o123 > 0) == (o130 > 0))); | 183 | 17.1k | int split02; | 184 | 17.1k | status = TOBJ_TESS_OK; | 185 | 17.1k | if (d02 && !d13) { | 186 | 564 | split02 = 1; | 187 | 16.5k | } else if (d13 && !d02) { | 188 | 1.11k | split02 = 0; | 189 | 15.4k | } else { | 190 | | /* convex (both internal) or degenerate (neither): shorter 3D diagonal */ | 191 | 15.4k | const TOBJ_TESS_REAL *q = desc->points; | 192 | 15.4k | double e02x = (double)q[6] - (double)q[0]; | 193 | 15.4k | double e02y = (double)q[7] - (double)q[1]; | 194 | 15.4k | double e02z = (double)q[8] - (double)q[2]; | 195 | 15.4k | double e13x = (double)q[9] - (double)q[3]; | 196 | 15.4k | double e13y = (double)q[10] - (double)q[4]; | 197 | 15.4k | double e13z = (double)q[11] - (double)q[5]; | 198 | 15.4k | double s02 = e02x * e02x + e02y * e02y + e02z * e02z; | 199 | 15.4k | double s13 = e13x * e13x + e13y * e13y + e13z * e13z; | 200 | 15.4k | split02 = s02 <= s13; | 201 | 15.4k | if (!d02 && !d13) status = TOBJ_TESS_DEGENERATE_BESTEFFORT; | 202 | 15.4k | } | 203 | 17.1k | if (split02) { | 204 | 8.31k | tobj_tess_emit(out, &k, 0, 1, 2); | 205 | 8.31k | tobj_tess_emit(out, &k, 0, 2, 3); | 206 | 8.83k | } else { | 207 | 8.83k | tobj_tess_emit(out, &k, 0, 1, 3); | 208 | 8.83k | tobj_tess_emit(out, &k, 1, 2, 3); | 209 | 8.83k | } | 210 | 17.1k | } else { | 211 | 15.2k | status = tobj_tess_run2d(&w, n, out, desc->flags); | 212 | 15.2k | } | 213 | | | 214 | 32.3k | if (!proj_ok && status == TOBJ_TESS_OK) status = TOBJ_TESS_DEGENERATE_BESTEFFORT; | 215 | | | 216 | 32.3k | if (scratch_alloc) desc->alloc->free(desc->alloc->ud, scratch); | 217 | | | 218 | 32.3k | result->indices = out; | 219 | 32.3k | result->num_triangles = tri; | 220 | 32.3k | result->indices_allocated = out_alloc; | 221 | 32.3k | result->status = status; | 222 | 32.3k | return status; | 223 | 32.3k | } |
Unexecuted instantiation: tobj_tess_polygon_d |