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 & src)40 void ModelViewNG::Create(const std::string& src)
41 {
42 LOGD("MODEL_NG: Create-> src: %s", src.c_str());
43 auto* stack = ViewStackProcessor::GetInstance();
44 auto nodeId = stack->ClaimNodeId();
45 auto frameNode = FrameNode::GetOrCreateFrameNode(
46 V2::MODEL_ETS_TAG, nodeId, [&nodeId]() { return AceType::MakeRefPtr<ModelPattern>(nodeId); });
47 stack->Push(frameNode);
48 frameNode_ = AceType::WeakClaim(AceType::RawPtr(frameNode));
49 ACE_UPDATE_LAYOUT_PROPERTY(ModelLayoutProperty, NeedsSceneSetup, false);
50 ACE_UPDATE_LAYOUT_PROPERTY(ModelLayoutProperty, ModelSource, src);
51 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelLights, {});
52 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelAnimations, {});
53 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelGeometries, {});
54 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelCustomRenders, {});
55 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelImageTexturePaths, {});
56 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelShaderInputBuffers, {});
57
58 lightsIdx_ = 0;
59 if (lights_.empty()) {
60 isFirstLightsUpdate_ = true;
61 } else {
62 isFirstLightsUpdate_ = false;
63 }
64 }
65
SetBackground(const std::string & value)66 void ModelViewNG::SetBackground(const std::string& value)
67 {
68 LOGD("MODEL_NG: background: %s", value.c_str());
69 ACE_UPDATE_LAYOUT_PROPERTY(ModelLayoutProperty, ModelBackground, value);
70 }
71
SetHandleCameraMove(bool value)72 void ModelViewNG::SetHandleCameraMove(bool value)
73 {
74 LOGD("MODEL_NG: cameraMode: %s", value ? "true" : "false");
75 ACE_UPDATE_LAYOUT_PROPERTY(ModelLayoutProperty, ModelCameraMove, value);
76 }
77
SetTransparent(bool value)78 void ModelViewNG::SetTransparent(bool value)
79 {
80 LOGD("MODEL_NG: transparent: %s", value ? "true" : "false");
81 ACE_UPDATE_LAYOUT_PROPERTY(ModelLayoutProperty, ModelTransparent, value);
82 }
83
SetCameraPosition(AnimatableFloat x,AnimatableFloat y,AnimatableFloat z,AnimatableFloat distance,bool isAngular)84 void ModelViewNG::SetCameraPosition(AnimatableFloat x, AnimatableFloat y, AnimatableFloat z,
85 AnimatableFloat distance, bool isAngular)
86 {
87 LOGD("MODEL_NG: cameraPosition: [%.2f, %.2f %.2f], distance: %.2f",
88 x.GetValue(), y.GetValue(), z.GetValue(), distance.GetValue());
89 if (NearEqual(cameraPosition_.GetDistance().GetValue(), std::numeric_limits<float>::max())) {
90 // Initial update. Set the values directly without the animation if any.
91 cameraPosition_.SetDistance(AnimatableFloat(distance.GetValue()));
92 cameraPosition_.SetVec(OHOS::Ace::Vec3(x.GetValue(), y.GetValue(), z.GetValue()));
93 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraDistance, distance);
94 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraPosition, OHOS::Ace::Vec3(x, y, z));
95 } else {
96 cameraPosition_.SetDistance(distance);
97 cameraPosition_.SetVec(OHOS::Ace::Vec3(x, y, z));
98 }
99 LOGD("MODEL_NG: cameraIsAngular: %s", isAngular ? "true" : "false");
100 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraIsAngular, isAngular);
101 }
102
SetCameraRotation(Quaternion quat)103 void ModelViewNG::SetCameraRotation(Quaternion quat)
104 {
105 LOGD("MODEL_NG: cameraRotation: @quat");
106 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraRotation, quat);
107 }
108
SetCameraFrustum(float zNear,float zFar,float fovDegrees)109 void ModelViewNG::SetCameraFrustum(float zNear, float zFar, float fovDegrees)
110 {
111 LOGD("MODEL_NG: cameraFrustum");
112 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraZNear, zNear);
113 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraZFar, zFar);
114 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraFOV, fovDegrees);
115 }
116
SetCameraLookAt(Vec3 lookAtVec)117 void ModelViewNG::SetCameraLookAt(Vec3 lookAtVec)
118 {
119 LOGD("MODEL_NG: cameraLookAt: @Vec3");
120 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraLookAt, lookAtVec);
121 }
122
SetCameraUp(Vec3 upVec)123 void ModelViewNG::SetCameraUp(Vec3 upVec)
124 {
125 LOGD("MODEL_NG: cameraUp: @Vec3");
126 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, CameraUp, upVec);
127 }
128
AddLight(const RefPtr<OHOS::Render3D::SVLight> & light)129 void ModelViewNG::AddLight(const RefPtr<OHOS::Render3D::SVLight>& light)
130 {
131 LOGD("MODEL_NG: light: @light");
132 if (isFirstLightsUpdate_) {
133 // Set the animation callback.
134 RefPtr<PipelineBase> pipeline = PipelineBase::GetCurrentContext();
135 CHECK_NULL_VOID(pipeline);
136 if (pipeline) {
137 light->SetContextAndCallback(pipeline,
138 std::bind(&ModelViewNG::PerformLightUpdate, this));
139 } else {
140 LOGE("ModelViewNG() pipeline context is null");
141 }
142 lights_.push_back(light);
143 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleLight, light);
144 } else {
145 lightsIdx_++;
146 // Update the corresponding light proepties.
147 auto currentLight = lights_.at(lightsIdx_-1);
148 currentLight->SetLightType(light->GetLightType());
149 currentLight->SetIntensity(light->GetLightIntensity());
150 currentLight->SetColor(light->GetLightColor());
151 currentLight->SetLightShadow(light->GetLightShadow());
152 currentLight->SetPosition(light->GetPosition());
153 currentLight->SetRotation(light->GetRotation());
154 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleLight, currentLight);
155 }
156 }
157
AddGeometry(const RefPtr<OHOS::Render3D::SVGeometry> & shape)158 void ModelViewNG::AddGeometry(const RefPtr<OHOS::Render3D::SVGeometry>& shape)
159 {
160 LOGD("MODEL_NG: AddGeometry @shape %s", shape->GetName().c_str());
161 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleGeometry, shape);
162 }
163
AddGLTFAnimation(const RefPtr<OHOS::Render3D::GLTFAnimation> & animation)164 void ModelViewNG::AddGLTFAnimation(const RefPtr<OHOS::Render3D::GLTFAnimation>& animation)
165 {
166 LOGD("MODEL_NG: AddGLTFAnimation @animation");
167 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleAnimation, animation);
168 }
169
AddCustomRender(const RefPtr<OHOS::Render3D::SVCustomRenderDescriptor> & customRender)170 void ModelViewNG::AddCustomRender(const RefPtr<OHOS::Render3D::SVCustomRenderDescriptor>& customRender)
171 {
172 LOGD("MODEL_NG: AddCustomRender");
173 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleCustomRender, customRender);
174 }
175
SetWidth(Dimension & width)176 void ModelViewNG::SetWidth(Dimension& width)
177 {
178 LOGD("MODEL_NG: ModelViewNG::SetWidth() %f", width.Value());
179 if (LessNotEqual(width.Value(), 0.0)) {
180 width.SetValue(0.0);
181 }
182 ViewAbstract::SetWidth(CalcLength(width));
183 }
184
SetHeight(Dimension & height)185 void ModelViewNG::SetHeight(Dimension& height)
186 {
187 LOGD("MODEL_NG: ModelViewNG::SetHeight() %f", height.Value());
188 if (LessNotEqual(height.Value(), 0.0)) {
189 height.SetValue(0.0);
190 }
191 ViewAbstract::SetHeight(CalcLength(height));
192 }
193
SetShader(const std::string & path)194 void ModelViewNG::SetShader(const std::string& path)
195 {
196 LOGD("ModelViewNG::SetShader() path: %s", path.c_str());
197 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ShaderPath, path);
198 }
199
AddShaderImageTexture(const std::string & path)200 void ModelViewNG::AddShaderImageTexture(const std::string& path)
201 {
202 LOGD("ModelViewNG::AddShaderImageTexture() path: %s", path.c_str());
203 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleImageTexturePath, path);
204 }
205
AddShaderInputBuffer(const RefPtr<OHOS::Render3D::ShaderInputBuffer> & buffer)206 void ModelViewNG::AddShaderInputBuffer(const RefPtr<OHOS::Render3D::ShaderInputBuffer>& buffer)
207 {
208 LOGD("ModelViewNG::AddShaderInputBuffer() size: %d", buffer->GetSize());
209 ACE_UPDATE_PAINT_PROPERTY(ModelPaintProperty, ModelSingleShaderInputBuffer, buffer);
210 }
211
PerformCameraUpdate()212 void ModelViewNG::PerformCameraUpdate()
213 {
214 LOGD("ModelViewNG::PerformCameraUpdate() position: %f, %f, %f, distance: %f", cameraPosition_.GetX(),
215 cameraPosition_.GetY(), cameraPosition_.GetZ(), cameraPosition_.GetDistance().GetValue());
216 auto frameNode = frameNode_.Upgrade();
217 if (!frameNode) {
218 LOGE("frameNode is null!");
219 return;
220 }
221
222 auto paintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
223 if (paintProperty) {
224 paintProperty->UpdateCameraDistance(cameraPosition_.GetDistance());
225 paintProperty->UpdateCameraPosition(cameraPosition_.GetVec());
226 frameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
227 } else {
228 LOGE("ModelPaintProperty is null");
229 }
230 }
231
PerformLightUpdate()232 void ModelViewNG::PerformLightUpdate()
233 {
234 auto frameNode = frameNode_.Upgrade();
235 if (!frameNode) {
236 LOGE("frameNode is null!");
237 return;
238 }
239
240 auto paintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
241 if (!paintProperty) {
242 LOGE("ModelPaintProperty is null");
243 return;
244 }
245 paintProperty->ModelLightsAnimationUpdate(lights_);
246 frameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
247 }
248
249 } // namespace OHOS::Ace::NG
250