1#include "IndexConversion.h"
7 #include "tesselator.h"
9 #include "libtess2/tesselator.h"
12#include "Resources/Mesh.h"
24void Cogs::Core::tesselate(
const glm::vec3* contours,
27 std::vector<uint32_t>& triangleIndexes,
29 const int polySize = 3;
30 TESStesselator* tess = tessNewTess(
nullptr);
32 tessAddContour(tess, polySize, contours,
static_cast<int>(stride),
static_cast<int>(count));
34 if (!tessTesselate(tess, TESS_WINDING_POSITIVE, TESS_POLYGONS, 3, 3,
nullptr)) {
38 const int elementCount = tessGetElementCount(tess);
39 const auto elements = tessGetElements(tess);
40 const auto indexes = tessGetVertexIndices(tess);
42 triangleIndexes.reserve(base + elementCount * polySize);
44 for (
int i = 0; i < elementCount; ++i) {
45 const auto poly = &elements[i * polySize];
48 uint32_t polyIndexes[polySize];
50 for (
int j = 0; j < polySize; ++j) {
51 const TESSindex index = indexes[poly[j]];
53 valid &= (index >= 0) && ((
size_t)index < count);
55 polyIndexes[j] = base +
static_cast<uint32_t
>(index);
59 triangleIndexes.insert(triangleIndexes.end(), std::begin(polyIndexes), std::end(polyIndexes));
66std::vector<int32_t> Cogs::Core::tesselatePolygons(std::vector<int32_t> & inputIndexes, Mesh * mesh)
68 if (inputIndexes.size()) {
69 std::vector<uint32_t> indexes;
70 size_t currentIndex = 0;
72 auto addPolygon = [&](
size_t base,
size_t numVertexes)
74 auto [data, count, stride] = mesh->getPositionStream();
76 std::vector<IndexedPosition> positions(numVertexes);
78 for (
size_t i = 0; i < numVertexes; ++i) {
79 const uint32_t index = inputIndexes[base + i];
80 assert(index < count &&
"Vertex index out of bounds.");
81 positions[i].index = index;
82 positions[i].position = *
reinterpret_cast<glm::vec3 *
>(data + index * stride);
85 std::vector<uint32_t> positionIndexes;
86 tesselate(
reinterpret_cast<const glm::vec3 *
>(positions.data()), numVertexes,
sizeof(IndexedPosition), positionIndexes);
88 for (
size_t i = 0; i < positionIndexes.size(); ++i) {
89 indexes.push_back(positions[positionIndexes[i]].index);
92 currentIndex = indexes.size();
96 while (idx < inputIndexes.size()) {
97 const size_t base = idx;
99 while (inputIndexes[idx++] != -1 && idx < inputIndexes.size()) {}
101 size_t numVertexes = idx - base - 1;
103 addPolygon(base, numVertexes);
106 std::vector<int32_t> output((indexes.size() / 3) * 4);
108 for (
size_t i = 0; i < indexes.size() / 3; ++i) {
109 output[i * 4 + 0] = indexes[i * 3 + 0];
110 output[i * 4 + 1] = indexes[i * 3 + 1];
111 output[i * 4 + 2] = indexes[i * 3 + 2];
112 output[i * 4 + 3] = -1;
118 return std::vector<int32_t>();
121void Cogs::Core::reindex(
const std::vector<int32_t> & inputIndexes, Mesh * mesh,
bool isLine)
123 if (inputIndexes.size()) {
124 std::vector<uint32_t> indexes;
125 size_t currentIndex = 0;
129 auto addTriangle = [&](
size_t base)
131 indexes.resize(indexes.size() + 3);
132 indexes[currentIndex++] = inputIndexes[base];
133 indexes[currentIndex++] = inputIndexes[base + 1];
134 indexes[currentIndex++] = inputIndexes[base + 2];
137 auto addQuad = [&](
size_t base)
139 indexes.resize(indexes.size() + 6);
140 indexes[currentIndex++] = inputIndexes[base];
141 indexes[currentIndex++] = inputIndexes[base + 1];
142 indexes[currentIndex++] = inputIndexes[base + 2];
144 indexes[currentIndex++] = inputIndexes[base];
145 indexes[currentIndex++] = inputIndexes[base + 2];
146 indexes[currentIndex++] = inputIndexes[base + 3];
149 auto addPolygon = [&](
size_t base,
size_t numVertexes)
151 auto [data, count, stride] = mesh->getPositionStream();
153 std::vector<IndexedPosition> positions(numVertexes);
155 for (
size_t i = 0; i < numVertexes; ++i) {
156 const uint32_t index = inputIndexes[base + i];
157 assert(index < count &&
"Vertex index out of bounds.");
158 positions[i].index = index;
159 positions[i].position = *
reinterpret_cast<glm::vec3 *
>(data + index * stride);
162 std::vector<uint32_t> positionIndexes;
163 tesselate(
reinterpret_cast<const glm::vec3 *
>(positions.data()), numVertexes,
sizeof(IndexedPosition), positionIndexes);
165 for (
size_t i = 0; i < positionIndexes.size(); ++i) {
166 indexes.push_back(positions[positionIndexes[i]].index);
169 currentIndex = indexes.size();
173 while (idx < inputIndexes.size()) {
174 const size_t base = idx;
176 while (inputIndexes[idx++] != -1 && idx < inputIndexes.size()) {}
178 size_t numVertexes = idx - base - 1;
180 if (numVertexes == 3) {
182 }
else if (numVertexes == 4) {
185 addPolygon(base, numVertexes);
189 for (
size_t i = 0; i < inputIndexes.size() - 1; ++i) {
190 if (inputIndexes[i] != -1 && inputIndexes[i + 1] != -1) {
191 indexes.push_back(inputIndexes[i]);
192 indexes.push_back(inputIndexes[i + 1]);
196 mesh->primitiveType = PrimitiveType::LineList;
199 mesh->setIndexData(indexes.data(), indexes.size());
Contains all Cogs related functionality.