1#include <glm/gtc/type_ptr.hpp>
2#include "LoftedCrossSectionsSystem.h"
3#define COGS_TABLE_HOLLOW
4#include "LoftedCrossSectionsSystem_tables.h"
19void Cogs::Core::LoftedCrossSectionsSystem::hollowInitialize()
21 hollowCellClassCounts.resize(4 * 256);
23 for (
int caps = 0; caps < 4; caps++) {
24 for (
int code = 0; code < 256; code++) {
25 CellClassCounts counts = { 0, 0, 0, 0 };
28 int N = triangle_table_hollow[256 * caps + code].n;
29 unsigned char* indices = triangle_table_hollow[256 * caps + code].indices;
32 for (
int k = 0; k < N; k++) {
35 int b = (ix >> 3) & 0x7;
36 switch ((ix >> 6) & 0x3) {
61 hollowCellClassCounts[256 * caps + code] = counts;
68void Cogs::Core::LoftedCrossSectionsSystem::hollowOpenAlignedClassifySamples(vector<uint8_t>& inside,
70 const size_t pos_stride,
71 const vector<vec3>& spine,
76 inside.resize(2 * slices*samples);
77 for (
int j = 0; j < slices; j++) {
78 for (
int i = 0; i < samples; i++) {
80 const vec3 p0 = make_vec3(pos + pos_stride*(2 * (j*samples + i) + 0));
81 inside[2 * (j*samples + i) + 0] = dot(viewer - p0, p0 - spine[j]) <= 0.f;
83 const vec3 p1 = make_vec3(pos + pos_stride*(2 * (j*samples + i) + 1));
84 inside[2 * (j*samples + i) + 1] = dot(viewer - p1, p1 - spine[j]) <= 0.f;
91void Cogs::Core::LoftedCrossSectionsSystem::hollowOpenAlignedCountCellResources(
size_t& newVertices,
size_t& outIndices,
size_t& cutIndices,
92 vector<uint8_t>& classification,
94 const vector<uint8_t>& inside,
96 const int slices,
const int samples,
const bool doubleSeam)
98 classification.resize(slices*samples);
104 for (
int j = 1; j < slices - 2; j++) {
107 int which_caps = ((j == 1) ? 1 : 0) | ((j == (slices - 3)) ? 2 : 0);
110 for (
int i = 0; i < samples - (doubleSeam ? 1 : 0); i++) {
113 int ii = (i + 1) % samples;
116 int crn_vtx_ix[8] = {
117 2 * ((j + 0)*samples + i) + 0, 2 * ((j + 0)*samples + i) + 1,
118 2 * ((j + 0)*samples + ii) + 0, 2 * ((j + 0)*samples + ii) + 1,
119 2 * ((j + 1)*samples + i) + 0, 2 * ((j + 1)*samples + i) + 1,
120 2 * ((j + 1)*samples + ii) + 0, 2 * ((j + 1)*samples + ii) + 1
124 uint8_t code = (inside[crn_vtx_ix[0]] ? 1 : 0) | (inside[crn_vtx_ix[1]] ? 2 : 0) |
125 (inside[crn_vtx_ix[2]] ? 4 : 0) | (inside[crn_vtx_ix[3]] ? 8 : 0) |
126 (inside[crn_vtx_ix[4]] ? 16 : 0) | (inside[crn_vtx_ix[5]] ? 32 : 0) |
127 (inside[crn_vtx_ix[6]] ? 64 : 0) | (inside[crn_vtx_ix[7]] ? 128 : 0);
129 classification[j*samples + i] = code;
131 const CellClassCounts& counts = hollowCellClassCounts[256 * which_caps + code];
132 newVertices += counts.newVertices;
133 outIndices += counts.outIndices;
134 cutIndices += counts.cutIndices;
139void Cogs::Core::LoftedCrossSectionsSystem::hollowOpenAlignedSkin(vector<unsigned int>& outSurface,
140 vector<unsigned int>& cutSurface,
141 float* pos,
const size_t pos_stride,
142 float* tex,
const size_t tex_stride,
143 float* nrm,
const size_t nrm_stride,
144 const vector<uint8_t>& classification,
145 const vector<vec3>& spine,
147 const int slices,
const int samples,
const bool doubleSeam)
149 unsigned int newVertex = 2 * samples * slices;
150 unsigned int outIndex = 0;
151 unsigned int cutIndex = 0;
154 for (
int j = 1; j < slices - 2; j++) {
157 int which_caps = ((j == 1) ? 1 : 0) | ((j == (slices - 3)) ? 2 : 0);
160 for (
int i = 0; i < samples - (doubleSeam ? 1 : 0); i++) {
163 int ii = (i + 1) % samples;
166 int crn_vtx_ix[8] = {
167 2 * ((j + 0)*samples + i) + 0, 2 * ((j + 0)*samples + i) + 1,
168 2 * ((j + 0)*samples + ii) + 0, 2 * ((j + 0)*samples + ii) + 1,
169 2 * ((j + 1)*samples + i) + 0, 2 * ((j + 1)*samples + i) + 1,
170 2 * ((j + 1)*samples + ii) + 0, 2 * ((j + 1)*samples + ii) + 1
174 int code = classification[j*samples + i];
175 int N = triangle_table_hollow[256 * which_caps + code].n;
176 unsigned char* indices = triangle_table_hollow[256 * which_caps + code].indices;
179 for (
int k = 0; k < N; k++) {
181 int a = crn_vtx_ix[ix & 0x7];
182 int a_j = j + ((ix & 0x4) == 0 ? 0 : 1);
183 int b = crn_vtx_ix[(ix >> 3) & 0x7];
184 int b_j = j + (((ix >> 3) & 0x4) == 0 ? 0 : 1);
188 switch ((ix >> 6) & 0x3) {
191 outSurface[outIndex++] = a;
194 outSurface[outIndex++] = newVertex;
200 outSurface[outIndex++] = a - 2 * samples;
205 outSurface[outIndex++] = newVertex;
211 outSurface[outIndex++] = a + 2 * samples;
216 outSurface[outIndex++] = newVertex;
221 cutSurface[cutIndex++] = newVertex;
229 const vec3 ap = make_vec3(pos + pos_stride*a);
230 const vec3 bp = make_vec3(pos + pos_stride*b);
232 vec3 va = normalize(viewer - ap);
233 vec3 vb = normalize(viewer - bp);
234 vec3 na = normalize(ap - spine[a_j]);
235 vec3 nb = normalize(bp - spine[b_j]);
237 float fa = std::acos(glm::dot(va, na)) - float(M_PI_2);
238 float fb = std::acos(glm::dot(vb, nb)) - float(M_PI_2);
240 float fa = dot(va, na);
241 float fb = dot(vb, nb);
243 const float t = fa*fb < 0.f ? fa / (fa - fb) : (abs(fa) < abs(fb) ? 0.f : 1.f);
245 const vec3 p = mix(ap, bp, t);
246 *
reinterpret_cast<vec3*
>(pos + pos_stride*newVertex) = p;
249 const vec2 at = make_vec2(tex + tex_stride*a);
250 const vec2 bt = make_vec2(tex + tex_stride*b);
251 *
reinterpret_cast<vec2*
>(tex + tex_stride*newVertex) = mix(at, bt, t);
255 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*newVertex) = normalize(viewer - p);
258 const vec3 an = make_vec3(nrm + nrm_stride*a);
259 const vec3 bn = make_vec3(nrm + nrm_stride*b);
260 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*newVertex) = mix(an, bn, t);
271void Cogs::Core::LoftedCrossSectionsSystem::hollowOpenCountCellResources(
size_t& newVertices,
size_t& outIndices,
size_t& cutIndices,
272 const int slices,
const int samples,
const bool doubleSeam)
274 const int cN = (samples - (doubleSeam ? 1 : 0)) / 2;
275 newVertices = 8 * (slices - 3);
276 outIndices = cN * 12 * (slices - 3) + cN * 6 + cN * 6;
277 cutIndices = 12 * (slices - 3);
280void Cogs::Core::LoftedCrossSectionsSystem::hollowOpenSkin(vector<unsigned int>& outSurface,
281 vector<unsigned int>& cutSurface,
282 float* pos,
const size_t pos_stride,
283 float* tex,
const size_t tex_stride,
284 float* nrm,
const size_t nrm_stride,
285 const int slices,
const int samples,
const bool doubleSeam)
287 const int cN = (samples - (doubleSeam ? 1 : 0)) / 2;
288 const int cuts[4 * 3] = {
289 2 * 0 + 0, 2 * 2 + 0, 2 * 1 + 0,
290 2 * 1 + 0, 2 * 2 + 0, 2 * 3 + 0,
291 2 * 0 + 1, 2 * 1 + 1, 2 * 2 + 1,
292 2 * 1 + 1, 2 * 3 + 1, 2 * 2 + 1
294 const int end0[2 * 3] = {
295 2 * 0 + 0, 2 * 0 + 1, 2 * 1 + 0,
296 2 * 0 + 1, 2 * 1 + 1, 2 * 1 + 0
298 const int end1[2 * 3] = {
299 2 * ((slices - 1)*samples + 0) + 0, 2 * ((slices - 1)*samples + 1) + 0, 2 * ((slices - 1)*samples + 0) + 1,
300 2 * ((slices - 1)*samples + 0) + 1, 2 * ((slices - 1)*samples + 1) + 0, 2 * ((slices - 1)*samples + 1) + 1
302 const int wall[12] = {
303 2 * (0 * samples + 0) + 0, 2 * (0 * samples + 1) + 0, 2 * (1 * samples + 0) + 0,
304 2 * (1 * samples + 1) + 0, 2 * (1 * samples + 0) + 0, 2 * (0 * samples + 1) + 0,
305 2 * (0 * samples + 0) + 1, 2 * (1 * samples + 0) + 1, 2 * (0 * samples + 1) + 1,
306 2 * (1 * samples + 1) + 1, 2 * (0 * samples + 1) + 1, 2 * (1 * samples + 0) + 1,
308 int cutVtxIx[3 * 2] = {
309 2 * 0, 2 * (samples - (doubleSeam ? 2 : 1)), 2 * 1,
310 2 * cN, 2 * (cN + 1), 2 * (cN - 1)
313 unsigned int newVertex = 2 * samples * slices;
314 unsigned int outIndex = 0;
315 unsigned int cutIndex = 0;
316 for (
int k = 1; k < slices - 2; k++) {
317 for (
int i = 0; i < cN; i++) {
318 for (
int q = 0; q < 12; q++) {
319 outSurface[outIndex++] = wall[q] + 2 * (i + k*samples);
322 int base = newVertex;
323 for (
int j = 0; j < 2; j++) {
324 for (
int i = 0; i < 2; i++) {
325 for (
int q = 0; q < 2; q++) {
326 int a = cutVtxIx[3 * q + 0] + i + 2 * samples*(k + j);
327 int b = cutVtxIx[3 * q + 1] + i + 2 * samples*(k + j);
328 int c = cutVtxIx[3 * q + 2] + i + 2 * samples*(k + j);
330 *
reinterpret_cast<vec3*
>(pos + pos_stride*newVertex) = *
reinterpret_cast<vec3*
>(pos + pos_stride*a);
332 *
reinterpret_cast<vec2*
>(tex + tex_stride*newVertex) = *
reinterpret_cast<vec2*
>(tex + tex_stride*a);
335 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*newVertex) = normalize(*
reinterpret_cast<vec3*
>(pos + pos_stride*b) - *
reinterpret_cast<vec3*
>(pos + pos_stride*c));
341 for (
int q = 0; q < 4 * 3; q++) {
342 cutSurface[cutIndex++] = cuts[q] + base;
346 for (
int i = 0; i < cN; i++) {
347 for (
int q = 0; q < 2 * 3; q++) {
348 outSurface[outIndex++] = end0[q] + 2 * i;
351 for (
int i = 0; i < cN; i++) {
352 for (
int q = 0; q < 2 * 3; q++) {
353 outSurface[outIndex++] = end1[q] + 2 * i;
359void Cogs::Core::LoftedCrossSectionsSystem::hollowClosedCountCellResources(
size_t& newVertices,
size_t& outIndices,
size_t& cutIndices,
360 const int slices,
const int samples,
const bool doubleSeam)
362 int Nk = slices - 2 - 1;
363 int Ni = (doubleSeam ? samples - 1 : samples);
365 outIndices = 4 * 3 * Ni*Nk + 2 * 3 * Ni + 2 * 3 * Ni;
369void Cogs::Core::LoftedCrossSectionsSystem::hollowClosedSkin(std::vector<unsigned int>& outSurface,
370 const int slices,
const int samples,
const bool doubleSeam)
372 unsigned int outIndex = 0;
374 for (
int k = 1; k < slices - 2; k++) {
375 for (
int i = 0; i < (doubleSeam ? samples - 1 : samples); i++) {
376 int ii = (i + 1) % samples;
378 outSurface[outIndex++] = 2 * ((k + 0)*samples + i) + 0;
379 outSurface[outIndex++] = 2 * ((k + 0)*samples + ii) + 0;
380 outSurface[outIndex++] = 2 * ((k + 1)*samples + i) + 0;
382 outSurface[outIndex++] = 2 * ((k + 1)*samples + ii) + 0;
383 outSurface[outIndex++] = 2 * ((k + 1)*samples + i) + 0;
384 outSurface[outIndex++] = 2 * ((k + 0)*samples + ii) + 0;
386 outSurface[outIndex++] = 2 * ((k + 0)*samples + i) + 1;
387 outSurface[outIndex++] = 2 * ((k + 1)*samples + i) + 1;
388 outSurface[outIndex++] = 2 * ((k + 0)*samples + ii) + 1;
390 outSurface[outIndex++] = 2 * ((k + 1)*samples + ii) + 1;
391 outSurface[outIndex++] = 2 * ((k + 0)*samples + ii) + 1;
392 outSurface[outIndex++] = 2 * ((k + 1)*samples + i) + 1;
396 for (
int i = 0; i < (doubleSeam ? samples - 1 : samples); i++) {
397 int k = (i + 1) % samples;
398 outSurface[outIndex++] = 2 * i + 0;
399 outSurface[outIndex++] = 2 * i + 1;
400 outSurface[outIndex++] = 2 * k + 0;
401 outSurface[outIndex++] = 2 * i + 1;
402 outSurface[outIndex++] = 2 * k + 1;
403 outSurface[outIndex++] = 2 * k + 0;
406 for (
int i = 0; i < (doubleSeam ? samples - 1 : samples); i++) {
407 int k = (i + 1) % samples;
408 outSurface[outIndex++] = 2 * ((slices - 1)*samples + i) + 0;
409 outSurface[outIndex++] = 2 * ((slices - 1)*samples + k) + 0;
410 outSurface[outIndex++] = 2 * ((slices - 1)*samples + i) + 1;
411 outSurface[outIndex++] = 2 * ((slices - 1)*samples + i) + 1;
412 outSurface[outIndex++] = 2 * ((slices - 1)*samples + k) + 0;
413 outSurface[outIndex++] = 2 * ((slices - 1)*samples + k) + 1;