Cogs.Core
RationalReducerExtension.cpp
1#include "ExtensionRegistry.h"
2
3#include "Components/Core/DynamicComponent.h"
4#include "Components/Core/TransformComponent.h"
5#include "Components/Core/MeshRenderComponent.h"
6#include "Components/Core/SceneComponent.h"
7
8#include "Context.h"
9#include "EntityStore.h"
10
11#include "Renderer/Renderer.h"
12#include "Renderer/RenderPipelineManager.h"
13#include "Renderer/Tasks/RenderTaskFactory.h"
14
15#include "Resources/ResourceStore.h"
16#include "Resources/MaterialInstance.h"
17
18#include "Editor.h"
19
20#include "Services/Services.h"
21
22#include "AnnotationComponent.h"
23#include "RationalReducerComponent.h"
24#include "MeshReductionManager.h"
25#include "RRSimplifyCommand.h"
26#include "RRMultiSimplifyCommand.h"
27#include "RRSaveAllLodCommand.h"
28
29#include "Foundation/ComponentModel/Entity.h"
30#include "Foundation/Logging/Logger.h"
31
32using namespace Cogs::Core;
33using namespace Cogs::Reflection;
34
35namespace {
36 Cogs::Logging::Log logger = Cogs::Logging::getLogger("RationalReducer");
37
38
39 struct MeshItem
40 {
41 MeshComponent* meshComp;
43 };
44
45 void populateMeshItems(std::vector<MeshItem>& items, Cogs::ComponentModel::Entity* root)
46 {
47 if (auto * sceneComp = root->getComponent<SceneComponent>(); sceneComp) {
48 for (auto & child : sceneComp->children) {
49 populateMeshItems(items, child.get());
50 }
51 }
52 if (auto * meshComp = root->getComponent<MeshComponent>(); meshComp && meshComp->meshHandle) {
53 if (auto * meshRenderComp = root->getComponent<MeshRenderComponent>(); meshRenderComp && meshRenderComp->material) {
54 items.emplace_back(MeshItem{meshComp, meshRenderComp->material });
55 }
56 }
57 }
58
59
60 struct RationalReducerCommand : public EditorCommand
61 {
62 RationalReducerCommand(EditorState * state) : EditorCommand(state, state->context) {}
63
64 TaskId id = NoTask;
65
66 virtual bool done() {
67 LOG_DEBUG(logger, "done\n");
68 return true;
69 }
70
71 void apply() override
72 {
73 auto entity = state->getSelected();
74 if (!entity) return;
75
76 std::vector<MeshItem> items;
77 populateMeshItems(items, entity);
78
79 if (items.empty()) return;
80
81 std::vector<Mesh *> meshes;
82 std::vector<MaterialInstance *> mats;
83 for (auto & item : items) {
84 meshes.push_back(item.meshComp->meshHandle.resolve());
85 mats.push_back(item.mat.resolve());
86 }
87
88 float reductionPercent = 90.f;
89 float reductionEpsilon = 0.05f;
90
91 auto manager = context->services->getService<Cogs::RationalReducerExtension::MeshReductionManager>();
92 //manager->setAddNormals(true);
93 auto reducedMeshes = manager->reduce(meshes, mats, std::clamp(reductionPercent, 0.0f, 100.0f), reductionEpsilon);
94
95 if (reducedMeshes.size() != items.size()) {
96 LOG_ERROR(logger, "Expected %zu meshes from reduce, got %zu.", items.size(), reducedMeshes.size());
97 }
98 else {
99 for (size_t i = 0; i < items.size(); i++) {
100 items[i].meshComp->meshHandle = reducedMeshes[i];
101 items[i].meshComp->setChanged();
102 }
103 LOG_DEBUG(logger, "Simplified %zu meshes", items.size());
104 }
105 }
106
107 void undo() override
108 {
109
110 }
111
112 };
113
114}
115
116
117namespace Cogs
118{
119 namespace RationalReducerExtension
120 {
121
123 {
124
126 {
127 ExtensionRegistry::add(this, COGS_CORE_VERSION_STRING);
128 }
129
130 virtual bool initializeStatic() override
131 {
132 RationalReducerComponent::registerType();
133 AnnotationComponent::registerType();
134 TypeDatabase::createType<MeshReductionManager>();
135 Editor::registerExtensionCommand("RRSimplify", [](EditorState * state) { return new RRSimplifiyCommand(state); });
136 Editor::registerExtensionItem("RRSimplify", "RR Simplify Mesh");
137 Editor::registerExtensionCommand("RRMultiSimplify", [](EditorState * state) { return new RRMultiSimplifyCommand(state); });
138 Editor::registerExtensionItem("RRMultiSimplify", "RR create LOD levels");
139 Editor::registerExtensionCommand("RRSaveAllLod", [](EditorState * state) { return new RRSaveAllLodCommand(state); });
140 Editor::registerExtensionItem("RRSaveAllLod", "RR save LODs in separate files");
141
142 //Editor::registerExtensionCommand("RationalReducer", [](EditorState * state) { return new RationalReducerCommand(state); });
143 //Editor::registerExtensionItem("RationalReducer", "Reduce Mesh");
144
145 return true;
146 }
147
148 virtual bool initialize(Context * context) override
149 {
150 context->registerDynamicComponentType("RationalReducerComponent");
151 context->registerDynamicComponentType("AnnotationComponent");
152 context->resourceStore->addSearchPath("../Extensions/RationalReducer/Data/");
153 context->services->registerService<MeshReductionManager>(context);
154
155 return true;
156 }
157
158 virtual void cleanup(Context * context) override
159 {
160 auto manager = context->services->getService<MeshReductionManager>();
161
162 if (manager) {
163 manager->cleanup();
164 }
165 }
166
167 virtual const char * getExtensionKey() const override { return "RationalReducer"; }
168 } rationalReducerExtensionInstance;
169 }
170}
Container for components, providing composition of dynamic entities.
Definition: Entity.h:18
T * getComponent() const
Get a pointer to the first component implementing the given type in the entity.
Definition: Entity.h:35
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
void registerDynamicComponentType(const StringView &typeName)
Register a dynamic component type with the given typeName.
Definition: Context.cpp:380
std::unique_ptr< class ResourceStore > resourceStore
ResourceStore service instance.
Definition: Context.h:210
static void add(Extension *extension, StringView version)
Adds the given extension to the registry, ensuring the initialization methods are called at appropria...
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.
MaterialInstanceHandle material
Material used to render the mesh.
Contains information on how the entity behaves in the scene.
Log implementation class.
Definition: LogManager.h:139
Interface to Rational Reducer for reducing meshes.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
Contains reflection support.
Definition: Component.h:11
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
Base class for Cogs Editor commands.
Definition: EditorCommand.h:19
virtual void apply()=0
Run the command.
Defines an extension to Cogs.Core and provides methods to override in order to initialize extension c...
Task id struct used to identify unique Task instances.
Definition: TaskManager.h:20
virtual bool initialize(Context *context) override
Initialize extension for the given context.
virtual void cleanup(Context *context) override
Cleanup context bound extension content.
virtual const char * getExtensionKey() const override
Get the extensions unique key, used to check for extension presence and retrieve extension specific d...
virtual bool initializeStatic() override
Initialize extension statically.