1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <3d/ecs/components/material_component.h>
17 #include <core/property/property_types.h>
18 CORE_BEGIN_NAMESPACE()
19 using CORE3D_NS::MaterialComponent;
20 DECLARE_PROPERTY_TYPE(MaterialComponent::TextureInfo);
21 DECLARE_PROPERTY_TYPE(BASE_NS::vector<MaterialComponent::TextureInfo>);
22 CORE_END_NAMESPACE()
23
24 #include <scene/ext/intf_ecs_context.h>
25
26 #include <core/property/property_handle_util.h>
27
28 #include "material_component.h"
29
SCENE_BEGIN_NAMESPACE()30 SCENE_BEGIN_NAMESPACE()
31
32 BASE_NS::string MaterialComponent::GetName() const
33 {
34 return "MaterialComponent";
35 }
36
GetActiveTextureSlotInfo()37 IInternalMaterial::ActiveTextureSlotInfo MaterialComponent::GetActiveTextureSlotInfo()
38 {
39 static constexpr auto textureInfoTypeDecl =
40 CORE_NS::PropertySystem::PropertyTypeDeclFromType<CORE3D_NS::MaterialComponent::TextureInfo>();
41 auto ecso = GetEcsObject();
42 if (!ecso) {
43 return {};
44 }
45 auto scene = ecso->GetScene();
46 if (!scene) {
47 return {};
48 }
49 ActiveTextureSlotInfo info;
50 size_t maxIdx = 0;
51 auto& ecsc = scene->GetEcsContext();
52 if (auto mp = GetProperty("MaterialShader", META_NS::MetadataQuery::EXISTING)) {
53 scene->SyncProperty(mp, META_NS::EngineSyncDirection::AUTO);
54 }
55 if (auto m = ecsc.FindComponent<CORE3D_NS::IMaterialComponentManager>()) {
56 auto entity = ecso->GetEntity();
57 if (m->HasComponent(entity)) {
58 if (auto data = m->GetData(entity)) {
59 const auto meta = data->Owner()->MetaData();
60 uintptr_t texturesOffset {};
61 for (auto& p : meta) {
62 if (p.name == "textures") {
63 texturesOffset = p.offset;
64 break;
65 }
66 }
67 // add the default types. (incorrect .shader declarations may make them active anyway. so we MUST keep
68 // them)
69 info.count = CORE3D_NS::MaterialComponent::TextureIndex::TEXTURE_COUNT;
70 info.slots.resize(CORE3D_NS::MaterialComponent::TextureIndex::TEXTURE_COUNT);
71 const char *const names[] = {"BASE_COLOR",
72 "NORMAL",
73 "MATERIAL",
74 "EMISSIVE",
75 "AO",
76 "CLEARCOAT",
77 "CLEARCOAT_ROUGHNESS",
78 "CLEARCOAT_NORMAL",
79 "SHEEN",
80 "TRANSMISSION",
81 "SPECULAR"};
82 for (int index = 0; index < CORE3D_NS::MaterialComponent::TextureIndex::TEXTURE_COUNT; index++) {
83 ActiveTextureSlotInfo::TextureSlot ts;
84 ts.name = names[index];
85 info.slots[index] = BASE_NS::move(ts);
86 }
87 // this updates the names of the inputs that .shader declares. (which hopefully are used)
88 for (auto& p : meta) {
89 if (p.type == textureInfoTypeDecl) {
90 auto index = (p.offset - texturesOffset) / sizeof(CORE3D_NS::MaterialComponent::TextureInfo);
91 ActiveTextureSlotInfo::TextureSlot ts;
92 ts.name = p.name;
93 info.slots[index] = BASE_NS::move(ts);
94 }
95 }
96 }
97 }
98 }
99 return info;
100 }
101
102 SCENE_END_NAMESPACE()
103