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

Side by Side Diff: device/vr/vr_math.cc

Issue 2814443004: Refactor VR math off of GVR types, onto gfx types where possible. (Closed)
Patch Set: Fix tests 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
« no previous file with comments | « device/vr/vr_math.h ('k') | device/vr/vr_types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "device/vr/vr_math.h"
6
7 #include <cmath>
8
9 #include "base/logging.h"
10
11 namespace vr {
12
13 namespace {
14 Mat4f CopyMat(const Mat4f& mat) {
15 Mat4f ret = mat;
16 return ret;
17 }
18 }
19
20 // Internal matrix layout:
21 //
22 // m[0][0], m[0][1], m[0][2], m[0][3],
23 // m[1][0], m[1][1], m[1][2], m[1][3],
24 // m[2][0], m[2][1], m[2][2], m[2][3],
25 // m[3][0], m[3][1], m[3][2], m[3][3],
26 //
27 // The translation component is in the right column m[i][3].
28 //
29 // The bottom row m[3][i] is (0, 0, 0, 1) for non-perspective transforms.
30 //
31 // These matrices are intended to be used to premultiply column vectors
32 // for transforms, so successive transforms need to be left-multiplied.
33
34 void SetIdentityM(Mat4f* mat) {
35 for (int i = 0; i < 4; i++) {
36 for (int j = 0; j < 4; j++) {
37 (*mat)[i][j] = i == j ? 1 : 0;
38 }
39 }
40 }
41
42 // Left multiply a translation matrix.
43 void TranslateM(const Mat4f& mat,
44 const gfx::Vector3dF& translation,
45 Mat4f* out) {
46 if (out != &mat) {
47 for (int i = 0; i < 4; ++i) {
48 for (int j = 0; j < 4; ++j) {
49 (*out)[i][j] = mat[i][j];
50 }
51 }
52 }
53 (*out)[0][3] += translation.x();
54 (*out)[1][3] += translation.y();
55 (*out)[2][3] += translation.z();
56 }
57
58 // Left multiply a scale matrix.
59 void ScaleM(const Mat4f& mat, const gfx::Vector3dF& scale, Mat4f* out) {
60 if (out != &mat) {
61 for (int i = 0; i < 4; ++i) {
62 for (int j = 0; j < 3; ++j) {
63 (*out)[i][j] = mat[i][j];
64 }
65 }
66 }
67 // Multiply all rows including translation components.
68 for (int j = 0; j < 4; ++j) {
69 (*out)[0][j] *= scale.x();
70 (*out)[1][j] *= scale.y();
71 (*out)[2][j] *= scale.z();
72 }
73 }
74
75 gfx::Vector3dF MatrixVectorMul(const Mat4f& m, const gfx::Vector3dF& v) {
76 return gfx::Vector3dF(
77 m[0][0] * v.x() + m[0][1] * v.y() + m[0][2] * v.z() + m[0][3],
78 m[1][0] * v.x() + m[1][1] * v.y() + m[1][2] * v.z() + m[1][3],
79 m[2][0] * v.x() + m[2][1] * v.y() + m[2][2] * v.z() + m[2][3]);
80 }
81
82 // Rotation only, ignore translation components.
83 gfx::Vector3dF MatrixVectorRotate(const Mat4f& m, const gfx::Vector3dF& v) {
84 return gfx::Vector3dF(m[0][0] * v.x() + m[0][1] * v.y() + m[0][2] * v.z(),
85 m[1][0] * v.x() + m[1][1] * v.y() + m[1][2] * v.z(),
86 m[2][0] * v.x() + m[2][1] * v.y() + m[2][2] * v.z());
87 }
88
89 void MatrixMul(const Mat4f& matrix1, const Mat4f& matrix2, Mat4f* out) {
90 const Mat4f& mat1 = (out == &matrix1) ? CopyMat(matrix1) : matrix1;
91 const Mat4f& mat2 = (out == &matrix2) ? CopyMat(matrix2) : matrix2;
92 for (int i = 0; i < 4; ++i) {
93 for (int j = 0; j < 4; ++j) {
94 (*out)[i][j] = 0.0f;
95 for (int k = 0; k < 4; ++k) {
96 (*out)[i][j] += mat1[i][k] * mat2[k][j];
97 }
98 }
99 }
100 }
101
102 void PerspectiveMatrixFromView(const gfx::RectF& fov,
103 float z_near,
104 float z_far,
105 Mat4f* out) {
106 const float x_left = -std::tan(fov.x() * M_PI / 180.0f) * z_near;
107 const float x_right = std::tan(fov.right() * M_PI / 180.0f) * z_near;
108 const float y_bottom = -std::tan(fov.bottom() * M_PI / 180.0f) * z_near;
109 const float y_top = std::tan(fov.y() * M_PI / 180.0f) * z_near;
110
111 DCHECK(x_left < x_right && y_bottom < y_top && z_near < z_far &&
112 z_near > 0.0f && z_far > 0.0f);
113 const float X = (2 * z_near) / (x_right - x_left);
114 const float Y = (2 * z_near) / (y_top - y_bottom);
115 const float A = (x_right + x_left) / (x_right - x_left);
116 const float B = (y_top + y_bottom) / (y_top - y_bottom);
117 const float C = (z_near + z_far) / (z_near - z_far);
118 const float D = (2 * z_near * z_far) / (z_near - z_far);
119
120 for (int i = 0; i < 4; ++i) {
121 (*out)[i].fill(0.0f);
122 }
123 (*out)[0][0] = X;
124 (*out)[0][2] = A;
125 (*out)[1][1] = Y;
126 (*out)[1][2] = B;
127 (*out)[2][2] = C;
128 (*out)[2][3] = D;
129 (*out)[3][2] = -1;
130 }
131
132 gfx::Vector3dF GetForwardVector(const Mat4f& matrix) {
133 // Same as multiplying the inverse of the rotation component of the matrix by
134 // (0, 0, -1, 0).
135 return gfx::Vector3dF(-matrix[2][0], -matrix[2][1], -matrix[2][2]);
136 }
137
138 gfx::Vector3dF GetTranslation(const Mat4f& matrix) {
139 return gfx::Vector3dF(matrix[0][3], matrix[1][3], matrix[2][3]);
140 }
141
142 float NormalizeVector(gfx::Vector3dF* vec) {
143 float len = vec->Length();
144 if (len == 0)
145 return 0;
146 vec->Scale(1.0f / len);
147 return len;
148 }
149
150 void NormalizeQuat(Quatf* quat) {
151 float len = sqrt(quat->qx * quat->qx + quat->qy * quat->qy +
152 quat->qz * quat->qz + quat->qw * quat->qw);
153 quat->qx /= len;
154 quat->qy /= len;
155 quat->qz /= len;
156 quat->qw /= len;
157 }
158
159 Quatf QuatFromAxisAngle(const RotationAxisAngle& axis_angle) {
160 // Rotation angle is the product of |angle| and the magnitude of |axis|.
161 gfx::Vector3dF normal(axis_angle.x, axis_angle.y, axis_angle.z);
162 float length = NormalizeVector(&normal);
163 float angle = axis_angle.angle * length;
164
165 Quatf res;
166 float s = sin(angle / 2);
167 res.qx = normal.x() * s;
168 res.qy = normal.y() * s;
169 res.qz = normal.z() * s;
170 res.qw = cos(angle / 2);
171 return res;
172 }
173
174 Quatf QuatMultiply(const Quatf& a, const Quatf& b) {
175 Quatf res;
176 res.qw = a.qw * b.qw - a.qx * b.qx - a.qy * b.qy - a.qz * b.qz;
177 res.qx = a.qw * b.qx + a.qx * b.qw + a.qy * b.qz - a.qz * b.qy;
178 res.qy = a.qw * b.qy - a.qx * b.qz + a.qy * b.qw + a.qz * b.qx;
179 res.qz = a.qw * b.qz + a.qx * b.qy - a.qy * b.qx + a.qz * b.qw;
180 return res;
181 }
182
183 void QuatToMatrix(const Quatf& quat, Mat4f* out) {
184 const float x2 = quat.qx * quat.qx;
185 const float y2 = quat.qy * quat.qy;
186 const float z2 = quat.qz * quat.qz;
187 const float xy = quat.qx * quat.qy;
188 const float xz = quat.qx * quat.qz;
189 const float xw = quat.qx * quat.qw;
190 const float yz = quat.qy * quat.qz;
191 const float yw = quat.qy * quat.qw;
192 const float zw = quat.qz * quat.qw;
193
194 const float m11 = 1.0f - 2.0f * y2 - 2.0f * z2;
195 const float m12 = 2.0f * (xy - zw);
196 const float m13 = 2.0f * (xz + yw);
197 const float m21 = 2.0f * (xy + zw);
198 const float m22 = 1.0f - 2.0f * x2 - 2.0f * z2;
199 const float m23 = 2.0f * (yz - xw);
200 const float m31 = 2.0f * (xz - yw);
201 const float m32 = 2.0f * (yz + xw);
202 const float m33 = 1.0f - 2.0f * x2 - 2.0f * y2;
203
204 *out = {{{{m11, m12, m13, 0.0f}},
205 {{m21, m22, m23, 0.0f}},
206 {{m31, m32, m33, 0.0f}},
207 {{0.0f, 0.0f, 0.0f, 1.0f}}}};
208 }
209
210 gfx::Point3F GetRayPoint(const gfx::Point3F& rayOrigin,
211 const gfx::Vector3dF& rayVector,
212 float scale) {
213 return rayOrigin + gfx::ScaleVector3d(rayVector, scale);
214 }
215
216 float Distance(const gfx::Point3F& p1, const gfx::Point3F& p2) {
217 return std::sqrt(p1.SquaredDistanceTo(p2));
218 }
219
220 bool XZAngle(const gfx::Vector3dF& vec1,
221 const gfx::Vector3dF& vec2,
222 float* angle) {
223 float len1 = vec1.Length();
224 float len2 = vec2.Length();
225 if (len1 == 0 || len2 == 0)
226 return false;
227 float cross_p = vec1.x() * vec2.z() - vec1.z() * vec2.x();
228 *angle = asin(cross_p / (len1 * len2));
229 return true;
230 }
231
232 } // namespace vr
OLDNEW
« no previous file with comments | « device/vr/vr_math.h ('k') | device/vr/vr_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698