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