Cogs.Core
RationalReducerComponent.cpp
1#include "RationalReducerComponent.h"
2#include "MeshReductionManager.h"
3
4#include "Components/Core/MeshComponent.h"
5#include "Components/Core/MeshRenderComponent.h"
6#include "Components/Core/SceneComponent.h"
7#include "Components/Core/ModelComponent.h"
8
9#include "Context.h"
10#include "Engine.h"
11
12#include "Resources/Mesh.h"
13#include "Resources/MaterialInstance.h"
14#include "Services/Services.h"
15
16#include "Foundation/ComponentModel/Component.h"
17#include "Foundation/Reflection/TypeDatabase.h"
18
19#include <stack>
20
21using namespace Cogs::Core;
22using namespace Cogs::ComponentModel;
23using namespace Cogs::Reflection;
24using namespace Cogs::RationalReducerExtension;
25
26void RationalReducerComponent::registerType()
27{
28 Field fields[] = {
34 };
35
36 Method methods[] = {
37 Method(Name("initialize"), &RationalReducerComponent::initialize),
38 Method(Name("update"), &RationalReducerComponent::update),
39 };
40 DynamicComponent::registerDerivedType<RationalReducerComponent>().setFields(fields).setMethods(methods);
41}
42
43void RationalReducerComponent::initialize(Context * context)
44{
45 this->context = context;
46}
47
48namespace {
49 void updateMeshComp(Context* context, MeshComponent* meshComp, MeshHandle handle)
50 {
51 if (handle) {
52 if (meshComp->meshHandle != handle) {
53 meshComp->meshHandle = handle;
54 meshComp->setChanged();
55 context->engine->setDirty();
56 }
57 }
58 }
59
60 void updateMeshComps(Context* context, std::vector<ComponentHandle> meshComps, std::vector<MeshHandle> handles)
61 {
62 for (size_t i = 0; i < meshComps.size(); i++)
63 {
64 if (i >= handles.size()) return;
65 updateMeshComp(context, meshComps[i].resolveComponent<MeshComponent>(), handles[i]);
66 }
67 }
68
69 std::vector<ComponentHandle> findMeshComps(Cogs::ComponentModel::Entity* entity)
70 {
71 std::stack<Cogs::ComponentModel::Entity*> candidates;
72 candidates.push(entity);
73
74 std::vector<ComponentHandle> comps;
75
76 while (!candidates.empty()) {
77 auto candidate = candidates.top();
78 candidates.pop();
79
80 auto meshComp = candidate->getComponent<MeshComponent>();
81 if (meshComp != nullptr) comps.push_back(meshComp->getComponentHandle<MeshComponent>());
82
83 auto sceneComp = candidate->getComponent<SceneComponent>();
84 if (sceneComp != nullptr) {
85 for (auto& child : sceneComp->children) {
86 candidates.push(child.get());
87 }
88 }
89 }
90
91 return comps;
92 }
93}
94
95void RationalReducerComponent::update()
96{
97 auto meshComps = findMeshComps(getContainer());
98 if (meshComps.empty()) return; //No mesh components
99
100 if (this->meshComponents.size() > 0 && !std::equal(meshComps.begin(), meshComps.end(), this->meshComponents.begin())) {
101 //New mesh components detected, reset and start over
102 originalMeshes.clear();
103 reducedMeshes.clear();
104 materials.clear();
105 this->meshComponents = meshComps;
106 }
107 if (!enabled)
108 {
109 updateMeshComps(context, meshComps, originalMeshes);
110 return;
111 }
112
113 //if (!meshComp->meshHandle) return; //No valid mesh
114
115 if (reducedMeshes.size() > 0 && reductionPercent == lastPercent) {
116 //already processed, if we have a reduced version, set it now as it might not have been ready earlier or we might have toggled enabled state
117 updateMeshComps(context, meshComps, reducedMeshes);
118 return;
119 }
120
121 lastPercent = reductionPercent;
122
123 if (originalMeshes.size() == 0) {
124 for (auto & handle : meshComps) {
125 auto comp = handle.resolveComponent<MeshComponent>();
126 originalMeshes.push_back(comp->meshHandle); //Keep the handle so it can be restored later
127 auto mat = comp->getComponent<MeshRenderComponent>()->material;
128 materials.push_back(mat);
129 mat->setVariant("TangentSpaceNormalMap", false); //FIXME
130 }
131 }
132 auto manager = context->services->getService<MeshReductionManager>();
133
134 //FIXME: Should be moved to a task or background thread. Consider using resource system.
135 std::vector<Mesh *> meshes;
136 for (auto & handle : originalMeshes) meshes.push_back(handle.resolve());
137 std::vector<MaterialInstance *> mats;
138 for (auto & mat : materials) mats.push_back(mat.resolve());
139
140 manager->setLogging(loglevel);
141 manager->setAddNormals(addNormals);
142 reducedMeshes = manager->reduce(meshes, mats, std::clamp(reductionPercent, 0.0f, 100.0f), reductionEpsilon);
143
144 updateMeshComps(context, meshComps, reducedMeshes);
145
146 //auto meshRender = meshComp->getComponent<MeshRenderComponent>();
147 //auto & mat = meshRender->materialHandles[0];
148 //mat->setVariant("TangentSpaceNormalMap", false);
149 //mat->setVariant("SpecularMap", false);
150 //mat->setVariant("EnableLighting", false);
151 //mat->setVariant("LightModel", "BaseColor");
152 //mat->setOption("CullMode", "None");
153}
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
ComponentHandle getComponentHandle() const
Definition: Component.h:177
Container for components, providing composition of dynamic entities.
Definition: Entity.h:18
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
std::unique_ptr< class Services > services
Services.
Definition: Context.h:174
std::unique_ptr< class Engine > engine
Engine instance.
Definition: Context.h:222
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.
Contains information on how the entity behaves in the scene.
Interface to Rational Reducer for reducing meshes.
Field definition describing a single data member of a data structure.
Definition: Field.h:68
Simple method definition.
Definition: Method.h:72
Contains code for composing and managing entities built from components.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
Contains reflection support.
Definition: Component.h:11
ResourceType * resolve() const
Resolve the handle, returning a pointer to the actual resource.
float reductionPercent
The percentage of the triangles you want to remove.
bool addNormals
true if normals always to be generated, false = generate only if normals in input data.
float reductionEpsilon
A value telling RR to join all vertices where the distance between them are less than the given numbe...
Represents an unique name.
Definition: Name.h:70