Cogs.Core
TwinCadModelSystem.cpp
1#include "Foundation/Logging/Logger.h"
2
3#include "Components/Core/AssetComponent.h"
4
5#include "Systems/Core/AssetSystem.h"
6
7#include "Resources/MaterialManager.h"
8#include "Resources/TextureManager.h"
9
10#include "Services/Time.h"
11
12#include "ExtensionRegistry.h"
13#include "Context.h"
14
15#include "TwinCadModelSystem.h"
16#include "TwinVisualsSystem.h"
17
18
19namespace {
20 using Cogs::StringView;
21 using namespace Cogs::Core;
22 Cogs::Logging::Log logger = Cogs::Logging::getLogger("TwinCadModel");
23
24}
25
27{
28 TwinVisualsSystem* visualsSystem = ExtensionRegistry::getExtensionSystem<TwinVisualsSystem>(context);
29 if (visualsSystem == nullptr || visualsSystem->globalTwinVisualsComponent == nullptr) return;
30 TwinVisualsData& visualsData = visualsSystem->getData(visualsSystem->globalTwinVisualsComponent);
31
32 for (const TwinCadModelComponent& cadModelComp : pool) {
33 TwinCadModelData& cadModelData = getData(&cadModelComp);
34 if (cadModelData.firstRun) {
35
36 // We need to set this as early as possible, but when we create the TwinCadModelComponent,
37 // the AssetComponent might not have been created yet.
38 if (AssetComponent* assetComp = cadModelComp.getComponent<AssetComponent>(); assetComp) {
39 context->assetSystem->getData<AssetData>(assetComp).customRayPickHandling = cadModelComp.getComponentHandle<TwinCadModelComponent>();
40 }
41 cadModelData.firstRun = false;
42 }
43
44 // We do this in preUpdate so we get the transition to texture loading state before we check this in update.
45 if (cadModelComp.hasChanged()) {
46 if (cadModelData.substance != cadModelComp.substance) {
47 cadModelData.substance = cadModelComp.substance;
48 if (cadModelData.substance.empty()) {
49 cadModelData.baseColor.clear(context, visualsData);
50 cadModelData.normal.clear(context, visualsData);
51 cadModelData.orm.clear(context, visualsData);
52 }
53 else {
54 cadModelData.baseColor.issue(context, visualsData, cadModelData.substance + "/SubstanceSet_baseColor.ktx2");
55 cadModelData.normal.issue(context, visualsData, cadModelData.substance + "/SubstanceSet_normal.ktx2");
56 cadModelData.orm.issue(context, visualsData, cadModelData.substance + "/SubstanceSet_orm.ktx2");
57 }
58 }
59 }
60
61 }
62}
63
65{
66 TwinVisualsSystem* visualsSystem = ExtensionRegistry::getExtensionSystem<TwinVisualsSystem>(context);
67 if (visualsSystem == nullptr || visualsSystem->globalTwinVisualsComponent == nullptr) return;
68 TwinVisualsData& visualsData = visualsSystem->getData(visualsSystem->globalTwinVisualsComponent);
69
70 for (const TwinCadModelComponent& cadModelComp : pool) {
71 TwinCadModelData& cadModelData = getData(&cadModelComp);
72
73 if (cadModelData.attributeMapGen != cadModelComp.attributeMap.getGeneration()) {
74 cadModelData.attributeMapGen = cadModelComp.attributeMap.getGeneration();
75
76 if (!cadModelComp.attributeMap.empty()) {
77
78 size_t slots = cadModelComp.attributeMap.size() / 4;
79 size_t rows = (slots + 4096 - 1) / 4096;
80 cadModelData.attributeMapData.resize(4 * 4096 * rows);
81 for (size_t i = 0; i < 4 * slots; i++) {
82 cadModelData.attributeMapData[i] = cadModelComp.attributeMap[i];
83 }
84
85 ResourceId resourceId = NoResourceId;
86 if (cadModelData.attributeMap) {
87 resourceId = cadModelData.attributeMap->getId();
88 }
89 cadModelData.attributeMap = context->textureManager->loadTexture2D(cadModelData.attributeMapData.data(),
90 4096, static_cast<int>(rows),
91 TextureFormat::R8G8B8A8_UNORM, 0,
92 resourceId,
94 }
95 else {
96 cadModelData.attributeMapData.clear();
97 cadModelData.attributeMap = TextureHandle::NoHandle;
98 }
99 cadModelData.materialInstance->setTextureProperty(attributeMapKey, cadModelData.attributeMap);
100 }
101
102
103
104
105 if (cadModelComp.hasChanged()) {
106 cadModelData.needUpdate = true;
107 }
108 cadModelData.baseColor.check(context, visualsData);
109 cadModelData.normal.check(context, visualsData);
110 cadModelData.orm.check(context, visualsData);
111
112 if(cadModelData.needUpdate && visualsData.currTextureLoadingState == TextureLoadingState::Ready) {
113 cadModelData.needUpdate = false;
114
115 if (emissiveColorKey != NoProperty) {
116 cadModelData.materialInstance->setVec3Property(emissiveColorKey, cadModelComp.emissiveColor);
117 }
118
119 if (diffuseColorKey != NoProperty) {
120 cadModelData.materialInstance->setVec4Property(diffuseColorKey, cadModelComp.diffuseColor);
121 }
122
123 if (specularColorKey != NoProperty) {
124 cadModelData.materialInstance->setVec3Property(specularColorKey, cadModelComp.specularColor);
125 }
126
127 if (specularPowerKey != NoProperty) {
128 cadModelData.materialInstance->setFloatProperty(specularPowerKey, cadModelComp.specularPower);
129 }
130
131 if (metallicKey != NoProperty) {
132 cadModelData.materialInstance->setFloatProperty(metallicKey, cadModelComp.metallic);
133 }
134
135 if (roughnessKey != NoProperty) {
136 cadModelData.materialInstance->setFloatProperty(roughnessKey, cadModelComp.roughness);
137 }
138
139 if (substanceParamsKey != NoProperty) {
140 cadModelData.materialInstance->setVec3Property(substanceParamsKey, cadModelComp.substanceParams);
141 }
142
143 if (parametersKey != NoProperty) {
144 cadModelData.materialInstance->setVec4Property(parametersKey, cadModelComp.parameters);
145 }
146
147 if (clippingKey != NoProperty) {
148 cadModelData.materialInstance->setVec4Property(clippingKey, cadModelComp.clipping);
149 }
150
151 if (minClippingKey != NoProperty) {
152 cadModelData.materialInstance->setVec3Property(minClippingKey, cadModelComp.minClipping);
153 }
154
155 if (maxClippingKey != NoProperty) {
156 cadModelData.materialInstance->setVec3Property(maxClippingKey, cadModelComp.maxClipping);
157 }
158
159 if (hasAttributeDataKey != NoProperty) {
160 cadModelData.materialInstance->setBoolProperty(hasAttributeDataKey, cadModelComp.hasAttributeData);
161 }
162
163 if (surfaceVarianceTextureKey != NoProperty) {
164 cadModelData.materialInstance->setTextureProperty(surfaceVarianceTextureKey, cadModelComp.surfaceVarianceTexture);
165 }
166
167 if (allowClippingVariantIndex != Material::NoVariantIndex) {
168 cadModelData.materialInstance->setVariant(allowClippingVariantIndex, cadModelComp.allowClipping);
169 }
170
171 if (customEffectVariantIndex != Material::NoVariantIndex) {
172 cadModelData.materialInstance->setVariant(customEffectVariantIndex, cadModelComp.customEffect);
173 }
174
175 if (selectionEffectVariantIndex != Material::NoVariantIndex) {
176 cadModelData.materialInstance->setVariant(selectionEffectVariantIndex, cadModelComp.selectionEffect);
177 }
178
179 if (surfaceVarianceVariantIndex != Material::NoVariantIndex) {
180 cadModelData.materialInstance->setVariant(surfaceVarianceVariantIndex, cadModelComp.surfaceVariance);
181 }
182
183 if (lightModelVariantIndex != Material::NoVariantIndex) {
184 cadModelData.materialInstance->setVariant(lightModelVariantIndex, (cadModelComp.pbrLighting ? std::string_view("PBR") : std::string_view("Phong")));
185 }
186
187 if (numSubstanceDefinitionMapsVariantIndex != Material::NoVariantIndex) {
188 cadModelData.materialInstance->setVariant(numSubstanceDefinitionMapsVariantIndex, cadModelComp.numSubstanceDefinitionMaps);
189 }
190
191 }
192
193 if (AssetComponent* assetComp = cadModelComp.getComponent<AssetComponent>(); assetComp) {
194 if (assetComp->material != cadModelData.materialInstance) {
195 assetComp->material = cadModelData.materialInstance;
196 assetComp->setChanged();
197 }
198 }
199
200 if (visualsData.presentTextures) {
201 if (baseColorMapKey != NoProperty) {
202 cadModelData.materialInstance->setTextureProperty(baseColorMapKey, cadModelData.baseColor.present);
203 }
204 if (normalMapKey != NoProperty) {
205 cadModelData.materialInstance->setTextureProperty(normalMapKey, cadModelData.normal.present);
206 }
207 if (occlusionRoughnessMetallicMapKey != NoProperty) {
208 cadModelData.materialInstance->setTextureProperty(occlusionRoughnessMetallicMapKey, cadModelData.orm.present);
209 }
210 }
211
212 }
213}
214
216{
217 if (pool.size() == 0) {
218 if (material == MaterialHandle::NoHandle) {
219 material = context->materialManager->loadMaterial("TwinVisuals/TwinCadMaterial/AssetGeometry.material");
220 context->materialManager->processLoading();
221
222 attributeMapKey = material->getTextureKey("attributeMap");
223 emissiveColorKey = material->getVec3Key("emissiveColor");
224 diffuseColorKey = material->getVec4Key("diffuseColor");
225 specularColorKey = material->getVec3Key("specularColor");
226 specularPowerKey = material->getFloatKey("specularPower");
227 metallicKey = material->getFloatKey("metallic");
228 roughnessKey = material->getFloatKey("roughness");
229 substanceParamsKey = material->getVec3Key("substanceParams");
230 parametersKey = material->getVec4Key("parameters");
231 clippingKey = material->getVec4Key("clipping");
232 minClippingKey = material->getVec3Key("minClipping");
233 maxClippingKey = material->getVec3Key("maxClipping");
234 hasAttributeDataKey = material->getBoolKey("hasAttributeData");
235 surfaceVarianceTextureKey = material->getTextureKey("surfaceVarianceTexture");
236 baseColorMapKey = material->getTextureKey("baseColorMap");;
237 normalMapKey = material->getTextureKey("normalMap");;
238 occlusionRoughnessMetallicMapKey = material->getTextureKey("occlusionRoughnessMetallicMap");;
239
240 allowClippingVariantIndex = material->getVariantIndex("AllowClipping");
241 customEffectVariantIndex = material->getVariantIndex("CustomEffect");
242 selectionEffectVariantIndex = material->getVariantIndex("SelectionEffect");
243 surfaceVarianceVariantIndex = material->getVariantIndex("SurfaceVariance");
244 lightModelVariantIndex = material->getVariantIndex("LightModel");
245 numSubstanceDefinitionMapsVariantIndex = material->getVariantIndex("NumSubstanceDefinitionMaps");
246 }
247
248 assert(!rayPickExtension);
249 rayPickExtension = new TwinCadModelRayPickExtension(context->renderSystem, this);
250 context->rayPicking->addPickable(rayPickExtension);
251 LOG_DEBUG(logger, "First component created, registered raypick extension");
252 }
253
254 componentsCreated = true;
255
258 TwinCadModelData& data = getData(cadModelComp);
259 data.materialInstance = context->materialInstanceManager->createMaterialInstance(material);
260 return handle;
261}
262
263
265{
267 if (pool.size() == 0) {
268
269 assert(rayPickExtension);
270 context->rayPicking->removePickable(rayPickExtension);
271 delete rayPickExtension;
272 rayPickExtension = nullptr;
273
274 LOG_DEBUG(logger, "Last component destroyed, unregistered raypick extension");
275 }
276}
ComponentType * getComponent() const
Definition: Component.h:159
virtual ComponentHandle createComponent()
Create a new component instance.
Context * context
Pointer to the Context instance the system lives in.
virtual void destroyComponent(ComponentHandle)
Destroy the component held by the given handle.
void update()
Updates the system state to that of the current frame.
void preUpdate()
Run the pre-update method of the system.
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.
Definition: Context.h:83
Log implementation class.
Definition: LogManager.h:140
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:50
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
@ ForceSynchronous
Force loading the resource synchronously.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
Handle to a Component instance.
Definition: Component.h:67
ComponentType * resolveComponent() const
Definition: Component.h:90
Instantiates an asset model into the scene.
void setFloatProperty(const VariableKey key, float value)
Set the float property with the given key to value.
void setVec3Property(const VariableKey key, glm::vec3 value)
Set the vec3 property with the given key to value.
void setTextureProperty(const StringView &key, TextureHandle value)
Set the texture property with the given key to the texture resource held by value.
void setVec4Property(const VariableKey key, glm::vec4 value)
Set the vec4 property with the given key to value.
void setBoolProperty(const VariableKey key, bool value)
Set the bool property with the given key to value.
ResourceId getId() const
Get the resource id of this instance.
Definition: ResourceBase.h:215
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.
ComponentHandle createComponent() override
void destroyComponent(ComponentHandle handle) override