1#include <glm/gtc/type_ptr.hpp>
2#include "LoftedCrossSectionsSystem.h"
3#define COGS_TABLE_SHELL
4#include "LoftedCrossSectionsSystem_tables.h"
17void Cogs::Core::LoftedCrossSectionsSystem::shellInitialize()
19 shellCellClassCounts.resize(16);
20 for (
int code = 0; code < 16; code++) {
21 CellClassCounts counts = { 0, 0, 0, 0 };
23 int N = triangle_table_shell[code].n;
24 unsigned char* indices = triangle_table_shell[code].indices;
25 for (
int l = 0; l < N; l++) {
26 int ix_a = indices[l] & 0x3;
27 int ix_b = (indices[l] >> 4) & 0x3;
36 shellCellClassCounts[code] = counts;
41void Cogs::Core::LoftedCrossSectionsSystem::shellOpenAlignedClassifySamples(vector<uint8_t>& inside,
42 const float* pos,
const size_t pos_stride,
43 const vector<vec3>& spine,
45 const int slices,
const int samples)
47 inside.resize(slices*samples);
48 for (
int j = 0; j < slices; j++) {
49 for (
int i = 0; i < samples; i++) {
50 const vec3 p = make_vec3(pos + pos_stride*(j*samples + i));
51 inside[j*samples + i] = dot(viewer - p, p - spine[j]) <= 0.0f;
56void Cogs::Core::LoftedCrossSectionsSystem::shellOpenAlignedCountCellResources(
size_t& newVertices,
58 vector<uint8_t>& classification,
60 const vector<uint8_t>& inside,
62 const int slices,
const int samples,
const bool doubleSeam)
64 classification.resize(slices*samples);
68 for (
int k = 0; k < slices - 1; k++) {
69 for (
int i = 0; i < (doubleSeam ? samples - 1 : samples); i++) {
70 int ii = (i + 1) % samples;
71 uint8_t code = ((inside[(k + 0)*samples + i] ? 1 : 0) |
72 (inside[(k + 0)*samples + ii] ? 2 : 0) |
73 (inside[(k + 1)*samples + i] ? 4 : 0) |
74 (inside[(k + 1)*samples + ii] ? 8 : 0));
76 classification[k*samples + i] = code;
77 const CellClassCounts& counts = shellCellClassCounts[code];
78 outIndices += counts.outIndices;
79 newVertices += counts.newVertices;
85void Cogs::Core::LoftedCrossSectionsSystem::shellOpenAlignedSkin(vector<unsigned int>& outSurface,
86 float* pos,
const size_t pos_stride,
87 float* tex,
const size_t tex_stride,
88 float* nrm,
const size_t nrm_stride,
89 const vector<uint8_t>& classification,
90 const vector<vec3>& spine,
92 const int slices,
const int samples,
const bool doubleSeam)
94 unsigned int newVertex = samples * slices;
95 unsigned int outIndex = 0;
97 for (
int k = 0; k < slices - 1; k++) {
98 for (
int i = 0; i < (doubleSeam ? samples - 1 : samples); i++) {
99 int ii = (i + 1) % samples;
101 (k + 0)*samples + i, (k + 0)*samples + ii,
102 (k + 1)*samples + i, (k + 1)*samples + ii,
105 int code = classification[k*samples + i];
107 int N = triangle_table_shell[code].n;
108 unsigned char* indices = triangle_table_shell[code].indices;
109 for (
int l = 0; l < N; l++) {
110 int ix_a = indices[l] & 0x3;
111 int ix_b = (indices[l] >> 4) & 0x3;
113 outSurface[outIndex++] = ix[ix_a];
118 int a_j = k + ((ix_a & 0x2) == 0 ? 0 : 1);
119 int b_j = k + ((ix_b & 0x2) == 0 ? 0 : 1);
121 const vec3 ap = make_vec3(pos + pos_stride*a);
122 const vec3 bp = make_vec3(pos + pos_stride*b);
124 vec3 va = normalize(viewer - ap);
125 vec3 vb = normalize(viewer - bp);
126 vec3 na = normalize(ap - spine[a_j]);
127 vec3 nb = normalize(bp - spine[b_j]);
129 float fa = std::acos(glm::dot(va, na)) - float(M_PI_2);
130 float fb = std::acos(glm::dot(vb, nb)) - float(M_PI_2);
132 float fa = dot(va, na);
133 float fb = dot(vb, nb);
135 const float t = fa*fb < 0.f ? fa / (fa - fb) : (abs(fa) < abs(fb) ? 0.f : 1.f);
137 const vec3 p = mix(ap, bp, t);
138 *
reinterpret_cast<vec3*
>(pos + pos_stride*newVertex) = p;
141 const vec2 at = make_vec2(tex + tex_stride*a);
142 const vec2 bt = make_vec2(tex + tex_stride*b);
143 *
reinterpret_cast<vec2*
>(tex + tex_stride*newVertex) = mix(at, bt, t);
146 const vec3 an = make_vec3(nrm + nrm_stride*a);
147 const vec3 bn = make_vec3(nrm + nrm_stride*b);
148 *
reinterpret_cast<vec3*
>(nrm + nrm_stride*newVertex) = mix(an, bn, t);
151 outSurface[outIndex++] = newVertex++;
158void Cogs::Core::LoftedCrossSectionsSystem::shellOpenCountCellResources(
size_t& outIndices,
159 const int slices,
const int samples,
160 const bool doubleSeam)
162 int cN = (samples - (doubleSeam ? 1 : 0)) / 2;
163 outIndices = 6 * cN*(slices - 1);
167void Cogs::Core::LoftedCrossSectionsSystem::shellOpenSkin(vector<unsigned int>& outSurface,
170 const bool doubleSeam)
172 int cN = (samples - (doubleSeam ? 1 : 0)) / 2;
173 unsigned int outIndex = 0;
174 for (
int k = 0; k < slices - 1; k++) {
175 for (
int i = 0; i < cN; i++) {
176 int ii = (i + 1) % samples;
178 outSurface[outIndex++] = (k + 0)*samples + i;
179 outSurface[outIndex++] = (k + 0)*samples + ii;
180 outSurface[outIndex++] = (k + 1)*samples + i;
182 outSurface[outIndex++] = (k + 1)*samples + ii;
183 outSurface[outIndex++] = (k + 1)*samples + i;
184 outSurface[outIndex++] = (k + 0)*samples + ii;
189void Cogs::Core::LoftedCrossSectionsSystem::shellClosedCountCellResources(
size_t& outIndices,
190 const int slices,
const int samples,
191 const bool doubleSeam)
193 int cN = (samples - (doubleSeam ? 1 : 0));
194 outIndices = 6 * cN*(slices - 1);
198void Cogs::Core::LoftedCrossSectionsSystem::shellClosedSkin(vector<unsigned int>& outSurface,
201 const bool doubleSeam)
203 int cN = (samples - (doubleSeam ? 1 : 0));
204 unsigned int outIndex = 0;
205 for (
int k = 0; k < slices - 1; k++) {
206 for (
int i = 0; i < cN; i++) {
207 int ii = (i + 1) % samples;
209 outSurface[outIndex++] = (k + 0)*samples + i;
210 outSurface[outIndex++] = (k + 0)*samples + ii;
211 outSurface[outIndex++] = (k + 1)*samples + i;
213 outSurface[outIndex++] = (k + 1)*samples + ii;
214 outSurface[outIndex++] = (k + 1)*samples + i;
215 outSurface[outIndex++] = (k + 0)*samples + ii;