Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Side by Side Diff: chrome/browser/android/vr_shell/vr_math.cc

Issue 2795793002: Implementation of elbow model for the controller position and rotation. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/vr_shell/vr_math.h" 5 #include "chrome/browser/android/vr_shell/vr_math.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 10
(...skipping 16 matching lines...) Expand all
27 void SetIdentityM(gvr::Mat4f& mat) { 27 void SetIdentityM(gvr::Mat4f& mat) {
28 float* m = reinterpret_cast<float*>(mat.m); 28 float* m = reinterpret_cast<float*>(mat.m);
29 for (int i = 0; i < 16; i++) { 29 for (int i = 0; i < 16; i++) {
30 m[i] = 0; 30 m[i] = 0;
31 } 31 }
32 for (int i = 0; i < 16; i += 5) { 32 for (int i = 0; i < 16; i += 5) {
33 m[i] = 1.0f; 33 m[i] = 1.0f;
34 } 34 }
35 } 35 }
36 36
37 // Left multiply a translation matrix.
38 void TranslateM(gvr::Mat4f& tmat, gvr::Mat4f& mat, float x, float y, float z) { 37 void TranslateM(gvr::Mat4f& tmat, gvr::Mat4f& mat, float x, float y, float z) {
39 if (&tmat != &mat) { 38 if (&tmat != &mat) {
40 for (int i = 0; i < 4; ++i) { 39 for (int i = 0; i < 4; ++i) {
41 for (int j = 0; j < 4; ++j) { 40 for (int j = 0; j < 4; ++j) {
42 tmat.m[i][j] = mat.m[i][j]; 41 tmat.m[i][j] = mat.m[i][j];
43 } 42 }
44 } 43 }
45 } 44 }
46 tmat.m[0][3] += x; 45 tmat.m[0][3] += x;
47 tmat.m[1][3] += y; 46 tmat.m[1][3] += y;
48 tmat.m[2][3] += z; 47 tmat.m[2][3] += z;
49 } 48 }
50 49
51 // Left multiply a scale matrix.
52 void ScaleM(gvr::Mat4f& tmat, 50 void ScaleM(gvr::Mat4f& tmat,
53 const gvr::Mat4f& mat, 51 const gvr::Mat4f& mat,
54 float x, 52 float x,
55 float y, 53 float y,
56 float z) { 54 float z) {
57 if (&tmat != &mat) { 55 if (&tmat != &mat) {
58 for (int i = 0; i < 4; ++i) { 56 for (int i = 0; i < 4; ++i) {
59 for (int j = 0; j < 3; ++j) { 57 for (int j = 0; j < 3; ++j) {
60 tmat.m[i][j] = mat.m[i][j]; 58 tmat.m[i][j] = mat.m[i][j];
61 } 59 }
62 } 60 }
63 } 61 }
64 // Multiply all rows including translation components. 62 // Multiply all rows including translation components.
65 for (int j = 0; j < 4; ++j) { 63 for (int j = 0; j < 4; ++j) {
66 tmat.m[0][j] *= x; 64 tmat.m[0][j] *= x;
67 tmat.m[1][j] *= y; 65 tmat.m[1][j] *= y;
68 tmat.m[2][j] *= z; 66 tmat.m[2][j] *= z;
69 } 67 }
70 } 68 }
71 69
70 float Clampf(float value, float min, float max) {
cjgrant 2017/04/03 19:25:00 std::clamp is a thing, maybe we should use it inst
acondor_ 2017/04/19 18:44:27 I checked, and it is a C++17 feature.
71 if (value < min)
72 return min;
73 if (value > max)
74 return max;
75 return value;
76 }
77
78 float ToDegrees(float radians) {
79 return (radians * 180.f) / M_PI;
cjgrant 2017/04/03 19:24:59 No braces needed here.
acondor_ 2017/04/19 18:44:27 Done.
80 }
81
82 gvr::Vec3f QuatSlerp(gvr::Vec3f start, gvr::Vec3f end, float percent) {
83 NormalizeVector(start);
84 NormalizeVector(end);
85 float dot = Clampf(VectorDot(start, end), -1.f, 1.f);
cjgrant 2017/04/03 19:25:00 1.0f etc?
acondor_ 2017/04/19 18:44:27 Done.
86 float theta = acos(dot) * percent;
87 auto relative_vec = VectorSubtract(end, VectorScalarMul(start, dot));
88 NormalizeVector(relative_vec);
89 return VectorAdd(VectorScalarMul(start, cos(theta)),
90 VectorScalarMul(relative_vec, sin(theta)));
91 }
92
72 gvr::Vec3f MatrixVectorMul(const gvr::Mat4f& m, const gvr::Vec3f& v) { 93 gvr::Vec3f MatrixVectorMul(const gvr::Mat4f& m, const gvr::Vec3f& v) {
73 gvr::Vec3f res; 94 gvr::Vec3f res;
74 res.x = m.m[0][0] * v.x + m.m[0][1] * v.y + m.m[0][2] * v.z + m.m[0][3]; 95 res.x = m.m[0][0] * v.x + m.m[0][1] * v.y + m.m[0][2] * v.z + m.m[0][3];
75 res.y = m.m[1][0] * v.x + m.m[1][1] * v.y + m.m[1][2] * v.z + m.m[1][3]; 96 res.y = m.m[1][0] * v.x + m.m[1][1] * v.y + m.m[1][2] * v.z + m.m[1][3];
76 res.z = m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z + m.m[2][3]; 97 res.z = m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z + m.m[2][3];
77 return res; 98 return res;
78 } 99 }
79 100
80 // Rotation only, ignore translation components.
81 gvr::Vec3f MatrixVectorRotate(const gvr::Mat4f& m, const gvr::Vec3f& v) { 101 gvr::Vec3f MatrixVectorRotate(const gvr::Mat4f& m, const gvr::Vec3f& v) {
82 gvr::Vec3f res; 102 gvr::Vec3f res;
83 res.x = m.m[0][0] * v.x + m.m[0][1] * v.y + m.m[0][2] * v.z; 103 res.x = m.m[0][0] * v.x + m.m[0][1] * v.y + m.m[0][2] * v.z;
84 res.y = m.m[1][0] * v.x + m.m[1][1] * v.y + m.m[1][2] * v.z; 104 res.y = m.m[1][0] * v.x + m.m[1][1] * v.y + m.m[1][2] * v.z;
85 res.z = m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z; 105 res.z = m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z;
86 return res; 106 return res;
87 } 107 }
88 108
89 gvr::Mat4f MatrixMul(const gvr::Mat4f& matrix1, const gvr::Mat4f& matrix2) { 109 gvr::Mat4f MatrixMul(const gvr::Mat4f& matrix1, const gvr::Mat4f& matrix2) {
90 gvr::Mat4f result; 110 gvr::Mat4f result;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 gvr::Vec3f GetForwardVector(const gvr::Mat4f& matrix) { 156 gvr::Vec3f GetForwardVector(const gvr::Mat4f& matrix) {
137 // Same as multiplying the inverse of the rotation component of the matrix by 157 // Same as multiplying the inverse of the rotation component of the matrix by
138 // (0, 0, -1, 0). 158 // (0, 0, -1, 0).
139 return {-matrix.m[2][0], -matrix.m[2][1], -matrix.m[2][2]}; 159 return {-matrix.m[2][0], -matrix.m[2][1], -matrix.m[2][2]};
140 } 160 }
141 161
142 gvr::Vec3f GetTranslation(const gvr::Mat4f& matrix) { 162 gvr::Vec3f GetTranslation(const gvr::Mat4f& matrix) {
143 return {matrix.m[0][3], matrix.m[1][3], matrix.m[2][3]}; 163 return {matrix.m[0][3], matrix.m[1][3], matrix.m[2][3]};
144 } 164 }
145 165
166 float VectorLengthSquared(const gvr::Vec3f& vec) {
167 return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z;
168 }
169
146 float VectorLength(const gvr::Vec3f& vec) { 170 float VectorLength(const gvr::Vec3f& vec) {
147 return sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z); 171 return sqrt(VectorLengthSquared(vec));
148 } 172 }
149 173
150 gvr::Vec3f VectorSubtract(const gvr::Vec3f& a, const gvr::Vec3f& b) { 174 gvr::Vec3f VectorSubtract(const gvr::Vec3f& a, const gvr::Vec3f& b) {
151 return {a.x - b.x, a.y - b.y, a.z - b.z}; 175 return {a.x - b.x, a.y - b.y, a.z - b.z};
152 } 176 }
153 177
178 gvr::Vec3f VectorAdd(const gvr::Vec3f& a, const gvr::Vec3f& b) {
179 return {a.x + b.x, a.y + b.y, a.z + b.z};
180 }
181
154 float NormalizeVector(gvr::Vec3f& vec) { 182 float NormalizeVector(gvr::Vec3f& vec) {
155 float len = VectorLength(vec); 183 float len = VectorLength(vec);
156 vec.x /= len; 184 if (len != 0.0f)
157 vec.y /= len; 185 len = 1.f / len;
158 vec.z /= len; 186 vec.x *= len;
187 vec.y *= len;
188 vec.z *= len;
159 return len; 189 return len;
160 } 190 }
161 191
162 float VectorDot(const gvr::Vec3f& a, const gvr::Vec3f& b) { 192 float VectorDot(const gvr::Vec3f& a, const gvr::Vec3f& b) {
163 return a.x * b.x + a.y * b.y + a.z * b.z; 193 return a.x * b.x + a.y * b.y + a.z * b.z;
164 } 194 }
165 195
196 gvr::Vec3f VectorCross(const gvr::Vec3f& a, const gvr::Vec3f& b) {
197 return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
198 }
199
200 gvr::Vec3f PointwiseVectorMul(const gvr::Vec3f& a, const gvr::Vec3f& b) {
201 return {a.x * b.x, a.y * b.y, a.z * b.z};
202 }
203
204 gvr::Vec3f VectorScalarMul(const gvr::Vec3f& a, float s) {
205 return {a.x * s, a.y * s, a.z * s};
206 }
207
208 float VectorAngleDegrees(const gvr::Vec3f& a, const gvr::Vec3f& b) {
209 float angle_radians = acos(VectorDot(a, b));
210 return ToDegrees(angle_radians);
cjgrant 2017/04/03 19:24:59 Could drop the intermediate variable here.
acondor_ 2017/04/19 18:44:27 Done.
211 }
212
166 void NormalizeQuat(gvr::Quatf& quat) { 213 void NormalizeQuat(gvr::Quatf& quat) {
167 float len = sqrt(quat.qx * quat.qx + quat.qy * quat.qy + quat.qz * quat.qz + 214 float len = sqrt(quat.qx * quat.qx + quat.qy * quat.qy + quat.qz * quat.qz +
168 quat.qw * quat.qw); 215 quat.qw * quat.qw);
169 quat.qx /= len; 216 quat.qx /= len;
170 quat.qy /= len; 217 quat.qy /= len;
171 quat.qz /= len; 218 quat.qz /= len;
172 quat.qw /= len; 219 quat.qw /= len;
173 } 220 }
174 221
222 gvr::Quatf QuatInverted(const gvr::Quatf& quat) {
223 return {-quat.qx, -quat.qy, -quat.qz, quat.qw};
224 }
225
226 float QuatAngleDegrees(const gvr::Quatf& a, const gvr::Quatf& b) {
227 return QuatMultiply(b, QuatInverted(a)).qw;
228 }
229
230 gvr::Quatf QuatLerp(const gvr::Quatf& a, const gvr::Quatf& b, float t) {
231 auto result = QuatAdd(QuatScalarMul(a, 1.f - t), QuatScalarMul(b, t));
232 NormalizeQuat(result);
cjgrant 2017/04/03 19:24:59 With the quantity of math changes here, it might b
acondor_ 2017/04/19 18:44:27 The change was already done. I just need to rebase
233 return result;
234 }
235
175 gvr::Quatf QuatFromAxisAngle(const gvr::Vec3f& axis, float angle) { 236 gvr::Quatf QuatFromAxisAngle(const gvr::Vec3f& axis, float angle) {
176 // Rotation angle is the product of |angle| and the magnitude of |axis|. 237 // Rotation angle is the product of |angle| and the magnitude of |axis|.
177 gvr::Vec3f normal = axis; 238 gvr::Vec3f normal = axis;
178 float length = NormalizeVector(normal); 239 float length = NormalizeVector(normal);
179 angle *= length; 240 angle *= length;
180 241
181 gvr::Quatf res; 242 gvr::Quatf res;
182 float s = sin(angle / 2); 243 float s = sin(angle / 2);
183 res.qx = normal.x * s; 244 res.qx = normal.x * s;
184 res.qy = normal.y * s; 245 res.qy = normal.y * s;
185 res.qz = normal.z * s; 246 res.qz = normal.z * s;
186 res.qw = cos(angle / 2); 247 res.qw = cos(angle / 2);
187 return res; 248 return res;
188 } 249 }
189 250
251 gvr::Quatf FromToRotation(const gvr::Vec3f& from, const gvr::Vec3f& to) {
252 float dot = VectorDot(from, to);
253 float norm = sqrt(VectorLengthSquared(from) * VectorLengthSquared(to));
254 float real = norm + dot;
255 gvr::Vec3f w;
256 if (real < 1.e-6f * norm) {
257 real = 0.f;
258 w = fabsf(from.x) > fabsf(from.z) ? gvr::Vec3f{-from.y, from.x, 0.f}
259 : gvr::Vec3f{0.f, -from.z, from.y};
260 } else {
261 w = VectorCross(from, to);
262 }
263 gvr::Quatf result{w.x, w.y, w.z, real};
264 NormalizeQuat(result);
265 return result;
266 }
267
190 gvr::Quatf QuatMultiply(const gvr::Quatf& a, const gvr::Quatf& b) { 268 gvr::Quatf QuatMultiply(const gvr::Quatf& a, const gvr::Quatf& b) {
191 gvr::Quatf res; 269 gvr::Quatf res;
192 res.qw = a.qw * b.qw - a.qx * b.qx - a.qy * b.qy - a.qz * b.qz; 270 res.qw = a.qw * b.qw - a.qx * b.qx - a.qy * b.qy - a.qz * b.qz;
193 res.qx = a.qw * b.qx + a.qx * b.qw + a.qy * b.qz - a.qz * b.qy; 271 res.qx = a.qw * b.qx + a.qx * b.qw + a.qy * b.qz - a.qz * b.qy;
194 res.qy = a.qw * b.qy - a.qx * b.qz + a.qy * b.qw + a.qz * b.qx; 272 res.qy = a.qw * b.qy - a.qx * b.qz + a.qy * b.qw + a.qz * b.qx;
195 res.qz = a.qw * b.qz + a.qx * b.qy - a.qy * b.qx + a.qz * b.qw; 273 res.qz = a.qw * b.qz + a.qx * b.qy - a.qy * b.qx + a.qz * b.qw;
196 return res; 274 return res;
197 } 275 }
198 276
277 gvr::Quatf QuatAdd(const gvr::Quatf& a, const gvr::Quatf& b) {
278 return {a.qx + b.qx, a.qy + b.qy, a.qz + b.qz, a.qw + b.qw};
279 }
280
281 gvr::Quatf QuatScalarMul(const gvr::Quatf& quat, float s) {
282 return {quat.qx * s, quat.qy * s, quat.qz * s, quat.qw * s};
283 }
284
199 gvr::Mat4f QuatToMatrix(const gvr::Quatf& quat) { 285 gvr::Mat4f QuatToMatrix(const gvr::Quatf& quat) {
200 const float x2 = quat.qx * quat.qx; 286 const float x2 = quat.qx * quat.qx;
201 const float y2 = quat.qy * quat.qy; 287 const float y2 = quat.qy * quat.qy;
202 const float z2 = quat.qz * quat.qz; 288 const float z2 = quat.qz * quat.qz;
203 const float xy = quat.qx * quat.qy; 289 const float xy = quat.qx * quat.qy;
204 const float xz = quat.qx * quat.qz; 290 const float xz = quat.qx * quat.qz;
205 const float xw = quat.qx * quat.qw; 291 const float xw = quat.qx * quat.qw;
206 const float yz = quat.qy * quat.qz; 292 const float yz = quat.qy * quat.qz;
207 const float yw = quat.qy * quat.qw; 293 const float yw = quat.qy * quat.qw;
208 const float zw = quat.qz * quat.qw; 294 const float zw = quat.qz * quat.qw;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 float len1 = VectorLength(vec1); 327 float len1 = VectorLength(vec1);
242 float len2 = VectorLength(vec2); 328 float len2 = VectorLength(vec2);
243 if (len1 == 0 || len2 == 0) 329 if (len1 == 0 || len2 == 0)
244 return false; 330 return false;
245 float cross_p = vec1.x * vec2.z - vec1.z * vec2.x; 331 float cross_p = vec1.x * vec2.z - vec1.z * vec2.x;
246 *angle = asin(cross_p / (len1 * len2)); 332 *angle = asin(cross_p / (len1 * len2));
247 return true; 333 return true;
248 } 334 }
249 335
250 } // namespace vr_shell 336 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698