Cogs.Core
InstancedModelSystem.cpp
1#include "InstancedModelSystem.h"
2
3#include "EntityStore.h"
4
5#include "Systems/Core/SceneSystem.h"
6#include "Systems/Core/TransformSystem.h"
7#include "Systems/Core/MeshSystem.h"
8#include "Systems/Core/InstancedMeshRenderSystem.h"
9
10#include "Resources/ModelManager.h"
11#include "Resources/MeshManager.h"
12#include "Resources/MaterialManager.h"
13
14#include "Services/DeferredNameResolution.h"
15
17{
18 for (auto & component : pool) {
19 auto & modelData = getData<InstancedModelData>(&component);
20
21 auto model = HandleIsValid(component.model) ? context->modelManager->get(component.model) : nullptr;
22
23 if (component.hasChanged() || model) {
24 if (model) {
25 if (model->isLoaded() && !modelData.isLoaded) {
26 bool ready = true;
27 for (auto & mesh : model->meshes) {
28 ready &= mesh->isActive();
29 }
30
31 if (ready) {
32 std::vector<EntityPtr> entities(model->parts.size());
33 std::vector<ComponentHandle> transformComponents(model->parts.size());
34 std::vector<ComponentHandle> sceneComponents(model->parts.size());
35
36 const auto groupId = hash("Group");
37 const auto meshPartId = hash("InstancedMeshPart");
38
39 auto store = context->store;
40 store->createEntities(model->parts.size(), entities);
41
42 for (size_t i = 0; i < model->parts.size(); ++i) {
43 const auto & part = model->parts[i];
44 auto & entity = entities[i];
45
46 auto partName = model->getPartName(part);
47 if (!partName.empty()) {
48 entity->setName(partName);
49 context->deferredResolution->scheduleRescan();
50 }
51
52 auto transformComponent = context->transformSystem->createComponent();
53 transformComponents[i] = transformComponent;
54
55 entity->addComponent(transformComponent);
56
57 sceneComponents[i] = context->sceneSystem->createComponent();
58 entity->addComponent(sceneComponents[i]);
59
60 if (part.parentIndex != NoParentPart) {
61 sceneComponents[part.parentIndex].resolveComponent<SceneComponent>()->children.emplace_back(entity);
62 transformComponent.resolveComponent<TransformComponent>()->parent = transformComponents[part.parentIndex];
63 } else {
64 context->store->addChild(component.getContainer(), entity);
65 }
66
67 EntityData* entityData = static_cast<EntityData *>(entity->getUserData());
68 entityData->templateId = (part.meshIndex != static_cast<uint32_t>(-1) ? meshPartId : groupId);
69
70 if (part.meshIndex != static_cast<uint32_t>(-1)) {
71 auto & mesh = model->meshes[part.meshIndex];
72
73 auto mcHandle = context->meshSystem->createComponent();
74 entity->addComponent(mcHandle);
75
76 auto meshComponent = mcHandle.resolveComponent<MeshComponent>();
77 meshComponent->meshHandle = mesh;
78 meshComponent->setChanged();
79
80 auto mrcHandle = context->instancedMeshRenderSystem->createComponent();
81 entity->addComponent(mrcHandle);
82
83 auto renderComponent = mrcHandle.resolveComponent<InstancedMeshRenderComponent>();
84 renderComponent->startIndex = part.startIndex;
85 renderComponent->vertexCount = part.vertexCount;
86 renderComponent->primitiveType = (PrimitiveType::EPrimitiveType)part.primitiveType;
87 renderComponent->instanceMesh = component.instanceMesh;
88
89 if (part.materialIndex >= model->materials.size()) {
90 continue;
91 }
92
93 auto & material = model->materials[part.materialIndex];
94 if (component.material) {
95 if (component.cloneModelMaterialProperties) {
96 renderComponent->material = context->materialInstanceManager->createMaterialInstance(component.material);
97
98 renderComponent->material->setPermutation(material->getPermutation());
99 renderComponent->material->instanceFlags = material->instanceFlags;
100 renderComponent->material->options = material->options;
101 renderComponent->material->cloneMatchingProperties(material.resolve());
102 renderComponent->material->cloneMatchingVariants(material.resolve());
103 } else {
104 renderComponent->material = component.material;
105 }
106 } else {
107 renderComponent->material = material;
108 material->setVariant("InstancedPositions", true);
109 }
110 }
111 }
112
113 for (size_t i = 0; i < model->parts.size(); ++i) {
114 const auto & part = model->parts[i];
115
116 context->transformSystem->setLocalTransform(transformComponents[i].resolveComponent<TransformComponent>(), model->getPartTransform(part));
117 }
118
119 modelData.isLoaded = true;
120 }
121 }
122 }
123 }
124 }
125}
Context * context
Pointer to the Context instance the system lives in.
void update()
Updates the system state to that of the current frame.
ComponentHandle createComponent() override
ComponentHandle createComponent() override
Create a new component instance.
ComponentPool< ComponentType > pool
Pool of components managed by the system.
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
std::unique_ptr< class DeferredNameResolution > deferredResolution
Deferred name resolution service instance.
Definition: Context.h:204
void addChild(ComponentModel::Entity *parent, const EntityPtr &entity)
Add a child to the given parent.
void createEntities(size_t count, std::vector< EntityPtr > &entities)
Allocates and initializes a collection of empty entities.
uint32_t startIndex
Start vertex index to render from.
ComponentHandle createComponent() override
Create a new component instance.
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
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.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
Definition: HashFunctions.h:62
ComponentType * resolveComponent() const
Definition: Component.h:90
Holds extra housekeeping data for an Entity instance.
Definition: EntityStore.h:24
size_t templateId
Contains the hashed name of a template or entity definition (if any) used to create the instance.
Definition: EntityStore.h:26
EPrimitiveType
Primitive type enumeration.
Definition: Common.h:114