• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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