1 /* 2 * Copyright (c) 2021-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 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_TRANSFORM_UTIL_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_TRANSFORM_UTIL_H 18 19 #include <utility> 20 #include <vector> 21 22 #include "base/geometry/dimension.h" 23 #include "base/geometry/matrix4.h" 24 #include "base/geometry/quaternion.h" 25 26 namespace OHOS::Ace { 27 28 struct ACE_EXPORT TranslateOperation { 29 TranslateOperation() = default; dxTranslateOperation30 TranslateOperation(Dimension dx, Dimension dy, Dimension dz = Dimension {}) : dx(dx), dy(dy), dz(dz) {} 31 bool operator==(const TranslateOperation& other) const 32 { 33 return dx == other.dx && dy == other.dy && dz == other.dz; 34 } 35 Dimension dx; 36 Dimension dy; 37 Dimension dz; 38 39 static TranslateOperation Blend(const TranslateOperation& to, const TranslateOperation& from, float progress); 40 }; 41 42 struct ACE_EXPORT ScaleOperation { 43 ScaleOperation() = default; ScaleOperationScaleOperation44 ScaleOperation(float x, float y, float z) : scaleX(x), scaleY(y), scaleZ(z) {} 45 bool operator==(const ScaleOperation& other) const 46 { 47 constexpr double epsilon = 0.0001; 48 return NearEqual(scaleX, other.scaleX, epsilon) && NearEqual(scaleY, other.scaleY, epsilon) && 49 NearEqual(scaleZ, other.scaleZ, epsilon); 50 } 51 float scaleX = 1.0f; 52 float scaleY = 1.0f; 53 float scaleZ = 1.0f; 54 55 static ScaleOperation Blend(const ScaleOperation& to, const ScaleOperation& from, float progress); 56 }; 57 58 struct ACE_EXPORT SkewOperation { 59 SkewOperation() = default; SkewOperationSkewOperation60 SkewOperation(float x, float y) : skewX(x), skewY(y) {} 61 bool operator==(const SkewOperation& other) const 62 { 63 return NearEqual(skewX, other.skewX) && NearEqual(skewY, other.skewY); 64 } 65 float skewX = 0.0f; 66 float skewY = 0.0f; 67 68 static SkewOperation Blend(const SkewOperation& to, const SkewOperation& from, float progress); 69 }; 70 71 struct ACE_EXPORT RotateOperation { 72 RotateOperation() = default; RotateOperationRotateOperation73 RotateOperation(float x, float y, float z, float angle) : dx(x), dy(y), dz(z), angle(angle) {} 74 bool operator==(const RotateOperation& other) const 75 { 76 return NearEqual(dx, other.dx) && NearEqual(dy, other.dy) && NearEqual(dz, other.dz) && 77 NearEqual(angle, other.angle); 78 } 79 float dx = 0.0f; 80 float dy = 0.0f; 81 float dz = 0.0f; 82 float angle = 0.0f; 83 84 static RotateOperation Blend(const RotateOperation& to, const RotateOperation& from, float progress); 85 }; 86 87 struct ACE_EXPORT PerspectiveOperation { 88 PerspectiveOperation() = default; PerspectiveOperationPerspectiveOperation89 explicit PerspectiveOperation(const Dimension& dis) : distance(dis) {} 90 bool operator==(const PerspectiveOperation& other) const 91 { 92 return distance == other.distance; 93 } 94 Dimension distance; 95 96 static PerspectiveOperation Blend(const PerspectiveOperation& to, const PerspectiveOperation& from, float progress); 97 }; 98 99 struct ACE_EXPORT DecomposedTransform { 100 float translate[3] = { 0.0f, 0.0f, 0.0f }; 101 float scale[3] = { 1.0f, 1.0f, 1.0f }; 102 float skew[3] = { 0.0f, 0.0f, 0.0f }; 103 float perspective[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; 104 Quaternion quaternion; 105 106 std::string ToString() const; 107 }; 108 109 enum class TransformOperationType { 110 TRANSLATE, 111 SCALE, 112 SKEW, 113 ROTATE, 114 MATRIX, 115 PERSPECTIVE, 116 UNDEFINED, 117 }; 118 119 struct ACE_EXPORT TransformOperation { TransformOperationTransformOperation120 TransformOperation() : type_(TransformOperationType::UNDEFINED) {} 121 122 TransformOperationType type_ = TransformOperationType::UNDEFINED; 123 Matrix4 matrix4_ = Matrix4::CreateIdentity(); 124 union { 125 TranslateOperation translateOperation_; 126 ScaleOperation scaleOperation_; 127 SkewOperation skewOperation_; 128 RotateOperation rotateOperation_; 129 PerspectiveOperation perspectiveOperation_; 130 }; 131 132 bool operator==(const TransformOperation& other) const 133 { 134 if (type_ != other.type_) { 135 return false; 136 } 137 switch (type_) { 138 case TransformOperationType::MATRIX: { 139 return matrix4_ == other.matrix4_; 140 } 141 case TransformOperationType::PERSPECTIVE: { 142 return perspectiveOperation_ == other.perspectiveOperation_; 143 } 144 case TransformOperationType::ROTATE: { 145 return rotateOperation_ == other.rotateOperation_; 146 } 147 case TransformOperationType::SCALE: { 148 return scaleOperation_ == other.scaleOperation_; 149 } 150 case TransformOperationType::SKEW: { 151 return skewOperation_ == other.skewOperation_; 152 } 153 case TransformOperationType::TRANSLATE: { 154 return translateOperation_ == other.translateOperation_; 155 } 156 case TransformOperationType::UNDEFINED: 157 // fall through 158 default: 159 return true; 160 } 161 } 162 163 static TransformOperation Blend(const TransformOperation& to, const TransformOperation& from, float progress); 164 static TransformOperation Create(TransformOperationType type); 165 166 private: 167 static void BlendInner( 168 const TransformOperation& to, const TransformOperation& from, float progress, TransformOperation& out); 169 }; 170 171 class ACE_EXPORT TransformOperations { 172 public: 173 static void ParseOperationsToMatrix(std::vector<TransformOperation>& operations); 174 175 static void ParseOperationToMatrix(TransformOperation& operations); 176 177 static TransformOperations Blend(const TransformOperations& to, const TransformOperations& from, float progress); 178 179 explicit TransformOperations(std::vector<TransformOperation> operation = std::vector<TransformOperation>()) operations_(std::move (operation))180 : operations_(std::move(operation)) 181 {} 182 ~TransformOperations() = default; 183 GetOperations()184 std::vector<TransformOperation>& GetOperations() 185 { 186 return operations_; 187 } 188 GetOperations()189 const std::vector<TransformOperation>& GetOperations() const 190 { 191 return operations_; 192 } 193 194 Matrix4 ComputerRemaining(std::size_t startOffset) const; 195 SetAlwaysRotate(bool alwaysRotate)196 void SetAlwaysRotate(bool alwaysRotate) 197 { 198 alwaysRotate_ = alwaysRotate; 199 } 200 201 bool operator==(const TransformOperations& other) const 202 { 203 if (alwaysRotate_) { 204 return false; 205 } 206 if (operations_.size() != other.operations_.size()) { 207 return false; 208 } 209 for (size_t index = 0; index < operations_.size(); index++) { 210 if (!(operations_[index] == other.operations_[index])) { 211 return false; 212 } 213 } 214 return true; 215 } 216 217 protected: 218 std::vector<TransformOperation> operations_; 219 bool alwaysRotate_ = false; 220 221 private: 222 std::size_t MatchingLength(const TransformOperations& to, const TransformOperations& from) const; 223 void BlendInner(const TransformOperations& from, float progress, TransformOperations& out) const; 224 }; 225 226 class ACE_EXPORT TransformUtil final { 227 public: 228 static bool DecomposeTransform(DecomposedTransform& out, const Matrix4& transform); 229 static DecomposedTransform BlendDecomposedTransforms( 230 const DecomposedTransform& to, const DecomposedTransform& from, double progress); 231 static Matrix4 ComposeTransform(const DecomposedTransform& decomp); 232 }; 233 234 } // namespace OHOS::Ace 235 236 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_TRANSFORM_UTIL_H 237