1#include <glm/gtc/type_ptr.hpp>
2#include "LoftedCrossSectionsSystem.h"
3#define COGS_TABLE_SOLID
4#include "LoftedCrossSectionsSystem_tables.h"
17void Cogs::Core::LoftedCrossSectionsSystem::solidInitialize()
19 solidCellClassCounts.resize(4 * 256);
21 for (
int caps = 0; caps < 4; caps++) {
22 for (
int code = 0; code < 256; code++) {
23 CellClassCounts counts = { 0, 0, 0, 0 };
26 int N = triangle_table_solid[256 * caps + code].n;
27 unsigned char* indices = triangle_table_solid[256 * caps + code].indices;
28 for (
int k = 0; k < N; k++) {
32 int ix_b = (ix >> 3) & 0x7;
34 switch ((ix >> 6) & 0x3) {
47 if ((ix_a & 0x1) == 0) {
64 if ((ix_a & 0x1) == 0) {
89 solidCellClassCounts[256 * caps + code] = counts;
96void Cogs::Core::LoftedCrossSectionsSystem::solidOpenAlignedClassifySamples(std::vector<uint8_t>& inside,
97 const float* pos,
const size_t pos_stride,
98 const std::vector<glm::vec3>& spine,
99 const glm::vec3& viewer,
103 inside.resize(2*slices*samples);
104 for (
int j = 0; j < slices; j++) {
105 for (
int i = 0; i < samples; i++) {
106 const vec3 p = make_vec3(pos + pos_stride*(j*samples + i));
107 const glm::vec3 n = p - spine[j];
108 inside[2 * (j*samples + i) + 0] = glm::dot(viewer - p, n) <= 0.0f;
109 inside[2 * (j*samples + i) + 1] = glm::dot(viewer - spine[j], n) <= 0.0f;
114void Cogs::Core::LoftedCrossSectionsSystem::solidOpenAlignedCountCellResources(
size_t& newVertices,
size_t& outIndices,
size_t& cutIndices,
115 std::vector<uint8_t>& classification,
116 const std::vector<glm::vec3>& ,
117 const std::vector<uint8_t>& inside,
119 const int slices,
const int samples,
const bool doubleSeam)
121 classification.resize(samples*slices);
126 for (
int j = 1; j < slices - 2; j++) {
127 int which_caps = (j == 1 ? 1 : 0) | (j == (slices - 3) ? 2 : 0);
129 for (
int i = 0; i < samples - (doubleSeam ? 1 : 0); i++) {
130 int ii = (i + 1) % samples;
131 int crn_vtx_ix[4] = {
132 (j + 0)*samples + i, (j + 0)*samples + ii,
133 (j + 1)*samples + i, (j + 1)*samples + ii,
136 uint8_t code = (inside[2 * crn_vtx_ix[0] + 0] ? 1 : 0) |
137 (inside[2 * crn_vtx_ix[0] + 1] ? 2 : 0) |
138 (inside[2 * crn_vtx_ix[1] + 0] ? 4 : 0) |
139 (inside[2 * crn_vtx_ix[1] + 1] ? 8 : 0) |
140 (inside[2 * crn_vtx_ix[2] + 0] ? 16 : 0) |
141 (inside[2 * crn_vtx_ix[2] + 1] ? 32 : 0) |
142 (inside[2 * crn_vtx_ix[3] + 0] ? 64 : 0) |
143 (inside[2 * crn_vtx_ix[3] + 1] ? 128 : 0);
145 classification[j*samples + i] = code;
147 const CellClassCounts& counts = solidCellClassCounts[256 * which_caps + code];
148 newVertices += counts.newVertices;
149 outIndices += counts.outIndices;
150 cutIndices += counts.cutIndices;
157void Cogs::Core::LoftedCrossSectionsSystem::solidOpenAlignedSkin(std::vector<unsigned int>& outSurface,
158 std::vector<unsigned int>& ,
159 float* pos,
const size_t pos_stride,
160 float* tex,
const size_t tex_stride,
161 float* nrm,
const size_t nrm_stride,
162 const std::vector<uint8_t>& classification,
163 const std::vector<glm::vec3>& spine,
164 const glm::vec3& viewer,
165 const int slices,
const int samples,
const bool doubleSeam)
167 unsigned int newVertex = samples * slices;
168 unsigned int outIndex = 0;
171 for (
int j = 1; j < slices - 2; j++) {
173 int which_caps = (j == 1 ? 1 : 0) | (j == (slices - 3) ? 2 : 0);
176 for (
int i = 0; i < samples - (doubleSeam ? 1 : 0); i++) {
179 int ii = (i + 1) % samples;
181 int crn_vtx_ix[4] = {
182 (j + 0)*samples + i, (j + 0)*samples + ii,
183 (j + 1)*samples + i, (j + 1)*samples + ii,
186 int code = classification[j*samples + i];
188 int N = triangle_table_solid[256 * which_caps + code].n;
189 unsigned char* indices = triangle_table_solid[256 * which_caps + code].indices;
190 for (
int k = 0; k < N; k++) {
193 int ix_b = (ix >> 3) & 0x7;
195 int a = crn_vtx_ix[ix_a >> 1];
196 int a_j = j + ((ix & 0x4) == 0 ? 0 : 1);
197 int b = crn_vtx_ix[ix_b >> 1];
198 int b_j = j + (((ix >> 3) & 0x4) == 0 ? 0 : 1);
200 const float* paPtr = pos + pos_stride*a;
201 const float* pbPtr = pos + pos_stride*b;
203 bool createVertex =
false;
206 switch ((ix >> 6) & 0x3) {
210 outSurface[outIndex++] = a;
213 na = make_vec3(paPtr) - spine[a_j];
214 nb = make_vec3(paPtr) - spine[b_j];
222 if ((ix_a & 0x1) == 0) {
223 outSurface[outIndex++] = a;
226 paPtr =
reinterpret_cast<const float*
>(spine.data() + 0);
233 paPtr = pos + pos_stride*a;
234 pbPtr = pos + pos_stride*b;
235 na = make_vec3(paPtr) - spine[0];
236 nb = make_vec3(pbPtr) - spine[0];
237 if (ix_a & 0x1) { paPtr =
reinterpret_cast<const float*
>(spine.data() + 0); }
238 if (ix_b & 0x1) { pbPtr =
reinterpret_cast<const float*
>(spine.data() + 0); }
246 if ((ix_a & 0x1) == 0) {
247 outSurface[outIndex++] = a;
250 paPtr =
reinterpret_cast<const float*
>(spine.data() + slices - 1);
257 paPtr = pos + pos_stride*a;
258 pbPtr = pos + pos_stride*b;
259 na = make_vec3(paPtr) - spine[slices - 1];
260 nb = make_vec3(pbPtr) - spine[slices - 1];
261 if (ix_a & 0x1) { paPtr =
reinterpret_cast<const float*
>(spine.data() + slices - 1); }
262 if (ix_b & 0x1) { pbPtr =
reinterpret_cast<const float*
>(spine.data() + slices - 1); }
268 na = make_vec3(paPtr) - spine[j + (ix_a >> 2)];
269 nb = make_vec3(pbPtr) - spine[j + (ix_b >> 2)];
270 if (ix_a & 0x1) { paPtr =
reinterpret_cast<const float*
>(spine.data() + j + (ix_a >> 2)); }
271 if (ix_b & 0x1) { pbPtr =
reinterpret_cast<const float*
>(spine.data() + j + (ix_b >> 2)); }
282 vec3 pa = make_vec3(paPtr);
285 vec3 pb = make_vec3(pbPtr);
287 float fa = std::acos(dot(normalize(viewer - pa), normalize(na))) - float(M_PI_2);
288 float fb = std::acos(dot(normalize(viewer - pb), normalize(nb))) - float(M_PI_2);
290 float fa = dot(normalize(viewer - pa), normalize(na));
291 float fb = dot(normalize(viewer - pb), normalize(nb));
293 t = fa*fb < 0.f ? fa / (fa - fb) : (abs(fa) < abs(fb) ? 0.f : 1.f);
296 *
reinterpret_cast<vec3*
>(pos + pos_stride*newVertex) = pa;
299 vec2 vt = make_vec2(tex + tex_stride*a);
301 vt = mix(vt, make_vec2(tex + tex_stride*b), t);
303 *
reinterpret_cast<vec2*
>(tex + tex_stride*newVertex) = vt;
307 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*newVertex) = normalize(viewer - pa);
310 vec3 vn = make_vec3(nrm + nrm_stride*a);
312 vn = mix(vn, make_vec3(nrm + nrm_stride*b), t);
314 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*newVertex) = vn;
318 outSurface[outIndex++] = newVertex;
328void Cogs::Core::LoftedCrossSectionsSystem::solidOpenCountCellResources(
size_t& newVertices,
size_t& outIndices,
size_t& cutIndices,
329 const int slices,
const int samples,
const bool doubleSeam)
331 int cN = (samples - (doubleSeam ? 1 : 0)) / 2;
332 newVertices = 4 * slices + 2 * (cN + 1) + 2 * (cN + 1);
333 outIndices = 6 * cN*(slices - 2 - 1) + 3 * cN + 3 * cN;
334 cutIndices = 4 * 3 * (slices - 2 - 1);
338void Cogs::Core::LoftedCrossSectionsSystem::solidOpenSkin(vector<unsigned int>& outSurface, vector<unsigned int>& cutSurface,
339 float* pos,
const size_t pos_stride,
340 float* tex,
const size_t tex_stride,
341 float* nrm,
const size_t nrm_stride,
342 const vector<vec3>& spine,
343 const int slices,
const int samples,
const bool doubleSeam)
345 const int doubleSeamCut[4 * 3] = {
346 4 * 0 + 0, 4 * 1 + 0, 4 * 0 + 1,
347 4 * 1 + 0, 4 * 1 + 1, 4 * 0 + 1,
348 4 * 0 + 2, 4 * 1 + 2, 4 * 0 + 3,
349 4 * 1 + 2, 4 * 1 + 3, 4 * 0 + 3
352 int cN = (samples - (doubleSeam ? 1 : 0)) / 2;
354 unsigned int newVertex = samples * slices;
355 unsigned int outIndex = 0;
356 unsigned int cutIndex = 0;
358 for (
int k = 1; k < slices - 2; k++) {
359 for (
int i = 0; i < cN; i++) {
360 int ii = (i + 1) % samples;
362 outSurface[outIndex++] = (k + 0)*samples + i;
363 outSurface[outIndex++] = (k + 0)*samples + ii;
364 outSurface[outIndex++] = (k + 1)*samples + i;
366 outSurface[outIndex++] = (k + 1)*samples + ii;
367 outSurface[outIndex++] = (k + 1)*samples + i;
368 outSurface[outIndex++] = (k + 0)*samples + ii;
373 for (
int k = 1; k < slices - 2; k++) {
374 for (
int q = 0; q < 4 * 3; q++) {
375 cutSurface[cutIndex++] = doubleSeamCut[q] + 4 * k + newVertex;
379 for (
int j = 0; j < slices; j++) {
380 const vec3 q0 = make_vec3(pos + pos_stride*(j*samples + samples - 1));
381 const vec3 p0 = make_vec3(pos + pos_stride*(j*samples + 0));
382 const vec3 l0 = make_vec3(pos + pos_stride*(j*samples + 1));
383 const vec3 n0 = normalize(q0 - l0);
385 const vec3 q2 = make_vec3(pos + pos_stride*(j*samples + cN + 1));
386 const vec3 p2 = make_vec3(pos + pos_stride*(j*samples + cN));
387 const vec3 l2 = make_vec3(pos + pos_stride*(j*samples + cN - 1));
388 const vec3 n2 = normalize(q2 - l2);
390 const vec3& p1 = spine[j];
391 const vec3 n1 = normalize(n0 + n2);
393 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 0)) = p0;
394 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 1)) = p1;
395 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2)) = p1;
396 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 3)) = p2;
398 const vec2 t0 = make_vec2(tex + tex_stride*(j*samples + 0));
399 const vec2 t2 = make_vec2(tex + tex_stride*(j*samples + cN));
400 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 0)) = t0;
401 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 1)) = t0;
402 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2)) = t2;
403 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 3)) = t2;
406 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 0)) = n0;
407 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 1)) = n1;
408 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2)) = n1;
409 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 3)) = n2;
415 for (
int i = 0; i < cN; i++) {
417 outSurface[outIndex++] = newVertex + 2 * k + 0;
418 outSurface[outIndex++] = newVertex + 2 * i + 0;
419 outSurface[outIndex++] = newVertex + 2 * i + 1;
422 for (
int i = 0; i <= cN; i++) {
423 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2 * i + 0)) = make_vec3(pos + pos_stride*i);
424 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2 * i + 1)) = spine[0];
427 const vec3 n = normalize(spine[0] - spine[2]);
428 for (
int i = 0; i <= cN; i++) {
429 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2 * i + 0)) = n;
430 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2 * i + 1)) = n;
434 for (
int i = 0; i <= cN; i++) {
435 const vec2 t = make_vec2(tex + tex_stride*i);
436 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2 * i + 0)) = t;
437 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2 * i + 1)) = t;
440 newVertex += 2 * (cN + 1);
443 for (
int i = 0; i < cN; i++) {
445 outSurface[outIndex++] = newVertex + 2 * i + 0;
446 outSurface[outIndex++] = newVertex + 2 * k + 0;
447 outSurface[outIndex++] = newVertex + 2 * i + 1;
450 for (
int i = 0; i <= cN; i++) {
451 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2 * i + 0)) = make_vec3(pos + pos_stride*((slices - 1)*samples + i));
452 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2 * i + 1)) = spine[slices - 1];
455 const vec3 n = normalize(spine[slices - 1] - spine[slices - 3]);
456 for (
int i = 0; i <= cN; i++) {
457 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2 * i + 0)) = n;
458 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2 * i + 1)) = n;
462 for (
int i = 0; i <= cN; i++) {
463 const vec2 t = make_vec2(tex + tex_stride*((slices - 1)*samples + i));
464 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2 * i + 0)) = t;
465 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2 * i + 1)) = t;
468 newVertex += 2 * (cN + 1);
472void Cogs::Core::LoftedCrossSectionsSystem::solidClosedCountCellResources(
size_t& newVertices,
size_t& outIndices,
473 const int slices,
const int samples,
const bool doubleSeam)
475 int cN = (samples - (doubleSeam ? 1 : 0));
476 newVertices = 2 * (cN + 1) + 2 * (cN + 1);
477 outIndices = 6 * cN*(slices - 2 - 1) + 3 * cN + 3 * cN;
481void Cogs::Core::LoftedCrossSectionsSystem::solidClosedSkin(vector<unsigned int>& outSurface,
482 float* pos,
const size_t pos_stride,
483 float* tex,
const size_t tex_stride,
484 float* nrm,
const size_t nrm_stride,
485 const vector<vec3>& spine,
486 const int slices,
const int samples,
const bool doubleSeam)
489 int cN = (samples - (doubleSeam ? 1 : 0));
491 unsigned int newVertex = samples * slices;
492 unsigned int outIndex = 0;
494 for (
int k = 1; k < slices - 2; k++) {
495 for (
int i = 0; i < cN; i++) {
496 int ii = (i + 1) % samples;
498 outSurface[outIndex++] = (k + 0)*samples + i;
499 outSurface[outIndex++] = (k + 0)*samples + ii;
500 outSurface[outIndex++] = (k + 1)*samples + i;
502 outSurface[outIndex++] = (k + 1)*samples + ii;
503 outSurface[outIndex++] = (k + 1)*samples + i;
504 outSurface[outIndex++] = (k + 0)*samples + ii;
509 for (
int i = 0; i < cN; i++) {
510 int k = (i + 1) % samples;
511 outSurface[outIndex++] = newVertex + 2 * k + 0;
512 outSurface[outIndex++] = newVertex + 2 * i + 0;
513 outSurface[outIndex++] = newVertex + 2 * i + 1;
516 for (
int i = 0; i <= cN; i++) {
517 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2 * i + 0)) = make_vec3(pos + pos_stride*i);
518 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2 * i + 1)) = spine[0];
521 const vec3 n = normalize(spine[0] - spine[2]);
522 for (
int i = 0; i <= cN; i++) {
523 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2 * i + 0)) = n;
524 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2 * i + 1)) = n;
528 for (
int i = 0; i <= cN; i++) {
529 const vec2 t = make_vec2(tex + tex_stride*i);
530 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2 * i + 0)) = t;
531 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2 * i + 1)) = t;
534 newVertex += 2 * (cN + 1);
537 for (
int i = 0; i < cN; i++) {
538 int k = (i + 1) % samples;
539 outSurface[outIndex++] = newVertex + 2 * i + 0;
540 outSurface[outIndex++] = newVertex + 2 * k + 0;
541 outSurface[outIndex++] = newVertex + 2 * i + 1;
544 for (
int i = 0; i <= cN; i++) {
545 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2 * i + 0)) = make_vec3(pos + pos_stride*((slices - 1)*samples + i));
546 *
reinterpret_cast<vec3*
>(pos + pos_stride*(newVertex + 2 * i + 1)) = spine[slices - 1];
549 const vec3 n = normalize(spine[slices - 1] - spine[slices - 3]);
550 for (
int i = 0; i <= cN; i++) {
551 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2 * i + 0)) = n;
552 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*(newVertex + 2 * i + 1)) = n;
556 for (
int i = 0; i <= cN; i++) {
557 const vec2 t = make_vec2(tex + tex_stride*((slices - 1)*samples + i));
558 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2 * i + 0)) = t;
559 *
reinterpret_cast<vec2*
>(tex + tex_stride*(newVertex + 2 * i + 1)) = t;
562 newVertex += 2 * (cN + 1);