1#include "StaticModelSystem.h"
3#include "EntityStore.h"
5#include "Resources/ModelManager.h"
7#include "Systems/Core/TransformSystem.h"
8#include "Systems/Core/MeshSystem.h"
9#include "Systems/Core/SceneSystem.h"
10#include "Systems/Core/RenderSystem.h"
12#include "Renderer/RenderList.h"
14#include "Foundation/Platform/Timer.h"
21 transformSystem(allocator, size),
22 meshSystem(allocator, size),
23 sceneSystem(allocator, size),
24 renderSystem(allocator, size)
26 meshSystem.transformSystem = &transformSystem;
27 renderSystem.transformSystem = &transformSystem;
29 entityContext.transformSystem = &transformSystem;
30 entityContext.meshSystem = &meshSystem;
31 entityContext.renderSystem = &renderSystem;
43 if (batch.missing || dirty) {
44 transformSystem.
update(context);
45 meshSystem.
update(context);
46 sceneSystem.
update(context);
47 renderSystem.
update(context);
68Cogs::Core::StaticModelData::~StaticModelData()
73Cogs::Core::StaticModelSystem::~StaticModelSystem()
79 for (
auto & component : pool) {
80 auto & modelData = getData(&component);
82 auto model =
HandleIsValid(component.model) ? context->modelManager->get(component.model) :
nullptr;
84 if (component.hasChanged() || (model && model->isLoaded() && !modelData.isGeneration((uint8_t)model->getGeneration()))) {
88 modelData.modelContext = std::make_shared<StaticModelContext>(context, context->
memory->componentAllocator, numParts);
90 loadModel(context, component, modelData, model);
94 if (!modelData.modelContext)
continue;
98 if (context->transformSystem->hasChanged(transformComponent)) {
99 modelData.modelContext->dirty =
true;
101 for (
auto & root : modelData.roots) {
103 rootTransform->
position = transformComponent->position;
104 rootTransform->setChanged();
108 modelData.modelContext->update(context);
114 auto & data = getData(modelComponent);
116 if (!data.modelContext)
return nullptr;
118 return &data.modelContext->renderSystem;
121Cogs::Core::MeshSystem * Cogs::Core::StaticModelSystem::getMeshSystem(StaticModelComponent * modelComponent)
123 auto & data = getData(modelComponent);
125 if (!data.modelContext)
return nullptr;
127 return &data.modelContext->meshSystem;
132 auto & data = getData(modelComponent);
134 if (!data.modelContext)
return nullptr;
136 return &data.modelContext->batch;
139void Cogs::Core::StaticModelSystem::initializeCulling(CullingSource* cullingSource)
141 for (
auto & component : pool) {
142 auto & data = getData(&component);
144 if (!data.modelContext)
continue;
146 data.modelContext->renderSystem.initializeCulling(cullingSource);
150void Cogs::Core::StaticModelSystem::loadModel(Context * context,
const StaticModelComponent & component, StaticModelData & modelData, Model * model)
152 auto transformSystem = &modelData.modelContext->transformSystem;
153 auto meshSystem = &modelData.modelContext->meshSystem;
154 auto sceneSystem = &modelData.modelContext->sceneSystem;
155 auto renderSystem = &modelData.modelContext->renderSystem;
158 std::vector<EntityPtr> entities(model->parts.size());
159 std::vector<ComponentHandle> transformComponents(model->parts.size());
160 std::vector<ComponentHandle> sceneComponents(model->parts.size());
162 const auto groupId =
hash(
"Group");
163 const auto meshPartId =
hash(
"MeshPart");
165 auto store = context->store;
167 store->createEntities(model->parts.size(), entities, [transformSystem, meshSystem, sceneSystem, renderSystem](
Entity* e) {
168 if (auto h = e->getComponentHandle<TransformComponent>(); h) {
169 transformSystem->destroyComponent(h);
172 sceneSystem->destroyComponent(h);
175 meshSystem->destroyComponent(h);
178 renderSystem->destroyComponent(h);
182 bool shareMaterial =
true;
183 bool inheritMaterial =
false;
185 for (
size_t i = 0; i < model->parts.size(); ++i) {
186 const auto & part = model->parts[i];
187 auto & entity = entities[i];
189 auto partName = model->getPartName(part);
190 if (!partName.empty()) {
191 entity->setName(partName);
194 auto transformComponent = transformSystem->createComponent();
195 transformComponents[i] = transformComponent;
197 entity->addComponent(transformComponent);
199 sceneComponents[i] = sceneSystem->createComponent();
200 entity->addComponent(sceneComponents[i]);
202 if (part.parentIndex != NoParentPart) {
203 sceneComponents[part.parentIndex].resolveComponent<SceneComponent>()->children.emplace_back(entity);
204 transformComponent.resolveComponent<TransformComponent>()->parent = transformComponents[part.parentIndex];
206 component.getComponent<SceneComponent>()->children.emplace_back(entity);
207 modelData.roots.emplace_back(entity.get());
210 EntityData* entityData =
static_cast<EntityData *
>(entity->getUserData());
211 entityData->templateId = (part.meshIndex != NoIndex ? meshPartId : groupId);
212 entityData->entityContext = &modelData.modelContext->entityContext;
214 if (part.meshIndex < model->meshes.size() && part.materialIndex < model->materials.size()) {
215 auto mesh = model->meshes[part.meshIndex];
216 auto material = model->materials[part.materialIndex];
218 auto mcHandle = meshSystem->createComponent();
219 entity->addComponent(mcHandle);
221 auto meshComponent = mcHandle.resolveComponent<MeshComponent>();
222 meshComponent->meshHandle = mesh;
223 meshComponent->setChanged();
225 auto mrcHandle = renderSystem->createComponent();
226 entity->addComponent(mrcHandle);
228 auto renderComponent = mrcHandle.resolveComponent<MeshRenderComponent>();
229 renderComponent->startIndex = part.startIndex;
230 renderComponent->vertexCount = part.vertexCount;
232 if (model->bounds.size() > i) {
233 renderSystem->setLocalBounds(renderComponent, model->bounds[i]);
238 renderComponent->material = material;
244 for (
size_t i = 0; i < model->parts.size(); ++i) {
245 const auto & part = model->parts[i];
247 transformSystem->setLocalTransform(transformComponents[i].resolveComponent<TransformComponent>(), model->getPartTransform(part));
251 modelData.setGeneration((uint8_t)model->getGeneration());
ComponentType * getComponent() const
Container for components, providing composition of dynamic entities.
ComponentHandle getComponentHandle() const
Get a component handle to the first component implementing the given type.
virtual void initialize(Context *context)
Initialize the system.
void update()
Updates the system state to that of the current frame.
void postUpdate(Context *) override
Context base contains the parts of a Context that may be instantiated by static scene or model instan...
A Context instance contains all the services, systems and runtime components needed to use Cogs.
std::unique_ptr< struct MemoryContext > memory
Memory and allocation info.
void update(Context *context) override
Provided for custom update logic in derived systems.
The mesh render system handles MeshRenderComponents.
void initialize(Context *context) override
Initialize the system.
void update(Context *context) override
Provided for custom update logic in derived systems.
The scene system handles SceneComponent instances, managing hierarchical visibility and pickability b...
void update(Context *context)
Updates the scene system.
Base allocator implementation.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
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.
ComponentIndex SizeType
Type used to track the size of pools.