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