1 /*
2 * Copyright (c) 2022 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 "core/components_ng/pattern/model/model_view_ng.h"
17
18 #include "base/geometry/dimension.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/components_ng/base/view_abstract.h"
21 #include "core/components_ng/base/view_stack_processor.h"
22 #include "core/components_ng/pattern/model/model_pattern.h"
23 #include "core/components_v2/inspector/inspector_constants.h"
24 #include "core/pipeline/pipeline_base.h"
25
26 namespace OHOS::Ace::NG {
27
ModelViewNG()28 ModelViewNG::ModelViewNG()
29 {
30 const RefPtr<PipelineBase> pipeline = PipelineBase::GetCurrentContext();
31 CHECK_NULL_VOID(pipeline);
32 if (pipeline) {
33 cameraPosition_.SetContextAndCallbacks(pipeline,
34 std::bind(&ModelViewNG::PerformCameraUpdate, this));
35 } else {
36 LOGE("ModelViewNG() pipeline context is null");
37 }
38 }
39
Create(const std::string & bundleName,const std::string & moduleName,Render3D::SurfaceType surfaceType)40 void ModelViewNG::Create(const std::string& bundleName, const std::string& moduleName,
41 Render3D::SurfaceType surfaceType)
42 {
43 auto* stack = ViewStackProcessor::GetInstance();
44 auto nodeId = stack->ClaimNodeId();
45 static int staticKey = 0;
46
47 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::MODEL_ETS_TAG, nodeId);
48 auto frameNode = FrameNode::GetOrCreateFrameNode(
49 V2::MODEL_ETS_TAG, nodeId, [&nodeId, surfaceType, &bundleName, &moduleName]() {
50 return AceType::MakeRefPtr<ModelPattern>(staticKey++, surfaceType,
51 bundleName, moduleName);
52 });
53
54 stack->Push(frameNode);
55 frameNode_ = AceType::WeakClaim(AceType::RawPtr(frameNode));
56 }
57
SetBackground(const std::string & value)58 void ModelViewNG::SetBackground(const std::string& value)
59 {
60 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelBackground, value);
61 }
62
SetHandleCameraMove(bool value)63 void ModelViewNG::SetHandleCameraMove(bool value)
64 {
65 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelCameraMove, value);
66 }
67
SetModelSource(const std::string & value)68 void ModelViewNG::SetModelSource(const std::string& value)
69 {
70 LOGD("MODEL_NG: Model source: %s", value.c_str());
71 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSource, value);
72 }
73
SetTransparent(bool value)74 void ModelViewNG::SetTransparent(bool value)
75 {
76 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelTransparent, value);
77 }
78
SetCameraPosition(AnimatableFloat x,AnimatableFloat y,AnimatableFloat z,AnimatableFloat distance,bool isAngular)79 void ModelViewNG::SetCameraPosition(AnimatableFloat x, AnimatableFloat y, AnimatableFloat z,
80 AnimatableFloat distance, bool isAngular)
81 {
82 if (NearEqual(cameraPosition_.GetDistance().GetValue(), std::numeric_limits<float>::max())) {
83 // Initial update. Set the values directly without the animation if any.
84 cameraPosition_.SetDistance(AnimatableFloat(distance.GetValue()));
85 cameraPosition_.SetPosition(Vec3(x.GetValue(), y.GetValue(), z.GetValue()));
86 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraDistance, distance);
87 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraPosition, Vec3(x, y, z));
88 } else {
89 cameraPosition_.SetDistance(distance);
90 cameraPosition_.SetPosition(Vec3(x, y, z));
91 }
92 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraIsAngular, isAngular);
93 }
94
SetCameraRotation(Quaternion quat)95 void ModelViewNG::SetCameraRotation(Quaternion quat)
96 {
97 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraRotation, quat);
98 }
99
SetCameraFrustum(float zNear,float zFar,float fovDegrees)100 void ModelViewNG::SetCameraFrustum(float zNear, float zFar, float fovDegrees)
101 {
102 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraZNear, zNear);
103 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraZFar, zFar);
104 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraFOV, fovDegrees);
105 }
106
SetCameraLookAt(Vec3 lookAtVec)107 void ModelViewNG::SetCameraLookAt(Vec3 lookAtVec)
108 {
109 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraLookAt, lookAtVec);
110 }
111
SetCameraUp(Vec3 upVec)112 void ModelViewNG::SetCameraUp(Vec3 upVec)
113 {
114 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraUp, upVec);
115 }
116
AddLight(const RefPtr<ModelLight> & light)117 void ModelViewNG::AddLight(const RefPtr<ModelLight>& light)
118 {
119 if (!light) {
120 LOGE("Add light invalid light");
121 return;
122 }
123
124 if (lights_.empty()) {
125 // Set the animation callback.
126 RefPtr<PipelineBase> pipeline = PipelineBase::GetCurrentContext();
127 CHECK_NULL_VOID(pipeline);
128 if (pipeline) {
129 light->SetContextAndCallback(pipeline,
130 std::bind(&ModelViewNG::PerformLightUpdate, this));
131 } else {
132 LOGE("ModelViewNG() pipeline context is null");
133 }
134 }
135
136 lights_.push_back(light);
137 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleLight, light);
138 }
139
AddGeometry(const std::shared_ptr<Render3D::Geometry> & shape)140 void ModelViewNG::AddGeometry(const std::shared_ptr<Render3D::Geometry>& shape)
141 {
142 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleGeometry, shape);
143 }
144
AddGLTFAnimation(const std::shared_ptr<Render3D::GLTFAnimation> & animation)145 void ModelViewNG::AddGLTFAnimation(const std::shared_ptr<Render3D::GLTFAnimation>& animation)
146 {
147 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleAnimation, animation);
148 }
149
AddCustomRender(const std::shared_ptr<Render3D::CustomRenderDescriptor> & customRender)150 void ModelViewNG::AddCustomRender(const std::shared_ptr<Render3D::CustomRenderDescriptor>& customRender)
151 {
152 if (!customRender) {
153 return;
154 }
155 auto frameNode = frameNode_.Upgrade();
156 if (!frameNode) {
157 LOGE("frameNode is null!");
158 return;
159 }
160
161 auto paintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
162 if (!paintProperty) {
163 LOGE("model paint property is null!");
164 return;
165 }
166
167 const auto curCustomRender = paintProperty->GetModelCustomRenderValue({ });
168 if (!curCustomRender || (curCustomRender->GetUri() != customRender->GetUri())) {
169 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelCustomRender, customRender);
170 }
171 }
172
SetWidth(Dimension & width)173 void ModelViewNG::SetWidth(Dimension& width)
174 {
175 if (LessNotEqual(width.Value(), 0.0)) {
176 width.SetValue(0.0);
177 }
178 ViewAbstract::SetWidth(CalcLength(width));
179 }
180
SetHeight(Dimension & height)181 void ModelViewNG::SetHeight(Dimension& height)
182 {
183 if (LessNotEqual(height.Value(), 0.0)) {
184 height.SetValue(0.0);
185 }
186 ViewAbstract::SetHeight(CalcLength(height));
187 }
188
SetRenderHeight(Dimension & height)189 void ModelViewNG::SetRenderHeight(Dimension& height)
190 {
191 if (LessNotEqual(height.Value(), 0.0)) {
192 height.SetValue(1.0);
193 LOGE("MODEL_NG: ModelViewNG::SetRenderHeight() heigtScale set default 1.0");
194 }
195 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, RenderHeight, height.Value());
196 }
197
SetRenderWidth(Dimension & width)198 void ModelViewNG::SetRenderWidth(Dimension& width)
199 {
200 if (LessNotEqual(width.Value(), 0.0)) {
201 width.SetValue(1.0);
202 LOGE("MODEL_NG: ModelViewNG::SetRenderHeight() heigtScale set default 1.0");
203 }
204 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, RenderWidth, width.Value());
205 }
206
SetRenderFrameRate(float rate)207 void ModelViewNG::SetRenderFrameRate(float rate)
208 {
209 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, RenderFrameRate, rate);
210 }
211
SetShader(const std::string & path)212 void ModelViewNG::SetShader(const std::string& path)
213 {
214 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ShaderPath, path);
215 }
216
AddShaderImageTexture(const std::string & path)217 void ModelViewNG::AddShaderImageTexture(const std::string& path)
218 {
219 auto frameNode = frameNode_.Upgrade();
220 if (!frameNode) {
221 LOGE("frameNode is null!");
222 return;
223 }
224
225 auto paintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
226 if (!paintProperty) {
227 LOGE("model paint property is null!");
228 return;
229 }
230
231 const auto& images = paintProperty->GetModelImageTexturePathsValue({ });
232 for (auto& image : images) {
233 if (image == path) {
234 return;
235 }
236 }
237
238 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleImageTexturePath, path);
239 }
240
AddShaderInputBuffer(const std::shared_ptr<Render3D::ShaderInputBuffer> & buffer)241 void ModelViewNG::AddShaderInputBuffer(const std::shared_ptr<Render3D::ShaderInputBuffer>& buffer)
242 {
243 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelShaderInputBuffer, buffer);
244 }
245
PerformCameraUpdate()246 void ModelViewNG::PerformCameraUpdate()
247 {
248 auto frameNode = frameNode_.Upgrade();
249 if (!frameNode) {
250 LOGE("frameNode is null!");
251 return;
252 }
253
254 auto paintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
255 if (paintProperty) {
256 paintProperty->UpdateCameraDistance(cameraPosition_.GetDistance());
257 paintProperty->UpdateCameraPosition(cameraPosition_.GetPosition());
258 frameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
259 } else {
260 LOGE("ModelPaintProperty is null");
261 }
262 }
263
PerformLightUpdate()264 void ModelViewNG::PerformLightUpdate()
265 {
266 auto frameNode = frameNode_.Upgrade();
267 if (!frameNode) {
268 LOGE("frameNode is null!");
269 return;
270 }
271
272 auto paintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
273 if (!paintProperty) {
274 LOGE("ModelPaintProperty is null");
275 return;
276 }
277 paintProperty->ModelLightsAnimationUpdate(lights_);
278 frameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
279 }
280
GetShaderInputBuffer()281 std::optional<std::shared_ptr<Render3D::ShaderInputBuffer>> ModelViewNG::GetShaderInputBuffer()
282 {
283 auto frameNode = frameNode_.Upgrade();
284 if (!frameNode) {
285 LOGE("frameNode is null!");
286 return {};
287 }
288
289 auto paintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
290 if (!paintProperty) {
291 LOGE("ModelPaintProperty is null");
292 return {};
293 }
294
295 return paintProperty->CloneModelShaderInputBuffer();
296 }
297
298 } // namespace OHOS::Ace::NG
299