1#include "ResourceCommands.h"
3#include "Resources/MaterialInstance.h"
5#include "Components/Core/SceneComponent.h"
6#include "Components/Core/MeshComponent.h"
7#include "Components/Core/MeshRenderComponent.h"
9#include "Resources/MaterialManager.h"
10#include "Resources/MeshManager.h"
11#include "Resources/DefaultMaterial.h"
12#include "Resources/Texture.h"
13#include "Resources/TextureManager.h"
15#include "Resources/MaterialInstance.h"
17#include "Foundation/HashSequence.h"
18#include "Foundation/Logging/Logger.h"
19#include "Foundation/Platform/IO.h"
30 auto textureKey = material->
material->getTextureKey(key);
33 previousTexture = textureProperty.texture.handle;
38void Cogs::Core::SetTexturePropertyCommand::undo()
40 auto textureKey = material->material->getTextureKey(key);
41 material->setTextureProperty(textureKey, previousTexture);
46 void gatherMaterials(
ComponentModel::Entity * entity, std::unordered_map<EntityId, MaterialInstanceHandle> & materials)
48 auto component = entity->
getComponent<MeshRenderComponent>();
51 if (component->material) {
52 materials[entity->
getId()] = component->material;
56 auto sceneComponent = entity->
getComponent<SceneComponent>();
59 for (
auto & child : sceneComponent->children) {
60 gatherMaterials(child.get(), materials);
68 gatherMaterials(context->store->getEntityPtr(entityId), materials);
72 std::unordered_map<MaterialInstance *, MaterialInstance *> mapping;
74 auto material = context->materialManager->getMaterial(
"StandardMaterial");
76 for (
auto & m : materials) {
77 auto entity = context->store->getEntityPtr(m.first);
80 auto found = mapping.find(m.second.resolve());
82 if (found != mapping.end()) {
83 component->
material = context->materialInstanceManager->generateHandle(found->second);
87 auto newMaterial = context->materialInstanceManager->createMaterialInstance(material);
88 newMaterial->setVariant(
"Textured",
false);
90 auto color = m.second->getVec4Property(DefaultMaterial::DiffuseColor);
91 color = glm::pow(color, glm::vec4(glm::vec3(1.0f / 2.2f), 1.0f));
93 auto diffuseMap = m.second->getTextureProperty(DefaultMaterial::DiffuseMap);
95 TextureHandle diffuseHandle = m.second->getTextureProperty(DefaultMaterial::DiffuseMap).texture.handle;
97 if(!diffuseHandle->getSource().
empty()){
98 newMaterial->setTextureProperty(material->getTextureKey(
"albedoMap"), diffuseHandle);
99 newMaterial->setVariant(
"Textured",
true);
100 newMaterial->setVariant(
"AlbedoMap",
true);
103 auto name = diffuseHandle->
getName();
105 const char *patterns[] = {
113 std::string albedo, diffuse, gloss, normal, spec;
114 for(
const char *pattern : patterns){
115 std::string::size_type pos;
118 std::string last = name.substr(pos+strlen(pattern)).to_string();
119 albedo = first+
"ALBEDO"+last;
120 if(!Cogs::IO::exists(albedo)) albedo =
"";
121 diffuse = first+
"DIFFUSE"+last;
122 if(!Cogs::IO::exists(diffuse)) diffuse =
"";
123 gloss = first+
"GLOSS"+last;
124 if(!Cogs::IO::exists(gloss)) gloss =
"";
125 normal = first+
"NORMAL"+last;
126 if(!Cogs::IO::exists(normal)) normal =
"";
127 spec = first+
"SPEC"+last;
128 if(!Cogs::IO::exists(spec)) spec =
"";
132 newMaterial->setPermutation(
"Specular");
133 newMaterial->setVariant(
"Textured",
false);
134 newMaterial->setVec4Property(material->getVec4Key(
"albedo"), color);
135 newMaterial->setFloatProperty(material->getFloatKey(
"gloss"), 1.0);
136 newMaterial->setVec3Property(material->getVec3Key(
"specular"), glm::vec3(0.0));
137 newMaterial->setFloatProperty(material->getFloatKey(
"normalMapFactor"), 1.0);
139 newMaterial->setVariant(
"Textured",
true);
140 newMaterial->setVariant(
"AlbedoMap",
true);
142 newMaterial->setTextureProperty(material->getTextureKey(
"albedoMap"), mh);
144 else if(diffuse !=
""){
145 newMaterial->setVariant(
"Textured",
true);
146 newMaterial->setVariant(
"AlbedoMap",
true);
148 newMaterial->setTextureProperty(material->getTextureKey(
"albedoMap"), mh);
151 newMaterial->setVariant(
"Textured",
true);
152 newMaterial->setVariant(
"GlossMap",
true);
154 newMaterial->setTextureProperty(material->getTextureKey(
"glossMap"), mh);
157 newMaterial->setVariant(
"Textured",
true);
158 newMaterial->setVariant(
"NormalMap",
true);
160 newMaterial->setTextureProperty(material->getTextureKey(
"normalMap"), mh);
163 newMaterial->setVariant(
"Textured",
true);
164 newMaterial->setVariant(
"SpecularMap",
true);
165 newMaterial->setVec3Property(material->getVec3Key(
"specular"), glm::vec3(1.0));
167 newMaterial->setTextureProperty(material->getTextureKey(
"specularMap"), mh);
171 mapping[m.second.resolve()] = newMaterial.resolve();
172 component->material = newMaterial;
176void Cogs::Core::RemapMaterialCommand::undo()
178 for (
auto & m : materials) {
179 auto entity = context->store->getEntityPtr(m.first);
187 size_t hashValue = material->getName().hash();
189 if (material->material->getName() ==
"DefaultMaterial") {
190 hashValue =
Cogs::hash(material->getVec4Property(DefaultMaterial::DiffuseColor), hashValue);
191 hashValue =
Cogs::hash(material->getVec3Property(DefaultMaterial::SpecularColor), hashValue);
192 hashValue =
Cogs::hash(material->getVec3Property(DefaultMaterial::EmissiveColor), hashValue);
193 hashValue =
Cogs::hash(material->getFloatProperty(DefaultMaterial::SpecularPower), hashValue);
195 TextureHandle diffuseHandle = material->getTextureProperty(DefaultMaterial::DiffuseMap).texture.handle;
197 hashValue =
Cogs::hash(diffuseHandle->getName(), hashValue);
200 TextureHandle normalHandle = material->getTextureProperty(DefaultMaterial::NormalMap).texture.handle;
202 hashValue =
Cogs::hash(normalHandle->getName(), hashValue);
205 TextureHandle specularHandle = material->getTextureProperty(DefaultMaterial::SpecularMap).texture.handle;
207 hashValue =
Cogs::hash(specularHandle->getName(), hashValue);
211 hashValue =
Cogs::hash(
reinterpret_cast<intptr_t
>(material), hashValue);
218 gatherMaterials(context->store->getEntityPtr(entityId), materials);
220 std::set<MaterialInstance*> count;
221 for (
auto & m : materials)
222 count.insert(m.second.resolve());
224 std::unordered_map<size_t, MaterialInstance*> mapping;
226 for (
auto & m : materials) {
227 auto entity = context->store->getEntityPtr(m.first);
231 if(!mapping.count(
hash))
232 mapping[
hash] = m.second.resolve();
235 LOG_INFO(logger,
"%zu materials merget to %zu materials", count.size(), mapping.size());
237void Cogs::Core::MergeMaterialCommand::undo()
239 for (
auto & m : materials) {
240 auto entity = context->store->getEntityPtr(m.first);
246static void gatherMeshes(ComponentModel::Entity * entity, std::unordered_map<EntityId, MeshHandle> &meshes)
248 auto component = entity->getComponent<MeshComponent>();
251 if (component->meshHandle) {
252 meshes[entity->getId()] = component->meshHandle;
256 auto sceneComponent = entity->getComponent<SceneComponent>();
258 if (sceneComponent) {
259 for (
auto & child : sceneComponent->children) {
260 gatherMeshes(child.get(), meshes);
267 gatherMeshes(context->store->getEntityPtr(entityId), meshes);
268 for(
auto &m : meshes){
274 auto mesh = m.second.resolve();
278void Cogs::Core::GenNormalsCommand::undo()
280 LOG_ERROR(logger,
"TODO: Undo normal generation.");
281 for (
auto & m : meshes) {
282 auto entity = context->store->getEntityPtr(m.first);
289 gatherMeshes(context->store->getEntityPtr(entityId), meshes);
290 for(
auto &m : meshes){
296 auto mesh = m.second.resolve();
300void Cogs::Core::GenerateTangentsCommand::undo()
302 LOG_ERROR(logger,
"TODO: Undo tangent generation.");
303 for (
auto & m : meshes) {
304 auto entity = context->store->getEntityPtr(m.first);
Container for components, providing composition of dynamic entities.
T * getComponent() const
Get a pointer to the first component implementing the given type in the entity.
constexpr size_t getId() const noexcept
Get the unique identifier of this entity.
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.
Renders the contents of a MeshComponent using the given materials.
MaterialInstanceHandle material
Material used to render the mesh.
Log implementation class.
constexpr bool empty() const noexcept
Check if the string is empty.
constexpr StringView substr(size_t offset, size_t count=NoPosition) const noexcept
Get the given sub string.
static constexpr size_t NoPosition
No position.
std::string to_string() const
String conversion method.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
void COGSCORE_DLL_API generateMeshNormals(Mesh *mesh)
Generate normals.
void COGSCORE_DLL_API generateMeshTangents(Mesh *mesh)
Generate tangents.
@ LinearColorSpace
For textures with RGBA format without color space information, mark the data as being in linear color...
size_t getMaterialHash(const MaterialComponent &component)
Creates a hash value from the material properties in the given component.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
void apply() override
Run the command.
void apply() override
Run the command.
TextureValue getTextureProperty(const VariableKey key) const
Get the value of the property with the given key.
void setTextureProperty(const StringView &key, TextureHandle value)
Set the texture property with the given key to the texture resource held by value.
Material * material
Material resource this MaterialInstance is created from.
void apply() override
Run the command.
void apply() override
Run the command.
StringView getName() const
Get the name of the resource.
void apply() override
Run the command.