forked from facebook/react-native
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTransform.h
More file actions
208 lines (179 loc) · 5.13 KB
/
Transform.h
File metadata and controls
208 lines (179 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <array>
#include <folly/Hash.h>
#include <react/graphics/Float.h>
#include <react/graphics/Geometry.h>
#include <react/graphics/Quaternion.h>
#ifdef ANDROID
#include <folly/dynamic.h>
#endif
namespace facebook {
namespace react {
struct ScaleRotationTranslation {
Float translationX;
Float translationY;
Float translationZ;
Float scaleX;
Float scaleY;
Float scaleZ;
Quaternion<Float> rotation;
};
/*
* Defines transform matrix to apply affine transformations.
*/
struct Transform {
using SRT = ScaleRotationTranslation;
std::array<Float, 16> matrix{
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}};
/**
* For debugging only. Prints out the matrix.
*/
#ifdef RN_DEBUG_STRING_CONVERTIBLE
static void print(Transform const &t, std::string prefix);
#endif
/*
* Returns the identity transform (`[1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1]`).
*/
static Transform Identity();
/*
* Returns a Perspective transform.
*/
static Transform Perspective(Float perspective);
/*
* Returns a Scale transform.
*/
static Transform Scale(Float factorX, Float factorY, Float factorZ);
/*
* Returns a Translate transform.
*/
static Transform Translate(Float x, Float y, Float z);
/*
* Returns a Skew transform.
*/
static Transform Skew(Float x, Float y);
/*
* Returns a transform that rotates by `angle` radians along the given axis.
*/
static Transform RotateX(Float angle);
static Transform RotateY(Float angle);
static Transform RotateZ(Float angle);
static Transform Rotate(Float angleX, Float angleY, Float angleZ);
/**
* Extract SRT (scale, rotation, transformation) from a Transform matrix.
*
* CAVEATS:
* 1. The input matrix must not have Skew applied.
* 2. Scaling factors must be non-negative. Scaling by a negative factor is
* equivalent to a rotation, and though it is possible to detect if 1 or
* 3 of the scale signs are flipped (but not two), it is not possible
* to detect WHICH of the scales are flipped. Thus, any animation
* that involves a negative scale factor will not crash but will
* interpolate over nonsensical values.
* 3. Another caveat is that if the animation interpolates TO a 90º
* rotation in the X, Y, or Z axis, the View will appear to suddenly
* explode in size. Interpolating THROUGH 90º is fine as long as you don't end
* up at 90º or close to it (89.99). The same is true for 0±90 and 360n+90,
* etc.
*/
static SRT ExtractSRT(Transform const &transform);
/**
* Perform an interpolation between lhs and rhs, given progress.
* This first decomposes the matrices into translation, scale, and rotation,
* performs slerp between the two rotations, and a linear interpolation
* of scale and translation.
*
* @param progress
* @param lhs
* @param rhs
* @return
*/
static Transform Interpolate(
float animationProgress,
Transform const &lhs,
Transform const &rhs);
/*
* Equality operators.
*/
bool operator==(Transform const &rhs) const;
bool operator!=(Transform const &rhs) const;
/*
* Matrix subscript.
*/
Float &at(int x, int y);
Float const &at(int x, int y) const;
/*
* Concatenates (multiplies) transform matrices.
*/
Transform operator*(Transform const &rhs) const;
/**
* Convert to folly::dynamic.
*/
#ifdef ANDROID
operator folly::dynamic() const {
return folly::dynamic::array(
matrix[0],
matrix[1],
matrix[2],
matrix[3],
matrix[4],
matrix[5],
matrix[6],
matrix[7],
matrix[8],
matrix[9],
matrix[10],
matrix[11],
matrix[12],
matrix[13],
matrix[14],
matrix[15]);
}
#endif
};
/*
* Applies tranformation to the given point.
*/
Point operator*(Point const &point, Transform const &transform);
/*
* Applies tranformation to the given size.
*/
Size operator*(Size const &size, Transform const &transform);
/*
* Applies tranformation to the given rect.
* ONLY SUPPORTS scale and translation transformation.
*/
Rect operator*(Rect const &rect, Transform const &transform);
Vector operator*(Transform const &transform, Vector const &vector);
} // namespace react
} // namespace facebook
namespace std {
template <>
struct hash<facebook::react::Transform> {
size_t operator()(const facebook::react::Transform &transform) const {
return folly::hash::hash_combine(
0,
transform.matrix[0],
transform.matrix[1],
transform.matrix[2],
transform.matrix[3],
transform.matrix[4],
transform.matrix[5],
transform.matrix[6],
transform.matrix[7],
transform.matrix[8],
transform.matrix[9],
transform.matrix[10],
transform.matrix[11],
transform.matrix[12],
transform.matrix[13],
transform.matrix[14],
transform.matrix[15]);
}
};
} // namespace std