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 #include "particle_modifier.h"
16
17 #include "core/components_ng/pattern/particle/particle_model_ng.h"
18
19 namespace OHOS::Ace::NG {
20 namespace {
21 constexpr float DEFAULT_CENTER_VALUE = 0.5f;
22 constexpr float DEFAULT_START_ANGLE_VALUE = 0.0f;
23 constexpr float DEFAULT_END_ANGLE_VALUE = 360.0f;
24
SetDisturbanceField(ArkUINodeHandle node,const ArkUIInt32orFloat32 * values,ArkUI_Int32 length)25 void SetDisturbanceField(ArkUINodeHandle node, const ArkUIInt32orFloat32* values, ArkUI_Int32 length)
26 {
27 auto* frameNode = reinterpret_cast<FrameNode*>(node);
28 CHECK_NULL_VOID(frameNode);
29 std::vector<ParticleDisturbance> dataArray;
30 for (ArkUI_Int32 i = 0; i < length / 10; i++) {
31 ParticleDisturbance disturbanceField;
32 disturbanceField.strength = values[i*10].f32;
33 disturbanceField.shape = static_cast<ParticleDisturbanceShapeType>(values[i*10+1].i32);
34 disturbanceField.size[0] = values[i*10+2].i32, disturbanceField.size[1] = values[i*10+3].i32,
35 disturbanceField.position[0] = values[i*10+4].i32, disturbanceField.position[1] = values[i*10+5].i32,
36 disturbanceField.feather = values[i*10+6].i32;
37 disturbanceField.noiseScale = values[i*10+7].f32;
38 disturbanceField.noiseFrequency = values[i*10+8].f32;
39 disturbanceField.noiseAmplitude = values[i*10+9].f32;
40 dataArray.push_back(disturbanceField);
41 }
42 ParticleModelNG::DisturbanceField(dataArray, frameNode);
43 }
44
ResetDisturbanceField(ArkUINodeHandle node)45 void ResetDisturbanceField(ArkUINodeHandle node)
46 {
47 auto* frameNode = reinterpret_cast<FrameNode*>(node);
48 CHECK_NULL_VOID(frameNode);
49 std::vector<ParticleDisturbance> dataArray;
50 ParticleModelNG::DisturbanceField(dataArray, frameNode);
51 }
52
setEmitter(ArkUINodeHandle node,const ArkEmitterPropertyOptions * values,ArkUI_Int32 length)53 void setEmitter(ArkUINodeHandle node, const ArkEmitterPropertyOptions* values, ArkUI_Int32 length)
54 {
55 auto* frameNode = reinterpret_cast<FrameNode*>(node);
56 CHECK_NULL_VOID(frameNode);
57 std::vector<EmitterProperty> emitterProperties;
58 for (ArkUI_Int32 i = 0; i < length; i++) {
59 EmitterProperty prop;
60 prop.index = values[i].index;
61 if (values[i].isSetEmitRate == 1) {
62 prop.emitRate = values[i].emitRate;
63 }
64 if (values[i].isSetPosition == 1) {
65 prop.position = VectorF(values[i].positionX, values[i].positionY);
66 }
67 if (values[i].isSetSize == 1) {
68 prop.size = VectorF(values[i].sizeWidth, values[i].sizeHeight);
69 }
70
71 if (values[i].isSetAnnulusRegion == 1) {
72 std::pair<CalcDimension, CalcDimension> center = {
73 CalcDimension(DEFAULT_CENTER_VALUE, DimensionUnit::PERCENT),
74 CalcDimension(DEFAULT_CENTER_VALUE, DimensionUnit::PERCENT)};
75 CalcDimension innerRadius;
76 CalcDimension outerRadius;
77 float startAngle = DEFAULT_START_ANGLE_VALUE;
78 float endAngle = DEFAULT_END_ANGLE_VALUE;
79
80 if (values[i].isSetCenter == 1) {
81 center.first = CalcDimension(values[i].centerX.value,
82 static_cast<DimensionUnit>(values[i].centerX.units));
83 center.second = CalcDimension(values[i].centerY.value,
84 static_cast<DimensionUnit>(values[i].centerY.units));
85 }
86
87 if (values[i].isSetInnerRadius == 1) {
88 innerRadius = CalcDimension(values[i].innerRadius.value,
89 static_cast<DimensionUnit>(values[i].innerRadius.units));
90 }
91 if (values[i].isSetOuterRadius == 1) {
92 outerRadius = CalcDimension(values[i].outerRadius.value,
93 static_cast<DimensionUnit>(values[i].outerRadius.units));
94 }
95
96 if (values[i].isSetStartAngle == 1) {
97 startAngle = values[i].startAngle;
98 }
99 if (values[i].isSetEndAngle == 1) {
100 endAngle = values[i].endAngle;
101 }
102 prop.annulusRegion = {center, innerRadius, outerRadius, startAngle, endAngle};
103 }
104 emitterProperties.push_back(prop);
105 }
106 ParticleModelNG::updateEmitter(emitterProperties, frameNode);
107 }
108
resetEmitter(ArkUINodeHandle node)109 void resetEmitter(ArkUINodeHandle node)
110 {
111 auto* frameNode = reinterpret_cast<FrameNode*>(node);
112 CHECK_NULL_VOID(frameNode);
113 std::vector<EmitterProperty> dataArray;
114 ParticleModelNG::updateEmitter(dataArray, frameNode);
115 }
116 } // namespace
117
118 namespace NodeModifier {
GetParticleModifier()119 const ArkUIParticleModifier* GetParticleModifier()
120 {
121 CHECK_INITIALIZED_FIELDS_BEGIN(); // don't move this line
122 static const ArkUIParticleModifier modifier = {
123 .SetDisturbanceField = SetDisturbanceField,
124 .ResetDisturbanceField = ResetDisturbanceField,
125 .SetEmitter = setEmitter,
126 .ResetEmitter = resetEmitter,
127 };
128 CHECK_INITIALIZED_FIELDS_END(modifier, 0, 0, 0); // don't move this line
129 return &modifier;
130 }
131
GetCJUIParticleModifier()132 const CJUIParticleModifier* GetCJUIParticleModifier()
133 {
134 CHECK_INITIALIZED_FIELDS_BEGIN(); // don't move this line
135 static const CJUIParticleModifier modifier = {
136 .SetDisturbanceField = SetDisturbanceField,
137 .ResetDisturbanceField = ResetDisturbanceField,
138 .SetEmitter = setEmitter,
139 .ResetEmitter = resetEmitter,
140 };
141 CHECK_INITIALIZED_FIELDS_END(modifier, 0, 0, 0); // don't move this line
142 return &modifier;
143 }
144 } // namespace NodeModifier
145 } // namespace OHOS::Ace::NG
146