Cogs.Core
CommandHelpers.cpp
1#include "Context.h"
2#include "EntityStore.h"
3
4#include "Resources/Mesh.h"
5#include "Resources/MaterialInstance.h"
6#include "Resources/MeshManager.h"
7
8#include "Platform/Instrumentation.h"
9
10#include "CommandHelpers.h"
11
12namespace {
13 using namespace Cogs::Core;
14
15
16 template<typename T>
18 {
19 dst.resize(src.size());
20 if (src.size()) {
21 std::memcpy(dst.data(), src.data(), src.byteSize());
22 }
23
24 }
25
26
27 struct PrefixItem
28 {
30 uint32_t index;
31 };
32
33
34 void recordPrefix(std::vector<PrefixItem>& prefix, Cogs::Core::MeshItems& items)
35 {
36 // Hierarchy already updated, nothing to do.
37 if (prefix.back().index != ~0u) return;
38
39 // Make sure hierarchy is recorded, from root to leaf
40 for (size_t i = 0; i < prefix.size(); i++) {
41 if (prefix[i].index == ~0u) {
42 prefix[i].index = uint32_t(items.transforms.size());
43 items.transforms.emplace_back(TransformItem{ prefix[i].trComp, i == 0 ? ~0u : prefix[i - 1].index });
44 }
45 }
46 }
47
48 void getMeshItems_(std::vector<PrefixItem>& prefix, MeshItems& items, EntityPtr entity, uint32_t primitiveTypeMask);
49
50 void descend(std::vector<PrefixItem>& prefix, MeshItems& items, EntityPtr entity, uint32_t primitiveTypeMask)
51 {
52 auto * sceneComp = entity->getComponent<SceneComponent>();
53 if (!sceneComp) return;
54
55 // Add hierarchy to prefix.
57 if (trComp) prefix.emplace_back(PrefixItem{ trComp, ~0u });
58
59 for (auto & child : sceneComp->children) {
60 getMeshItems_(prefix, items, child, primitiveTypeMask);
61 }
62
63 if (trComp) prefix.pop_back();
64 }
65
66
67 void extract(std::vector<PrefixItem>& prefix, MeshItems& items, EntityPtr entity, uint32_t primitiveTypeMask)
68 {
69 if (auto meshComp = Cogs::ComponentModel::ComponentPtr<MeshComponent>(entity); meshComp && meshComp->meshHandle) {
70 if (((1 << meshComp->meshHandle->primitiveType) & primitiveTypeMask) != 0) {
71 if (auto meshRenderComp = Cogs::ComponentModel::ComponentPtr<MeshRenderComponent>(entity)) {
72
73 items.meshes.emplace_back(MeshItem{ meshComp->meshHandle, meshComp, meshRenderComp, meshRenderComp->material.resolve(), meshRenderComp->startIndex, meshRenderComp->vertexCount, ~0u });
74
75 if (!prefix.empty()) {
76 recordPrefix(prefix, items);
77 items.meshes.back().parent = prefix.back().index;
78 }
79 }
80 }
81 }
82 }
83
84
85 void getMeshItems_(std::vector<PrefixItem>& prefix, MeshItems& items, EntityPtr entity, uint32_t primitiveTypeMask)
86 {
87 descend(prefix, items, entity, primitiveTypeMask);
88 extract(prefix, items, entity, primitiveTypeMask);
89 }
90
91
92 void getMeshItems_(Context* context, std::vector<PrefixItem>& prefix, MeshItems& items, EntityIds entities, uint32_t primitiveTypeMask)
93 {
94 for (auto & entity : entities) {
95 auto entityPtr = context->store->getEntity(entity);
96 if (entityPtr) {
97 getMeshItems_(prefix, items, entityPtr, primitiveTypeMask);
98 }
99 }
100 }
101
102 void copy(TransformComponent* dstTrComp, const TransformComponent* srcTrComp)
103 {
104 dstTrComp->coordinates = srcTrComp->coordinates;
105 dstTrComp->transform = srcTrComp->transform;
106 dstTrComp->transformFlags = srcTrComp->transformFlags;
107 dstTrComp->setChanged();
108 }
109
110 void createNodeHierarchy(Context* context, std::vector<Cogs::ComponentModel::ComponentPtr<SceneComponent>>& hierarchy, EntityPtr parent, const std::vector<TransformItem>& transforms)
111 {
112 hierarchy.resize(transforms.size());
113
114 for (size_t i = 0; i < transforms.size(); i++) {
115 auto srcTrComp = transforms[i].trComp;
116
117 auto entity = context->store->createEntity(srcTrComp->getContainer()->getName(), "Group", false);
119
120 if (transforms[i].parent == ~0u) {
121 context->store->addChild(parent.get(), entity);
122 }
123 else {
124 assert(transforms[i].parent < i);
125 context->store->addChild(hierarchy[transforms[i].parent]->getContainer(), entity);
126 }
127
128 copy(entity->getComponent<TransformComponent>(), srcTrComp.get());
129 }
130 }
131
132 void createMeshResources(Context* context, std::vector<Cogs::ComponentModel::Entity*>& entities, std::vector<MeshHandle>& originalMeshes, MeshReps& meshes)
133 {
134 assert(entities.size() == meshes.size());
135 assert(entities.size() == originalMeshes.size());
136
137 for (size_t j = 0; j < meshes.size(); j++) {
138 const auto & meshRep = meshes[j];
139
140 auto * meshComp = entities[j]->getComponent<MeshComponent>();
141 if (meshRep.positions.size() == 0) {
143 continue;
144 }
145 meshComp->meshHandle = context->meshManager->create();
146 meshComp->setChanged();
147
148 auto * mesh = meshComp->meshHandle.resolve();
149
150 auto bbox = Cogs::Geometry::makeEmptyBoundingBox<Cogs::Geometry::BoundingBox>();
151 for (size_t i = 0; i < meshRep.positions.size(); i++) {
152 bbox.min = glm::min(bbox.min, meshRep.positions[i]);
153 bbox.max = glm::max(bbox.max, meshRep.positions[i]);
154 }
155 mesh->setBounds(bbox);
156
157 mesh->setPositions(meshRep.positions.data(), meshRep.positions.data() + meshRep.positions.size());
158 if (meshRep.normals.size() != 0) {
159 mesh->setNormals(meshRep.normals.data(), meshRep.normals.data() + meshRep.normals.size());
160 }
161 if (meshRep.texcoords.size() != 0) {
162 mesh->setTexCoords(meshRep.texcoords.data(), meshRep.texcoords.data() + meshRep.texcoords.size());
163 }
164 if (meshRep.tangents.size() != 0) {
165 mesh->setTangents(meshRep.tangents.data(), meshRep.tangents.data() + meshRep.tangents.size());
166 }
167 if (meshRep.indices.size() != 0) {
168 mesh->setIndexData(meshRep.indices.data(), meshRep.indices.size());
169 }
170
171 auto * originalMesh = originalMeshes[j].resolve();
172 if (originalMesh->isMeshFlagSet(MeshFlags::ClockwiseWinding)) {
173 mesh->setMeshFlag(MeshFlags::ClockwiseWinding);
174 }
175 else {
176 mesh->unsetMeshFlag(MeshFlags::ClockwiseWinding);
177 }
178
179 mesh->primitiveType = originalMesh->primitiveType;
180
181 auto * meshRndComp = entities[j]->getComponent<MeshRenderComponent>();
182 meshRndComp->startIndex = 0;
183 meshRndComp->vertexCount = (uint32_t)-1;
184 meshRndComp->setChanged();
185 }
186 }
187
188
189 void createMeshNodes(Context* context, const std::vector<Cogs::ComponentModel::ComponentPtr<SceneComponent>>& hierarchy, Cogs::ComponentModel::Entity* parent, std::vector<MeshHandle>& originalMeshes, const std::vector<MeshItem>& meshItems, MeshReps& meshes)
190 {
191 std::vector<Cogs::ComponentModel::Entity*> entities(meshes.size());
192 for (size_t i = 0; i < meshItems.size(); i++) {
193 auto & item = meshItems[i];
194
195 auto * meshEntityParent = parent;
196 if (item.parent != (uint32_t)-1) {
197 assert(item.parent < hierarchy.size());
198 meshEntityParent = hierarchy[item.parent]->getContainer();
199 }
200
201 auto entity = context->store->createChildEntity("MeshPart", meshEntityParent, item.meshComp->getContainer()->getName());
202 entities[i] = entity.get();
203
204 copy(entity->getComponent<TransformComponent>(), item.meshComp->getComponent<TransformComponent>());
205
206 auto * meshRndComp = entity->getComponent<MeshRenderComponent>();
207 meshRndComp->material = item.meshComp->getComponent<MeshRenderComponent>()->material;
208 meshRndComp->setChanged();
209 }
210
211 createMeshResources(context, entities, originalMeshes, meshes);
212
213 }
214}
215
216EntityPtr Cogs::Core::createNewMeshItems(Context* context, Cogs::ComponentModel::Entity* parent, std::vector<MeshHandle>& originalMeshes, MeshReps& meshes, MeshItems& items)
217{
218 // FIXME: No need to create a group if the hierarchy already have a single root node.
219 auto group = context->store->createEntity("", "Group", parent == nullptr);
220 if (parent) {
221 context->store->addChild(parent, group);
222 }
223
224 std::vector<Cogs::ComponentModel::ComponentPtr<SceneComponent>> hierarchy;
225 createNodeHierarchy(context, hierarchy, group, items.transforms);
226 createMeshNodes(context, hierarchy, group.get(), originalMeshes, items.meshes, meshes);
227 return group;
228}
229
230
231EntityPtr Cogs::Core::createAsSingleMeshItem(Context* context, Cogs::ComponentModel::Entity* parent, std::vector<MeshHandle>& originalMeshes, MeshReps& meshes, MeshItems& items)
232{
233
234 auto entity = context->store->createChildEntity("MeshPart", parent, "Combined");
235 auto * meshComp = entity->getComponent<MeshComponent>();
236 meshComp->meshHandle = context->meshManager->create();
237 meshComp->setChanged();
238
239 auto * mesh = meshComp->meshHandle.resolve();
240
241 size_t Vn = 0;
242 size_t Nn = 0;
243 size_t Tn = 0;
244 size_t Xn = 0;
245 size_t In = 0;
246 for(auto & meshRep : meshes) {
247 Vn += meshRep.positions.size();
248 Nn += meshRep.normals.size();
249 Tn += meshRep.tangents.size();
250 Xn += meshRep.texcoords.size();
251 In += meshRep.indices.size();
252 }
253
254 MeshRep singleRep;
255 singleRep.positions.resize(Vn, false);
256 singleRep.normals.resize(Nn, false);
257 singleRep.tangents.resize(Tn, false);
258 singleRep.texcoords.resize(Xn, false);
259 singleRep.indices.resize(In, false);
260
261
262 size_t Vo = 0;
263 size_t No = 0;
264 size_t To = 0;
265 size_t Xo = 0;
266 size_t Io = 0;
267
268 for (size_t j = 0; j < meshes.size(); j++) {
269 const auto & meshRep = meshes[j];
270
271 if (meshRep.positions.size() == 0) continue;
272
273 auto lIn = meshRep.indices.size();
274 if (lIn) {
275 for (size_t i = 0; i < lIn; i++) {
276 singleRep.indices[Io + i] = meshRep.indices[i] + uint32_t(Vo);
277 }
278 Io += lIn;
279 }
280
281 auto lVn = meshRep.positions.size();
282 std::memcpy(singleRep.positions.data() + Vo, meshRep.positions.data(), sizeof(glm::vec3)*lVn);
283 Vo += lVn;
284
285 // FIXME: Assumes no transforms! Not a valid assumption.
286
287 auto lNn = meshRep.normals.size();
288 if (lNn) {
289 std::memcpy(singleRep.normals.data() + No, meshRep.normals.data(), sizeof(glm::vec3)*lNn);
290 No += lNn;
291 }
292
293 auto lTn = meshRep.tangents.size();
294 if (lTn) {
295 std::memcpy(singleRep.tangents.data() + To, meshRep.tangents.data(), sizeof(glm::vec3)*lTn);
296 To += lTn;
297 }
298
299 auto lXn = meshRep.texcoords.size();
300 if (lXn) {
301 std::memcpy(singleRep.texcoords.data() + Xo, meshRep.texcoords.data(), sizeof(glm::vec2)*lXn);
302 Xo += lXn;
303 }
304
305 }
306
307 auto bbox = Cogs::Geometry::makeEmptyBoundingBox<Cogs::Geometry::BoundingBox>();
308 for (size_t i = 0; i < singleRep.positions.size(); i++) {
309 bbox.min = glm::min(bbox.min, singleRep.positions[i]);
310 bbox.max = glm::max(bbox.max, singleRep.positions[i]);
311 }
312 mesh->setBounds(bbox);
313
314 mesh->setPositions(singleRep.positions.data(), singleRep.positions.data() + singleRep.positions.size());
315 if (singleRep.normals.size() != 0) {
316 mesh->setNormals(singleRep.normals.data(), singleRep.normals.data() + singleRep.normals.size());
317 }
318 if (singleRep.texcoords.size() != 0) {
319 mesh->setTexCoords(singleRep.texcoords.data(), singleRep.texcoords.data() + singleRep.texcoords.size());
320 }
321 if (singleRep.tangents.size() != 0) {
322 mesh->setTangents(singleRep.tangents.data(), singleRep.tangents.data() + singleRep.tangents.size());
323 }
324 if (singleRep.indices.size() != 0) {
325 mesh->setIndexData(singleRep.indices.data(), singleRep.indices.size());
326 }
327
328 auto * originalMesh = originalMeshes[0].resolve();
329 if (originalMesh->isMeshFlagSet(MeshFlags::ClockwiseWinding)) {
330 mesh->setMeshFlag(MeshFlags::ClockwiseWinding);
331 }
332 else {
333 mesh->unsetMeshFlag(MeshFlags::ClockwiseWinding);
334 }
335
336 mesh->primitiveType = originalMesh->primitiveType;
337
338 auto * meshRndComp = entity->getComponent<MeshRenderComponent>();
339 meshRndComp->material = items.meshes.front().meshRenderComp->material;
340 meshRndComp->startIndex = 0;
341 meshRndComp->vertexCount = (uint32_t)-1;
342 meshRndComp->setChanged();
343
344 return entity;
345}
346
347
348void Cogs::Core::MeshRep::copy(const MeshRep & other)
349{
350 CpuInstrumentationScope(SCOPE_EDITOR_COMMAND, "MeshRepCopy");
351 ::copy(positions, other.positions);
352 ::copy(normals, other.normals);
353 ::copy(texcoords, other.texcoords);
354 ::copy(tangents, other.tangents);
355 ::copy(indices, other.indices);
356}
357
358
359void Cogs::Core::getMeshItems(Context* /*context*/, MeshItems& items, EntityPtr entity, uint32_t primitiveTypeMask)
360{
361 std::vector<PrefixItem> prefix;
362 getMeshItems_(prefix, items, entity, primitiveTypeMask);
363
364 //if (auto * sceneComp = entity->getComponent<SceneComponent>(); sceneComp) {
365 // for (auto & child : sceneComp->children) {
366 // getMeshItems(context, items, child.get(), primitiveTypeMask);
367 // }
368 //}
369 //if (auto * meshComp = entity->getComponent<MeshComponent>(); meshComp && meshComp->meshHandle) {
370 // if (((1 << meshComp->meshHandle->primitiveType) & primitiveTypeMask) != 0) {
371 // if (auto * meshRenderComp = entity->getComponent<MeshRenderComponent>(); meshRenderComp) {
372 // items.emplace_back(MeshItem{ meshComp, meshRenderComp, meshRenderComp->material.resolve(), meshRenderComp->startIndex, meshRenderComp->vertexCount });
373 // }
374 // }
375 //}
376}
377
378void Cogs::Core::getMeshItems(Context* context, MeshItems& items, Cogs::Core::EntityIds entities, uint32_t primitiveTypeMask)
379{
380 std::vector<PrefixItem> prefix;
381 getMeshItems_(context, prefix, items, entities, primitiveTypeMask);
382
383 //for (auto & entity : entities) {
384 // getMeshItems(context, items, context->store->getEntityPtr(entity), primitiveTypeMask);;
385 //}
386}
387
388void Cogs::Core::remapVertices(Context* /*context*/, MeshRep& rep, const std::vector<uint32_t>& unique)
389{
390 CpuInstrumentationScope(SCOPE_EDITOR_COMMAND, "remapVertices");
391
392 Memory::MemoryBuffer tmp(unique.size() * sizeof(float) * 4);
393
394 // FIXME: check for identity.
395
396 if (rep.positions.size() != 0) {
397 auto * P = reinterpret_cast<glm::vec3*>(tmp.data());
398 for (size_t i = 0; i < unique.size(); i++) {
399 P[i] = rep.positions[unique[i]];
400 }
401 rep.positions.resize(unique.size(), false);
402 std::memcpy(rep.positions.data(), tmp.data(), rep.positions.byteSize());
403 }
404 if (rep.normals.size()) {
405 auto * N = reinterpret_cast<glm::vec3*>(tmp.data());
406 for (size_t i = 0; i < unique.size(); i++) {
407 N[i] = rep.normals[unique[i]];
408 }
409 rep.normals.resize(unique.size(), false);
410 std::memcpy(rep.normals.data(), tmp.data(), rep.normals.byteSize());
411 }
412 if (rep.texcoords.size()) {
413 auto * T = reinterpret_cast<glm::vec2*>(tmp.data());
414 for (size_t i = 0; i < unique.size(); i++) {
415 T[i] = rep.texcoords[unique[i]];
416 }
417 rep.texcoords.resize(unique.size(), false);
418 std::memcpy(rep.texcoords.data(), tmp.data(), rep.texcoords.byteSize());
419 }
420 if (rep.tangents.size()) {
421 auto * T = reinterpret_cast<glm::vec3*>(tmp.data());
422 for (size_t i = 0; i < unique.size(); i++) {
423 T[i] = rep.tangents[unique[i]];
424 }
425 rep.tangents.resize(unique.size(), false);
426 std::memcpy(rep.tangents.data(), tmp.data(), rep.tangents.byteSize());
427 }
428}
429
430void Cogs::Core::remapIndices(Context* /*context*/, MeshRep& rep, const std::vector<uint32_t>& map)
431{
432 if (rep.indices.size() == 0) return;
433
434 CpuInstrumentationScope(SCOPE_EDITOR_COMMAND, "remapIndices");
435
436 Memory::TypedBuffer<uint32_t> tmp(rep.indices.size());
437 std::memcpy(tmp.data(), rep.indices.data(), tmp.byteSize());
438
439 for (size_t i = 0; i < rep.indices.size(); i++) {
440 rep.indices[i] = map[tmp[i]];
441 }
442
443}
444
445
446
447void Cogs::Core::unpackMeshItems(Context* context, std::vector<MeshHandle>& originalMeshes, MeshReps& meshes, MeshItems& items, UnpackOptions options)
448{
449 CpuInstrumentationScope(SCOPE_EDITOR_COMMAND, "unpackMeshItems");
450
451 originalMeshes.clear();
452
453 meshes.clear();
454 for (auto item : items.meshes) {
455 MeshRep mesh;
456
457 originalMeshes.push_back(item.mesh);
458
459 auto srcMesh = item.mesh.resolve();
460
461 srcMesh->copyData(mesh.positions, Cogs::ElementSemantic::Position, Cogs::DataFormat::X32Y32Z32_FLOAT);
462 if (options.discardNormals == false) {
463 srcMesh->copyData(mesh.normals, Cogs::ElementSemantic::Normal, Cogs::DataFormat::X32Y32Z32_FLOAT);
464 }
465 assert(mesh.normals.size() == 0 || mesh.normals.size() == mesh.positions.size());
466
467 if (options.discardTexCoords == false) {
468 srcMesh->copyData(mesh.texcoords, Cogs::ElementSemantic::TextureCoordinate, Cogs::DataFormat::X32Y32_FLOAT);
469 }
470 assert(mesh.texcoords.size() == 0 || mesh.texcoords.size() == mesh.positions.size());
471
472 if (options.discardTangents == false) {
473 srcMesh->copyData(mesh.tangents, Cogs::ElementSemantic::Tangent, Cogs::DataFormat::X32Y32Z32_FLOAT);
474 }
475 assert(mesh.tangents.size() == 0 || mesh.tangents.size() == mesh.positions.size());
476
477 uint32_t maxVertexCount = static_cast<uint32_t>(mesh.positions.size());
478 uint32_t maxIndex = std::max(uint32_t(1), maxVertexCount) - 1u;
479 auto indexes = srcMesh->getIndexes();
480
481 if (!indexes.empty()) {
482 uint32_t maxIndexCount = static_cast<uint32_t>(indexes.size());
483 uint32_t maxIndexOffset = std::max(uint32_t(1), maxIndexCount) - 1;
484 uint32_t rangeOffset = std::min(maxIndexOffset, item.offset);
485 uint32_t maxRangeCount = std::max(rangeOffset, maxIndexCount) - rangeOffset;
486 uint32_t rangeCount = std::min(maxRangeCount, item.count);
487
488 mesh.indices.resize(rangeCount, false);
489 if (rangeOffset != 0 || rangeCount != maxIndexCount) {
490
491 // Extract sub-range
492 std::vector<uint32_t> unique;
493 unique.reserve(indexes.size());
494
495 std::vector<uint32_t> map(indexes.size(), ~0u);
496
497 for (uint32_t i = 0; i < rangeCount; i++) {
498 auto ix0 = indexes[rangeOffset + i];
499 auto ix1 = map[ix0];
500 if (ix1 == ~0u) {
501 ix1 = static_cast<uint32_t>(unique.size());
502 unique.push_back(ix0);
503 map[ix0] = ix1;
504 }
505 mesh.indices[i] = ix1;
506 }
507 remapVertices(context, mesh, unique);
508 }
509 else {
510 std::memcpy(mesh.indices.data(), indexes.data(), sizeof(uint32_t)*indexes.size());
511 }
512 }
513 else {
514 uint32_t rangeOffset = std::min(maxIndex, item.offset);
515 uint32_t maxRangeCount = std::max(rangeOffset, maxVertexCount) - rangeOffset;
516 uint32_t rangeCount = std::min(maxRangeCount, item.count);
517
518 // Optionally restrict to sub-range.
519 if (rangeCount != maxVertexCount) {
520 if (rangeOffset != 0) {
521 std::memmove(mesh.positions.data(), mesh.positions.data() + rangeOffset, rangeCount * 3 * sizeof(float));
522 if (mesh.normals.size() != 0) std::memmove(mesh.normals.data(), mesh.normals.data() + rangeOffset, rangeCount * 3 * sizeof(float));
523 if (mesh.texcoords.size() != 0) std::memmove(mesh.positions.data(), mesh.positions.data() + rangeOffset, rangeCount * 2 * sizeof(float));
524 if (mesh.tangents.size() != 0) std::memmove(mesh.tangents.data(), mesh.tangents.data() + rangeOffset, rangeCount * 3 * sizeof(float));
525 }
526 mesh.positions.resize(rangeCount);
527 if (mesh.normals.size() != 0) mesh.normals.resize(rangeCount);
528 if (mesh.texcoords.size() != 0) mesh.texcoords.resize(rangeCount);
529 if (mesh.tangents.size() != 0) mesh.tangents.resize(rangeCount);
530 }
531
532 if (options.forceIndexed) {
533 mesh.indices.resize(mesh.positions.size(), false);
534 for (size_t i = 0; i < mesh.indices.size(); i++) {
535 mesh.indices[i] = static_cast<uint32_t>(i);
536 }
537
538 }
539 }
540 meshes.push_back(std::move(mesh));
541 }
542}
543
544
545void Cogs::Core::packMeshItems(Context* context, std::vector<MeshHandle>& originalMeshes, MeshReps& meshes, MeshItems& items, bool update)
546{
547 CpuInstrumentationScope(SCOPE_EDITOR_COMMAND, "packMeshItems");
548
549 if (update) {
550 std::vector<Cogs::ComponentModel::Entity*> entities(items.meshes.size());
551
552 for (size_t i = 0; i < entities.size(); i++) {
553 entities[i] = items.meshes[i].meshComp->getContainer();
554 }
555 createMeshResources(context, entities, originalMeshes, meshes);
556
557#if 0
558 for (size_t i = 0; i < items.meshes.size(); i++) {
559 const auto & item = items.meshes[i];
560 const auto & meshRep = meshes[i];
561 auto * originalMesh = originalMeshes[i].resolve();
562
563 if (meshRep.positions.size() == 0) {
564 item.meshComp->meshHandle = MeshHandle::NoHandle;
565 continue;
566 }
567
568 item.meshComp->meshHandle = context->meshManager->create();
569 item.meshComp->setChanged();
570
571 auto * newMesh = items.meshes[i].meshComp->meshHandle.resolve();
572
573 newMesh->setPositions(meshRep.positions.data(), meshRep.positions.data() + meshRep.positions.size());
574 if (meshRep.normals.size() != 0) {
575 newMesh->setNormals(meshRep.normals.data(), meshRep.normals.data() + meshRep.normals.size());
576 }
577 if (meshRep.texcoords.size() != 0) {
578 newMesh->setTexCoords(meshRep.texcoords.data(), meshRep.texcoords.data() + meshRep.texcoords.size());
579 }
580 if (meshRep.tangents.size() != 0) {
581 newMesh->setTangents(meshRep.tangents.data(), meshRep.tangents.data() + meshRep.tangents.size());
582 }
583 if (meshRep.indices.size() != 0) {
584 newMesh->setIndexData(meshRep.indices.data(), meshRep.indices.size());
585 }
586
587 if (originalMesh->isMeshFlagSet(MeshFlags::ClockwiseWinding)) {
588 newMesh->setMeshFlag(MeshFlags::ClockwiseWinding);
589 }
590 else {
591 newMesh->unsetMeshFlag(MeshFlags::ClockwiseWinding);
592 }
593 newMesh->primitiveType = originalMesh->primitiveType;
594
595 item.meshRenderComp->startIndex = 0;
596 item.meshRenderComp->vertexCount = ~0;
597 item.meshRenderComp->setChanged();
598 }
599#endif
600
601 }
602 else if(!originalMeshes.empty()) {
603 for (size_t i = 0; i < items.meshes.size(); i++) {
604 const auto & item = items.meshes[i];
605
606 item.meshComp->meshHandle = originalMeshes[i];
607 item.meshComp->setChanged();
608
609 item.meshRenderComp->startIndex = item.offset;
610 item.meshRenderComp->vertexCount = item.count;
611 item.meshRenderComp->setChanged();
612 }
613 }
614}
A shared_pointer type pointer to a component in an entity.
Definition: ComponentPtr.h:17
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
Definition: Component.h:202
ComponentType * getComponent() const
Definition: Component.h:159
class Entity * getContainer() const
Get the container currently owning this component instance.
Definition: Component.h:151
Container for components, providing composition of dynamic entities.
Definition: Entity.h:18
const std::string & getName() const noexcept
Get the name of this entity.
Definition: Entity.h:120
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
class EntityStore * store
Entity store.
Definition: Context.h:231
EntityPtr getEntity(const StringView &name, bool logIfNotFound=true) const
Retrieve a reference to the shared entity pointer to the Entity with the given name.
void addChild(ComponentModel::Entity *parent, const EntityPtr &entity)
Add a child to the given parent.
EntityPtr createChildEntity(const StringView &type, ComponentModel::Entity *parent, const StringView &name=StringView())
Create a new Entity, parenting it to the given parent.
EntityPtr createEntity(const StringView &name, const StringView &type, bool storeOwnership=true)
Create a new Entity.
Contains a handle to a Mesh resource to use when rendering using the MeshRenderComponent.
Definition: MeshComponent.h:15
MeshHandle meshHandle
Handle to a Mesh resource to use when rendering.
Definition: MeshComponent.h:29
Renders the contents of a MeshComponent using the given materials.
uint32_t startIndex
Start vertex index to render from.
MaterialInstanceHandle material
Material used to render the mesh.
Contains information on how the entity behaves in the scene.
Defines a 4x4 transformation matrix for the entity and a global offset for root entities.
uint32_t transformFlags
Transform flags.
glm::mat4 transform
Complete transformation.
glm::dvec3 coordinates
Global coordinates.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
Definition: EntityPtr.h:12
@ Position
Position semantic.
@ Tangent
Tangent semantic.
@ Normal
Normal semantic.
@ TextureCoordinate
Texture coordinate semantic.
@ ClockwiseWinding
The mesh uses clockwise winding order for it's triangles as opposed to the counter-clockwise default.
Definition: Mesh.h:63
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.