1#include "InstancedModelSystem.h"
3#include "EntityStore.h"
5#include "Systems/Core/SceneSystem.h"
6#include "Systems/Core/TransformSystem.h"
7#include "Systems/Core/MeshSystem.h"
8#include "Systems/Core/InstancedMeshRenderSystem.h"
10#include "Resources/ModelManager.h"
11#include "Resources/MeshManager.h"
12#include "Resources/MaterialManager.h"
14#include "Services/DeferredNameResolution.h"
18 for (
auto & component :
pool) {
19 auto & modelData = getData<InstancedModelData>(&component);
21 auto model =
HandleIsValid(component.model) ?
context->modelManager->get(component.model) :
nullptr;
23 if (component.hasChanged() || model) {
25 if (model->isLoaded() && !modelData.isLoaded) {
27 for (
auto & mesh : model->meshes) {
28 ready &= mesh->isActive();
32 std::vector<EntityPtr> entities(model->parts.size());
33 std::vector<ComponentHandle> transformComponents(model->parts.size());
34 std::vector<ComponentHandle> sceneComponents(model->parts.size());
36 const auto groupId =
hash(
"Group");
37 const auto meshPartId =
hash(
"InstancedMeshPart");
42 for (
size_t i = 0; i < model->parts.size(); ++i) {
43 const auto & part = model->parts[i];
44 auto & entity = entities[i];
46 auto partName = model->getPartName(part);
47 if (!partName.empty()) {
48 entity->setName(partName);
53 transformComponents[i] = transformComponent;
55 entity->addComponent(transformComponent);
58 entity->addComponent(sceneComponents[i]);
60 if (part.parentIndex != NoParentPart) {
62 transformComponent.resolveComponent<
TransformComponent>()->parent = transformComponents[part.parentIndex];
68 entityData->
templateId = (part.meshIndex !=
static_cast<uint32_t
>(-1) ? meshPartId : groupId);
70 if (part.meshIndex !=
static_cast<uint32_t
>(-1)) {
71 auto & mesh = model->meshes[part.meshIndex];
74 entity->addComponent(mcHandle);
78 meshComponent->setChanged();
81 entity->addComponent(mrcHandle);
85 renderComponent->vertexCount = part.vertexCount;
87 renderComponent->instanceMesh = component.instanceMesh;
89 if (part.materialIndex >= model->materials.size()) {
93 auto & material = model->materials[part.materialIndex];
94 if (component.material) {
95 if (component.cloneModelMaterialProperties) {
96 renderComponent->material =
context->materialInstanceManager->createMaterialInstance(component.material);
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());
104 renderComponent->material = component.material;
107 renderComponent->material = material;
108 material->setVariant(
"InstancedPositions",
true);
113 for (
size_t i = 0; i < model->parts.size(); ++i) {
114 const auto & part = model->parts[i];
116 context->transformSystem->setLocalTransform(transformComponents[i].resolveComponent<TransformComponent>(), model->getPartTransform(part));
119 modelData.isLoaded =
true;
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.
class EntityStore * store
Entity store.
std::unique_ptr< class DeferredNameResolution > deferredResolution
Deferred name resolution service instance.
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.
Renders a mesh using instancing.
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.
MeshHandle meshHandle
Handle to a Mesh resource to use when rendering.
Contains information on how the entity behaves in the scene.
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.
ComponentType * resolveComponent() const
Holds extra housekeeping data for an Entity instance.
size_t templateId
Contains the hashed name of a template or entity definition (if any) used to create the instance.
EPrimitiveType
Primitive type enumeration.