| OLD | NEW | 
|---|
|  | (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 "chrome/browser/android/vr_shell/vr_math.h" |  | 
| 6 |  | 
| 7 #include <cmath> |  | 
| 8 |  | 
| 9 #include "base/logging.h" |  | 
| 10 |  | 
| 11 namespace vr_shell { |  | 
| 12 |  | 
| 13 // Internal matrix layout: |  | 
| 14 // |  | 
| 15 //   m[0][0], m[0][1], m[0][2], m[0][3], |  | 
| 16 //   m[1][0], m[1][1], m[1][2], m[1][3], |  | 
| 17 //   m[2][0], m[2][1], m[2][2], m[2][3], |  | 
| 18 //   m[3][0], m[3][1], m[3][2], m[3][3], |  | 
| 19 // |  | 
| 20 // The translation component is in the right column m[i][3]. |  | 
| 21 // |  | 
| 22 // The bottom row m[3][i] is (0, 0, 0, 1) for non-perspective transforms. |  | 
| 23 // |  | 
| 24 // These matrices are intended to be used to premultiply column vectors |  | 
| 25 // for transforms, so successive transforms need to be left-multiplied. |  | 
| 26 |  | 
| 27 void SetIdentityM(gvr::Mat4f& mat) { |  | 
| 28   float* m = reinterpret_cast<float*>(mat.m); |  | 
| 29   for (int i = 0; i < 16; i++) { |  | 
| 30     m[i] = 0; |  | 
| 31   } |  | 
| 32   for (int i = 0; i < 16; i += 5) { |  | 
| 33     m[i] = 1.0f; |  | 
| 34   } |  | 
| 35 } |  | 
| 36 |  | 
| 37 // Left multiply a translation matrix. |  | 
| 38 void TranslateM(gvr::Mat4f& tmat, gvr::Mat4f& mat, float x, float y, float z) { |  | 
| 39   if (&tmat != &mat) { |  | 
| 40     for (int i = 0; i < 4; ++i) { |  | 
| 41       for (int j = 0; j < 4; ++j) { |  | 
| 42         tmat.m[i][j] = mat.m[i][j]; |  | 
| 43       } |  | 
| 44     } |  | 
| 45   } |  | 
| 46   tmat.m[0][3] += x; |  | 
| 47   tmat.m[1][3] += y; |  | 
| 48   tmat.m[2][3] += z; |  | 
| 49 } |  | 
| 50 |  | 
| 51 // Left multiply a scale matrix. |  | 
| 52 void ScaleM(gvr::Mat4f& tmat, |  | 
| 53             const gvr::Mat4f& mat, |  | 
| 54             float x, |  | 
| 55             float y, |  | 
| 56             float z) { |  | 
| 57   if (&tmat != &mat) { |  | 
| 58     for (int i = 0; i < 4; ++i) { |  | 
| 59       for (int j = 0; j < 3; ++j) { |  | 
| 60         tmat.m[i][j] = mat.m[i][j]; |  | 
| 61       } |  | 
| 62     } |  | 
| 63   } |  | 
| 64   // Multiply all rows including translation components. |  | 
| 65   for (int j = 0; j < 4; ++j) { |  | 
| 66     tmat.m[0][j] *= x; |  | 
| 67     tmat.m[1][j] *= y; |  | 
| 68     tmat.m[2][j] *= z; |  | 
| 69   } |  | 
| 70 } |  | 
| 71 |  | 
| 72 gvr::Vec3f MatrixVectorMul(const gvr::Mat4f& m, const gvr::Vec3f& v) { |  | 
| 73   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]; |  | 
| 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]; |  | 
| 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]; |  | 
| 77   return res; |  | 
| 78 } |  | 
| 79 |  | 
| 80 // Rotation only, ignore translation components. |  | 
| 81 gvr::Vec3f MatrixVectorRotate(const gvr::Mat4f& m, const gvr::Vec3f& v) { |  | 
| 82   gvr::Vec3f res; |  | 
| 83   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; |  | 
| 85   res.z = m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z; |  | 
| 86   return res; |  | 
| 87 } |  | 
| 88 |  | 
| 89 gvr::Mat4f MatrixMul(const gvr::Mat4f& matrix1, const gvr::Mat4f& matrix2) { |  | 
| 90   gvr::Mat4f result; |  | 
| 91   for (int i = 0; i < 4; ++i) { |  | 
| 92     for (int j = 0; j < 4; ++j) { |  | 
| 93       result.m[i][j] = 0.0f; |  | 
| 94       for (int k = 0; k < 4; ++k) { |  | 
| 95         result.m[i][j] += matrix1.m[i][k] * matrix2.m[k][j]; |  | 
| 96       } |  | 
| 97     } |  | 
| 98   } |  | 
| 99   return result; |  | 
| 100 } |  | 
| 101 |  | 
| 102 gvr::Mat4f PerspectiveMatrixFromView(const gvr::Rectf& fov, |  | 
| 103                                      float z_near, |  | 
| 104                                      float z_far) { |  | 
| 105   gvr::Mat4f result; |  | 
| 106   const float x_left = -std::tan(fov.left * 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.top * 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     for (int j = 0; j < 4; ++j) { |  | 
| 122       result.m[i][j] = 0.0f; |  | 
| 123     } |  | 
| 124   } |  | 
| 125   result.m[0][0] = X; |  | 
| 126   result.m[0][2] = A; |  | 
| 127   result.m[1][1] = Y; |  | 
| 128   result.m[1][2] = B; |  | 
| 129   result.m[2][2] = C; |  | 
| 130   result.m[2][3] = D; |  | 
| 131   result.m[3][2] = -1; |  | 
| 132 |  | 
| 133   return result; |  | 
| 134 } |  | 
| 135 |  | 
| 136 gvr::Vec3f GetForwardVector(const gvr::Mat4f& matrix) { |  | 
| 137   // Same as multiplying the inverse of the rotation component of the matrix by |  | 
| 138   // (0, 0, -1, 0). |  | 
| 139   return {-matrix.m[2][0], -matrix.m[2][1], -matrix.m[2][2]}; |  | 
| 140 } |  | 
| 141 |  | 
| 142 gvr::Vec3f GetTranslation(const gvr::Mat4f& matrix) { |  | 
| 143   return {matrix.m[0][3], matrix.m[1][3], matrix.m[2][3]}; |  | 
| 144 } |  | 
| 145 |  | 
| 146 float VectorLength(const gvr::Vec3f& vec) { |  | 
| 147   return sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z); |  | 
| 148 } |  | 
| 149 |  | 
| 150 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}; |  | 
| 152 } |  | 
| 153 |  | 
| 154 float NormalizeVector(gvr::Vec3f& vec) { |  | 
| 155   float len = VectorLength(vec); |  | 
| 156   vec.x /= len; |  | 
| 157   vec.y /= len; |  | 
| 158   vec.z /= len; |  | 
| 159   return len; |  | 
| 160 } |  | 
| 161 |  | 
| 162 float VectorDot(const gvr::Vec3f& a, const gvr::Vec3f& b) { |  | 
| 163   return a.x * b.x + a.y * b.y + a.z * b.z; |  | 
| 164 } |  | 
| 165 |  | 
| 166 void NormalizeQuat(gvr::Quatf& quat) { |  | 
| 167   float len = sqrt(quat.qx * quat.qx + quat.qy * quat.qy + quat.qz * quat.qz + |  | 
| 168                    quat.qw * quat.qw); |  | 
| 169   quat.qx /= len; |  | 
| 170   quat.qy /= len; |  | 
| 171   quat.qz /= len; |  | 
| 172   quat.qw /= len; |  | 
| 173 } |  | 
| 174 |  | 
| 175 gvr::Quatf QuatFromAxisAngle(const gvr::Vec3f& axis, float angle) { |  | 
| 176   // Rotation angle is the product of |angle| and the magnitude of |axis|. |  | 
| 177   gvr::Vec3f normal = axis; |  | 
| 178   float length = NormalizeVector(normal); |  | 
| 179   angle *= length; |  | 
| 180 |  | 
| 181   gvr::Quatf res; |  | 
| 182   float s = sin(angle / 2); |  | 
| 183   res.qx = normal.x * s; |  | 
| 184   res.qy = normal.y * s; |  | 
| 185   res.qz = normal.z * s; |  | 
| 186   res.qw = cos(angle / 2); |  | 
| 187   return res; |  | 
| 188 } |  | 
| 189 |  | 
| 190 gvr::Quatf QuatMultiply(const gvr::Quatf& a, const gvr::Quatf& b) { |  | 
| 191   gvr::Quatf res; |  | 
| 192   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; |  | 
| 194   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; |  | 
| 196   return res; |  | 
| 197 } |  | 
| 198 |  | 
| 199 gvr::Mat4f QuatToMatrix(const gvr::Quatf& quat) { |  | 
| 200   const float x2 = quat.qx * quat.qx; |  | 
| 201   const float y2 = quat.qy * quat.qy; |  | 
| 202   const float z2 = quat.qz * quat.qz; |  | 
| 203   const float xy = quat.qx * quat.qy; |  | 
| 204   const float xz = quat.qx * quat.qz; |  | 
| 205   const float xw = quat.qx * quat.qw; |  | 
| 206   const float yz = quat.qy * quat.qz; |  | 
| 207   const float yw = quat.qy * quat.qw; |  | 
| 208   const float zw = quat.qz * quat.qw; |  | 
| 209 |  | 
| 210   const float m11 = 1.0f - 2.0f * y2 - 2.0f * z2; |  | 
| 211   const float m12 = 2.0f * (xy - zw); |  | 
| 212   const float m13 = 2.0f * (xz + yw); |  | 
| 213   const float m21 = 2.0f * (xy + zw); |  | 
| 214   const float m22 = 1.0f - 2.0f * x2 - 2.0f * z2; |  | 
| 215   const float m23 = 2.0f * (yz - xw); |  | 
| 216   const float m31 = 2.0f * (xz - yw); |  | 
| 217   const float m32 = 2.0f * (yz + xw); |  | 
| 218   const float m33 = 1.0f - 2.0f * x2 - 2.0f * y2; |  | 
| 219 |  | 
| 220   return {{{m11, m12, m13, 0.0f}, |  | 
| 221            {m21, m22, m23, 0.0f}, |  | 
| 222            {m31, m32, m33, 0.0f}, |  | 
| 223            {0.0f, 0.0f, 0.0f, 1.0f}}}; |  | 
| 224 } |  | 
| 225 |  | 
| 226 gvr::Vec3f GetRayPoint(const gvr::Vec3f& rayOrigin, |  | 
| 227                        const gvr::Vec3f& rayVector, |  | 
| 228                        float scale) { |  | 
| 229   gvr::Vec3f v; |  | 
| 230   v.x = rayOrigin.x + scale * rayVector.x; |  | 
| 231   v.y = rayOrigin.y + scale * rayVector.y; |  | 
| 232   v.z = rayOrigin.z + scale * rayVector.z; |  | 
| 233   return v; |  | 
| 234 } |  | 
| 235 |  | 
| 236 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) { |  | 
| 237   return VectorLength(VectorSubtract(vec1, vec2)); |  | 
| 238 } |  | 
| 239 |  | 
| 240 bool XZAngle(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2, float* angle) { |  | 
| 241   float len1 = VectorLength(vec1); |  | 
| 242   float len2 = VectorLength(vec2); |  | 
| 243   if (len1 == 0 || len2 == 0) |  | 
| 244     return false; |  | 
| 245   float cross_p = vec1.x * vec2.z - vec1.z * vec2.x; |  | 
| 246   *angle = asin(cross_p / (len1 * len2)); |  | 
| 247   return true; |  | 
| 248 } |  | 
| 249 |  | 
| 250 }  // namespace vr_shell |  | 
| OLD | NEW | 
|---|