Rename plugins to external

This commit is contained in:
Willy-JL
2023-03-17 22:50:23 +00:00
parent b3c64d0428
commit b34a4f2468
1706 changed files with 15 additions and 15 deletions

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARDBOARD_SDK_UTIL_LOGGING_H_
#define CARDBOARD_SDK_UTIL_LOGGING_H_
#include <furi.h>
#include <furi_hal.h>
#if defined(__ANDROID__)
#include <android/log.h>
// Uncomment these to enable debug logging from native code
#define CARDBOARD_LOGI(...) // __android_log_print(ANDROID_LOG_INFO, "CardboardSDK", __VA_ARGS__)
#define CARDBOARD_LOGE(...) // __android_log_print(ANDROID_LOG_ERROR, "CardboardSDK", __VA_ARGS__)
#else
#define CARDBOARD_LOGI(...) // FURI_LOG_I("CardboardSDK", __VA_ARGS__)
#define CARDBOARD_LOGE(...) // FURI_LOG_E("CardboardSDK", __VA_ARGS__)
#endif
#endif // CARDBOARD_SDK_UTIL_LOGGING_H_

View File

@@ -0,0 +1,121 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "matrix_3x3.h"
namespace cardboard {
Matrix3x3::Matrix3x3(double m00, double m01, double m02, double m10, double m11, double m12,
double m20, double m21, double m22)
: elem_ { { { m00, m01, m02 }, { m10, m11, m12 }, { m20, m21, m22 } } }
{
}
Matrix3x3::Matrix3x3()
{
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
elem_[row][col] = 0;
}
}
Matrix3x3 Matrix3x3::Zero()
{
Matrix3x3 result;
return result;
}
Matrix3x3 Matrix3x3::Identity()
{
Matrix3x3 result;
for (int row = 0; row < 3; ++row) {
result.elem_[row][row] = 1;
}
return result;
}
void Matrix3x3::MultiplyScalar(double s)
{
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
elem_[row][col] *= s;
}
}
Matrix3x3 Matrix3x3::Negation() const
{
Matrix3x3 result;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
result.elem_[row][col] = -elem_[row][col];
}
return result;
}
Matrix3x3 Matrix3x3::Scale(const Matrix3x3& m, double s)
{
Matrix3x3 result;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
result.elem_[row][col] = m.elem_[row][col] * s;
}
return result;
}
Matrix3x3 Matrix3x3::Addition(const Matrix3x3& lhs, const Matrix3x3& rhs)
{
Matrix3x3 result;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
result.elem_[row][col] = lhs.elem_[row][col] + rhs.elem_[row][col];
}
return result;
}
Matrix3x3 Matrix3x3::Subtraction(const Matrix3x3& lhs, const Matrix3x3& rhs)
{
Matrix3x3 result;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
result.elem_[row][col] = lhs.elem_[row][col] - rhs.elem_[row][col];
}
return result;
}
Matrix3x3 Matrix3x3::Product(const Matrix3x3& m0, const Matrix3x3& m1)
{
Matrix3x3 result;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col) {
result.elem_[row][col] = 0;
for (int i = 0; i < 3; ++i)
result.elem_[row][col] += m0.elem_[row][i] * m1.elem_[i][col];
}
}
return result;
}
bool Matrix3x3::AreEqual(const Matrix3x3& m0, const Matrix3x3& m1)
{
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col) {
if (m0.elem_[row][col] != m1.elem_[row][col])
return false;
}
}
return true;
}
} // namespace cardboard

View File

@@ -0,0 +1,138 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARDBOARD_SDK_UTIL_MATRIX_3X3_H_
#define CARDBOARD_SDK_UTIL_MATRIX_3X3_H_
#include <array>
#include <cstring> // For memcpy().
#include <istream> // NOLINT
#include <ostream> // NOLINT
namespace cardboard {
// The Matrix3x3 class defines a square 3-dimensional matrix. Elements are
// stored in row-major order.
// TODO(b/135461889): Make this class consistent with Matrix4x4.
class Matrix3x3 {
public:
// The default constructor zero-initializes all elements.
Matrix3x3();
// Dimension-specific constructors that are passed individual element values.
Matrix3x3(
double m00,
double m01,
double m02,
double m10,
double m11,
double m12,
double m20,
double m21,
double m22);
// Constructor that reads elements from a linear array of the correct size.
explicit Matrix3x3(const double array[3 * 3]);
// Returns a Matrix3x3 containing all zeroes.
static Matrix3x3 Zero();
// Returns an identity Matrix3x3.
static Matrix3x3 Identity();
// Mutable element accessors.
double& operator()(int row, int col) {
return elem_[row][col];
}
std::array<double, 3>& operator[](int row) {
return elem_[row];
}
// Read-only element accessors.
const double& operator()(int row, int col) const {
return elem_[row][col];
}
const std::array<double, 3>& operator[](int row) const {
return elem_[row];
}
// Return a pointer to the data for interfacing with libraries.
double* Data() {
return &elem_[0][0];
}
const double* Data() const {
return &elem_[0][0];
}
// Self-modifying multiplication operators.
void operator*=(double s) {
MultiplyScalar(s);
}
void operator*=(const Matrix3x3& m) {
*this = Product(*this, m);
}
// Unary operators.
Matrix3x3 operator-() const {
return Negation();
}
// Binary scale operators.
friend Matrix3x3 operator*(const Matrix3x3& m, double s) {
return Scale(m, s);
}
friend Matrix3x3 operator*(double s, const Matrix3x3& m) {
return Scale(m, s);
}
// Binary matrix addition.
friend Matrix3x3 operator+(const Matrix3x3& lhs, const Matrix3x3& rhs) {
return Addition(lhs, rhs);
}
// Binary matrix subtraction.
friend Matrix3x3 operator-(const Matrix3x3& lhs, const Matrix3x3& rhs) {
return Subtraction(lhs, rhs);
}
// Binary multiplication operator.
friend Matrix3x3 operator*(const Matrix3x3& m0, const Matrix3x3& m1) {
return Product(m0, m1);
}
// Exact equality and inequality comparisons.
friend bool operator==(const Matrix3x3& m0, const Matrix3x3& m1) {
return AreEqual(m0, m1);
}
friend bool operator!=(const Matrix3x3& m0, const Matrix3x3& m1) {
return !AreEqual(m0, m1);
}
private:
// These private functions implement most of the operators.
void MultiplyScalar(double s);
Matrix3x3 Negation() const;
static Matrix3x3 Addition(const Matrix3x3& lhs, const Matrix3x3& rhs);
static Matrix3x3 Subtraction(const Matrix3x3& lhs, const Matrix3x3& rhs);
static Matrix3x3 Scale(const Matrix3x3& m, double s);
static Matrix3x3 Product(const Matrix3x3& m0, const Matrix3x3& m1);
static bool AreEqual(const Matrix3x3& m0, const Matrix3x3& m1);
std::array<std::array<double, 3>, 3> elem_;
};
} // namespace cardboard
#endif // CARDBOARD_SDK_UTIL_MATRIX_3X3_H_

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "matrix_4x4.h"
#include <algorithm>
#include <cmath>
#include <cstring>
namespace cardboard {
Matrix4x4 Matrix4x4::Identity()
{
Matrix4x4 ret;
for (int j = 0; j < 4; ++j) {
for (int i = 0; i < 4; ++i) {
ret.m[j][i] = (i == j) ? 1 : 0;
}
}
return ret;
}
Matrix4x4 Matrix4x4::Zeros()
{
Matrix4x4 ret;
for (int j = 0; j < 4; ++j) {
for (int i = 0; i < 4; ++i) {
ret.m[j][i] = 0;
}
}
return ret;
}
Matrix4x4 Matrix4x4::Translation(float x, float y, float z)
{
Matrix4x4 ret = Matrix4x4::Identity();
ret.m[3][0] = x;
ret.m[3][1] = y;
ret.m[3][2] = z;
return ret;
}
Matrix4x4 Matrix4x4::Perspective(const std::array<float, 4>& fov, float zNear, float zFar)
{
Matrix4x4 ret = Matrix4x4::Zeros();
const float xLeft = -std::tan(fov[0] * M_PI / 180.0f) * zNear;
const float xRight = std::tan(fov[1] * M_PI / 180.0f) * zNear;
const float yBottom = -std::tan(fov[2] * M_PI / 180.0f) * zNear;
const float yTop = std::tan(fov[3] * M_PI / 180.0f) * zNear;
const float X = (2 * zNear) / (xRight - xLeft);
const float Y = (2 * zNear) / (yTop - yBottom);
const float A = (xRight + xLeft) / (xRight - xLeft);
const float B = (yTop + yBottom) / (yTop - yBottom);
const float C = (zNear + zFar) / (zNear - zFar);
const float D = (2 * zNear * zFar) / (zNear - zFar);
ret.m[0][0] = X;
ret.m[2][0] = A;
ret.m[1][1] = Y;
ret.m[2][1] = B;
ret.m[2][2] = C;
ret.m[3][2] = D;
ret.m[2][3] = -1;
return ret;
}
void Matrix4x4::ToArray(float* array) const { std::memcpy(array, &m[0][0], 16 * sizeof(float)); }
} // namespace cardboard

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARDBOARD_SDK_UTIL_MATRIX_4X4_H_
#define CARDBOARD_SDK_UTIL_MATRIX_4X4_H_
#include <array>
namespace cardboard {
class Matrix4x4 {
public:
static Matrix4x4 Identity();
static Matrix4x4 Zeros();
static Matrix4x4 Translation(float x, float y, float z);
static Matrix4x4 Perspective(const std::array<float, 4>& fov, float zNear, float zFar);
void ToArray(float* array) const;
private:
std::array<std::array<float, 4>, 4> m;
};
} // namespace cardboard
#endif // CARDBOARD_SDK_UTIL_MATRIX4X4_H_

View File

@@ -0,0 +1,148 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "matrixutils.h"
#include "vectorutils.h"
namespace cardboard {
namespace {
// Returns true if the cofactor for a given row and column should be negated.
static bool IsCofactorNegated(int row, int col)
{
// Negated iff (row + col) is odd.
return ((row + col) & 1) != 0;
}
static double CofactorElement3(const Matrix3x3& m, int row, int col)
{
static const int index[3][2] = { { 1, 2 }, { 0, 2 }, { 0, 1 } };
const int i0 = index[row][0];
const int i1 = index[row][1];
const int j0 = index[col][0];
const int j1 = index[col][1];
const double cofactor = m(i0, j0) * m(i1, j1) - m(i0, j1) * m(i1, j0);
return IsCofactorNegated(row, col) ? -cofactor : cofactor;
}
// Multiplies a matrix and some type of column vector to
// produce another column vector of the same type.
Vector3 MultiplyMatrixAndVector(const Matrix3x3& m, const Vector3& v)
{
Vector3 result = Vector3::Zero();
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
result[row] += m(row, col) * v[col];
}
return result;
}
// Sets the upper 3x3 of a Matrix to represent a 3D rotation.
void RotationMatrix3x3(const Rotation& r, Matrix3x3* matrix)
{
//
// Given a quaternion (a,b,c,d) where d is the scalar part, the 3x3 rotation
// matrix is:
//
// a^2 - b^2 - c^2 + d^2 2ab - 2cd 2ac + 2bd
// 2ab + 2cd -a^2 + b^2 - c^2 + d^2 2bc - 2ad
// 2ac - 2bd 2bc + 2ad -a^2 - b^2 + c^2 + d^2
//
const Vector<4>& quat = r.GetQuaternion();
const double aa = quat[0] * quat[0];
const double bb = quat[1] * quat[1];
const double cc = quat[2] * quat[2];
const double dd = quat[3] * quat[3];
const double ab = quat[0] * quat[1];
const double ac = quat[0] * quat[2];
const double bc = quat[1] * quat[2];
const double ad = quat[0] * quat[3];
const double bd = quat[1] * quat[3];
const double cd = quat[2] * quat[3];
Matrix3x3& m = *matrix;
m[0][0] = aa - bb - cc + dd;
m[0][1] = 2 * ab - 2 * cd;
m[0][2] = 2 * ac + 2 * bd;
m[1][0] = 2 * ab + 2 * cd;
m[1][1] = -aa + bb - cc + dd;
m[1][2] = 2 * bc - 2 * ad;
m[2][0] = 2 * ac - 2 * bd;
m[2][1] = 2 * bc + 2 * ad;
m[2][2] = -aa - bb + cc + dd;
}
} // anonymous namespace
Vector3 operator*(const Matrix3x3& m, const Vector3& v) { return MultiplyMatrixAndVector(m, v); }
Matrix3x3 CofactorMatrix(const Matrix3x3& m)
{
Matrix3x3 result;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
result(row, col) = CofactorElement3(m, row, col);
}
return result;
}
Matrix3x3 AdjugateWithDeterminant(const Matrix3x3& m, double* determinant)
{
const Matrix3x3 cofactor_matrix = CofactorMatrix(m);
if (determinant) {
*determinant = m(0, 0) * cofactor_matrix(0, 0) + m(0, 1) * cofactor_matrix(0, 1)
+ m(0, 2) * cofactor_matrix(0, 2);
}
return Transpose(cofactor_matrix);
}
// Returns the transpose of a matrix.
Matrix3x3 Transpose(const Matrix3x3& m)
{
Matrix3x3 result;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col)
result(row, col) = m(col, row);
}
return result;
}
Matrix3x3 InverseWithDeterminant(const Matrix3x3& m, double* determinant)
{
// The inverse is the adjugate divided by the determinant.
double det;
Matrix3x3 adjugate = AdjugateWithDeterminant(m, &det);
if (determinant)
*determinant = det;
if (det == 0)
return Matrix3x3::Zero();
else
return adjugate * (1 / det);
}
Matrix3x3 Inverse(const Matrix3x3& m) { return InverseWithDeterminant(m, nullptr); }
Matrix3x3 RotationMatrixNH(const Rotation& r)
{
Matrix3x3 m;
RotationMatrix3x3(r, &m);
return m;
}
} // namespace cardboard

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARDBOARD_SDK_UTIL_MATRIXUTILS_H_
#define CARDBOARD_SDK_UTIL_MATRIXUTILS_H_
//
// This file contains operators and free functions that define generic Matrix
// operations.
//
#include "matrix_3x3.h"
#include "rotation.h"
#include "vector.h"
namespace cardboard {
// Returns the transpose of a matrix.
Matrix3x3 Transpose(const Matrix3x3& m);
// Multiplies a Matrix and a column Vector of the same Dimension to produce
// another column Vector.
Vector3 operator*(const Matrix3x3& m, const Vector3& v);
// Returns the determinant of the matrix. This function is defined for all the
// typedef'ed Matrix types.
double Determinant(const Matrix3x3& m);
// Returns the adjugate of the matrix, which is defined as the transpose of the
// cofactor matrix. This function is defined for all the typedef'ed Matrix
// types. The determinant of the matrix is computed as a side effect, so it is
// returned in the determinant parameter if it is not null.
Matrix3x3 AdjugateWithDeterminant(const Matrix3x3& m, double* determinant);
// Returns the inverse of the matrix. This function is defined for all the
// typedef'ed Matrix types. The determinant of the matrix is computed as a
// side effect, so it is returned in the determinant parameter if it is not
// null. If the determinant is 0, the returned matrix has all zeroes.
Matrix3x3 InverseWithDeterminant(const Matrix3x3& m, double* determinant);
// Returns the inverse of the matrix. This function is defined for all the
// typedef'ed Matrix types. If the determinant of the matrix is 0, the returned
// matrix has all zeroes.
Matrix3x3 Inverse(const Matrix3x3& m);
// Returns a 3x3 Matrix representing a 3D rotation. This creates a Matrix that
// does not work with homogeneous coordinates, so the function name ends in
// "NH".
Matrix3x3 RotationMatrixNH(const Rotation& r);
} // namespace cardboard
#endif // CARDBOARD_SDK_UTIL_MATRIXUTILS_H_

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "rotation.h"
#include <cmath>
#include <limits>
#include "vectorutils.h"
namespace cardboard {
void Rotation::SetAxisAndAngle(const VectorType& axis, double angle)
{
VectorType unit_axis = axis;
if (!Normalize(&unit_axis)) {
*this = Identity();
} else {
double a = angle / 2;
const double s = sin(a);
const VectorType v(unit_axis * s);
SetQuaternion(QuaternionType(v[0], v[1], v[2], cos(a)));
}
}
Rotation Rotation::FromRotationMatrix(const Matrix3x3& mat)
{
static const double kOne = 1.0;
static const double kFour = 4.0;
const double d0 = mat(0, 0), d1 = mat(1, 1), d2 = mat(2, 2);
const double ww = kOne + d0 + d1 + d2;
const double xx = kOne + d0 - d1 - d2;
const double yy = kOne - d0 + d1 - d2;
const double zz = kOne - d0 - d1 + d2;
const double max = std::max(ww, std::max(xx, std::max(yy, zz)));
if (ww == max) {
const double w4 = sqrt(ww * kFour);
return Rotation::FromQuaternion(QuaternionType((mat(2, 1) - mat(1, 2)) / w4,
(mat(0, 2) - mat(2, 0)) / w4, (mat(1, 0) - mat(0, 1)) / w4, w4 / kFour));
}
if (xx == max) {
const double x4 = sqrt(xx * kFour);
return Rotation::FromQuaternion(QuaternionType(x4 / kFour, (mat(0, 1) + mat(1, 0)) / x4,
(mat(0, 2) + mat(2, 0)) / x4, (mat(2, 1) - mat(1, 2)) / x4));
}
if (yy == max) {
const double y4 = sqrt(yy * kFour);
return Rotation::FromQuaternion(QuaternionType((mat(0, 1) + mat(1, 0)) / y4, y4 / kFour,
(mat(1, 2) + mat(2, 1)) / y4, (mat(0, 2) - mat(2, 0)) / y4));
}
// zz is the largest component.
const double z4 = sqrt(zz * kFour);
return Rotation::FromQuaternion(QuaternionType((mat(0, 2) + mat(2, 0)) / z4,
(mat(1, 2) + mat(2, 1)) / z4, z4 / kFour, (mat(1, 0) - mat(0, 1)) / z4));
}
void Rotation::GetAxisAndAngle(VectorType* axis, double* angle) const
{
VectorType vec(quat_[0], quat_[1], quat_[2]);
if (Normalize(&vec)) {
*angle = 2 * acos(quat_[3]);
*axis = vec;
} else {
*axis = VectorType(1, 0, 0);
*angle = 0.0;
}
}
Rotation Rotation::RotateInto(const VectorType& from, const VectorType& to)
{
static const double kTolerance = std::numeric_limits<double>::epsilon() * 100;
// Directly build the quaternion using the following technique:
// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final
const double norm_u_norm_v = sqrt(LengthSquared(from) * LengthSquared(to));
double real_part = norm_u_norm_v + Dot(from, to);
VectorType w;
if (real_part < kTolerance * norm_u_norm_v) {
// If |from| and |to| are exactly opposite, rotate 180 degrees around an
// arbitrary orthogonal axis. Axis normalization can happen later, when we
// normalize the quaternion.
real_part = 0.0;
w = (abs(from[0]) > abs(from[2])) ? VectorType(-from[1], from[0], 0)
: VectorType(0, -from[2], from[1]);
} else {
// Otherwise, build the quaternion the standard way.
w = Cross(from, to);
}
// Build and return a normalized quaternion.
// Note that Rotation::FromQuaternion automatically performs normalization.
return Rotation::FromQuaternion(QuaternionType(w[0], w[1], w[2], real_part));
}
Rotation::VectorType Rotation::operator*(const Rotation::VectorType& v) const
{
return ApplyToVector(v);
}
} // namespace cardboard

View File

@@ -0,0 +1,156 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARDBOARD_SDK_UTIL_ROTATION_H_
#define CARDBOARD_SDK_UTIL_ROTATION_H_
#include "matrix_3x3.h"
#include "vector.h"
#include "vectorutils.h"
namespace cardboard {
// The Rotation class represents a rotation around a 3-dimensional axis. It
// uses normalized quaternions internally to make the math robust.
class Rotation {
public:
// Convenience typedefs for vector of the correct type.
typedef Vector<3> VectorType;
typedef Vector<4> QuaternionType;
// The default constructor creates an identity Rotation, which has no effect.
Rotation() {
quat_.Set(0, 0, 0, 1);
}
// Returns an identity Rotation, which has no effect.
static Rotation Identity() {
return Rotation();
}
// Sets the Rotation from a quaternion (4D vector), which is first normalized.
void SetQuaternion(const QuaternionType& quaternion) {
quat_ = Normalized(quaternion);
}
// Returns the Rotation as a normalized quaternion (4D vector).
const QuaternionType& GetQuaternion() const {
return quat_;
}
// Sets the Rotation to rotate by the given angle around the given axis,
// following the right-hand rule. The axis does not need to be unit
// length. If it is zero length, this results in an identity Rotation.
void SetAxisAndAngle(const VectorType& axis, double angle);
// Returns the right-hand rule axis and angle corresponding to the
// Rotation. If the Rotation is the identity rotation, this returns the +X
// axis and an angle of 0.
void GetAxisAndAngle(VectorType* axis, double* angle) const;
// Convenience function that constructs and returns a Rotation given an axis
// and angle.
static Rotation FromAxisAndAngle(const VectorType& axis, double angle) {
Rotation r;
r.SetAxisAndAngle(axis, angle);
return r;
}
// Convenience function that constructs and returns a Rotation given a
// quaternion.
static Rotation FromQuaternion(const QuaternionType& quat) {
Rotation r;
r.SetQuaternion(quat);
return r;
}
// Convenience function that constructs and returns a Rotation given a
// rotation matrix R with $R^\top R = I && det(R) = 1$.
static Rotation FromRotationMatrix(const Matrix3x3& mat);
// Convenience function that constructs and returns a Rotation given Euler
// angles that are applied in the order of rotate-Z by roll, rotate-X by
// pitch, rotate-Y by yaw (same as GetRollPitchYaw).
static Rotation FromRollPitchYaw(double roll, double pitch, double yaw) {
VectorType x(1, 0, 0), y(0, 1, 0), z(0, 0, 1);
return FromAxisAndAngle(z, roll) * (FromAxisAndAngle(x, pitch) * FromAxisAndAngle(y, yaw));
}
// Convenience function that constructs and returns a Rotation given Euler
// angles that are applied in the order of rotate-Y by yaw, rotate-X by
// pitch, rotate-Z by roll (same as GetYawPitchRoll).
static Rotation FromYawPitchRoll(double yaw, double pitch, double roll) {
VectorType x(1, 0, 0), y(0, 1, 0), z(0, 0, 1);
return FromAxisAndAngle(y, yaw) * (FromAxisAndAngle(x, pitch) * FromAxisAndAngle(z, roll));
}
// Constructs and returns a Rotation that rotates one vector to another along
// the shortest arc. This returns an identity rotation if either vector has
// zero length.
static Rotation RotateInto(const VectorType& from, const VectorType& to);
// The negation operator returns the inverse rotation.
friend Rotation operator-(const Rotation& r) {
// Because we store normalized quaternions, the inverse is found by
// negating the vector part.
return Rotation(-r.quat_[0], -r.quat_[1], -r.quat_[2], r.quat_[3]);
}
// Appends a rotation to this one.
Rotation& operator*=(const Rotation& r) {
const QuaternionType& qr = r.quat_;
QuaternionType& qt = quat_;
SetQuaternion(QuaternionType(
qr[3] * qt[0] + qr[0] * qt[3] + qr[2] * qt[1] - qr[1] * qt[2],
qr[3] * qt[1] + qr[1] * qt[3] + qr[0] * qt[2] - qr[2] * qt[0],
qr[3] * qt[2] + qr[2] * qt[3] + qr[1] * qt[0] - qr[0] * qt[1],
qr[3] * qt[3] - qr[0] * qt[0] - qr[1] * qt[1] - qr[2] * qt[2]));
return *this;
}
// Binary multiplication operator - returns a composite Rotation.
friend const Rotation operator*(const Rotation& r0, const Rotation& r1) {
Rotation r = r0;
r *= r1;
return r;
}
// Multiply a Rotation and a Vector to get a Vector.
VectorType operator*(const VectorType& v) const;
private:
// Private constructor that builds a Rotation from quaternion components.
Rotation(double q0, double q1, double q2, double q3)
: quat_(q0, q1, q2, q3) {
}
// Applies a Rotation to a Vector to rotate the Vector. Method borrowed from:
// http://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/
VectorType ApplyToVector(const VectorType& v) const {
VectorType im(quat_[0], quat_[1], quat_[2]);
VectorType temp = 2.0 * Cross(im, v);
return v + quat_[3] * temp + Cross(im, temp);
}
// The rotation represented as a normalized quaternion. (Unit quaternions are
// required for constructing rotation matrices, so it makes sense to always
// store them that way.) The vector part is in the first 3 elements, and the
// scalar part is in the last element.
QuaternionType quat_;
};
} // namespace cardboard
#endif // CARDBOARD_SDK_UTIL_ROTATION_H_

View File

@@ -0,0 +1,251 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARDBOARD_SDK_UTIL_VECTOR_H_
#define CARDBOARD_SDK_UTIL_VECTOR_H_
#include <array>
namespace cardboard {
// Geometric N-dimensional Vector class.
template <int Dimension>
class Vector {
public:
// The default constructor zero-initializes all elements.
Vector();
// Dimension-specific constructors that are passed individual element values.
constexpr Vector(double e0, double e1, double e2);
constexpr Vector(double e0, double e1, double e2, double e3);
// Constructor for a Vector of dimension N from a Vector of dimension N-1 and
// a scalar of the correct type, assuming N is at least 2.
// constexpr Vector(const Vector<Dimension - 1>& v, double s);
void Set(double e0, double e1, double e2); // Only when Dimension == 3.
void Set(double e0, double e1, double e2,
double e3); // Only when Dimension == 4.
// Mutable element accessor.
double& operator[](int index) {
return elem_[index];
}
// Element accessor.
double operator[](int index) const {
return elem_[index];
}
// Returns a Vector containing all zeroes.
static Vector Zero();
// Self-modifying operators.
void operator+=(const Vector& v) {
Add(v);
}
void operator-=(const Vector& v) {
Subtract(v);
}
void operator*=(double s) {
Multiply(s);
}
void operator/=(double s) {
Divide(s);
}
// Unary negation operator.
Vector operator-() const {
return Negation();
}
// Binary operators.
friend Vector operator+(const Vector& v0, const Vector& v1) {
return Sum(v0, v1);
}
friend Vector operator-(const Vector& v0, const Vector& v1) {
return Difference(v0, v1);
}
friend Vector operator*(const Vector& v, double s) {
return Scale(v, s);
}
friend Vector operator*(double s, const Vector& v) {
return Scale(v, s);
}
friend Vector operator*(const Vector& v, const Vector& s) {
return Product(v, s);
}
friend Vector operator/(const Vector& v, double s) {
return Divide(v, s);
}
// Self-modifying addition.
void Add(const Vector& v);
// Self-modifying subtraction.
void Subtract(const Vector& v);
// Self-modifying multiplication by a scalar.
void Multiply(double s);
// Self-modifying division by a scalar.
void Divide(double s);
// Unary negation.
Vector Negation() const;
// Binary component-wise multiplication.
static Vector Product(const Vector& v0, const Vector& v1);
// Binary component-wise addition.
static Vector Sum(const Vector& v0, const Vector& v1);
// Binary component-wise subtraction.
static Vector Difference(const Vector& v0, const Vector& v1);
// Binary multiplication by a scalar.
static Vector Scale(const Vector& v, double s);
// Binary division by a scalar.
static Vector Divide(const Vector& v, double s);
private:
std::array<double, Dimension> elem_;
};
//------------------------------------------------------------------------------
template <int Dimension>
Vector<Dimension>::Vector() {
for(int i = 0; i < Dimension; i++) {
elem_[i] = 0;
}
}
template <int Dimension>
constexpr Vector<Dimension>::Vector(double e0, double e1, double e2)
: elem_{e0, e1, e2} {
}
template <int Dimension>
constexpr Vector<Dimension>::Vector(double e0, double e1, double e2, double e3)
: elem_{e0, e1, e2, e3} {
}
/*
template <>
constexpr Vector<4>::Vector(const Vector<3>& v, double s)
: elem_{v[0], v[1], v[2], s} {}
*/
template <int Dimension>
void Vector<Dimension>::Set(double e0, double e1, double e2) {
elem_[0] = e0;
elem_[1] = e1;
elem_[2] = e2;
}
template <int Dimension>
void Vector<Dimension>::Set(double e0, double e1, double e2, double e3) {
elem_[0] = e0;
elem_[1] = e1;
elem_[2] = e2;
elem_[3] = e3;
}
template <int Dimension>
Vector<Dimension> Vector<Dimension>::Zero() {
Vector<Dimension> v;
return v;
}
template <int Dimension>
void Vector<Dimension>::Add(const Vector& v) {
for(int i = 0; i < Dimension; i++) {
elem_[i] += v[i];
}
}
template <int Dimension>
void Vector<Dimension>::Subtract(const Vector& v) {
for(int i = 0; i < Dimension; i++) {
elem_[i] -= v[i];
}
}
template <int Dimension>
void Vector<Dimension>::Multiply(double s) {
for(int i = 0; i < Dimension; i++) {
elem_[i] *= s;
}
}
template <int Dimension>
void Vector<Dimension>::Divide(double s) {
for(int i = 0; i < Dimension; i++) {
elem_[i] /= s;
}
}
template <int Dimension>
Vector<Dimension> Vector<Dimension>::Negation() const {
Vector<Dimension> ret;
for(int i = 0; i < Dimension; i++) {
ret.elem_[i] = -elem_[i];
}
return ret;
}
template <int Dimension>
Vector<Dimension> Vector<Dimension>::Product(const Vector& v0, const Vector& v1) {
Vector<Dimension> ret;
for(int i = 0; i < Dimension; i++) {
ret.elem_[i] = v0[i] * v1[i];
}
return ret;
}
template <int Dimension>
Vector<Dimension> Vector<Dimension>::Sum(const Vector& v0, const Vector& v1) {
Vector<Dimension> ret;
for(int i = 0; i < Dimension; i++) {
ret.elem_[i] = v0[i] + v1[i];
}
return ret;
}
template <int Dimension>
Vector<Dimension> Vector<Dimension>::Difference(const Vector& v0, const Vector& v1) {
Vector<Dimension> ret;
for(int i = 0; i < Dimension; i++) {
ret.elem_[i] = v0[i] - v1[i];
}
return ret;
}
template <int Dimension>
Vector<Dimension> Vector<Dimension>::Scale(const Vector& v, double s) {
Vector<Dimension> ret;
for(int i = 0; i < Dimension; i++) {
ret.elem_[i] = v[i] * s;
}
return ret;
}
template <int Dimension>
Vector<Dimension> Vector<Dimension>::Divide(const Vector& v, double s) {
Vector<Dimension> ret;
for(int i = 0; i < Dimension; i++) {
ret.elem_[i] = v[i] / s;
}
return ret;
}
typedef Vector<3> Vector3;
typedef Vector<4> Vector4;
} // namespace cardboard
#endif // CARDBOARD_SDK_UTIL_VECTOR_H_

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vectorutils.h"
namespace cardboard {
// Returns the dot (inner) product of two Vectors.
double Dot(const Vector<3>& v0, const Vector<3>& v1)
{
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
}
// Returns the dot (inner) product of two Vectors.
double Dot(const Vector<4>& v0, const Vector<4>& v1)
{
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2] + v0[3] * v1[3];
}
// Returns the 3-dimensional cross product of 2 Vectors. Note that this is
// defined only for 3-dimensional Vectors.
Vector<3> Cross(const Vector<3>& v0, const Vector<3>& v1)
{
return Vector<3>(v0[1] * v1[2] - v0[2] * v1[1], v0[2] * v1[0] - v0[0] * v1[2],
v0[0] * v1[1] - v0[1] * v1[0]);
}
} // namespace cardboard

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CARDBOARD_SDK_UTIL_VECTORUTILS_H_
#define CARDBOARD_SDK_UTIL_VECTORUTILS_H_
//
// This file contains free functions that operate on Vector instances.
//
#include <cmath>
#include "vector.h"
namespace cardboard {
// Returns the dot (inner) product of two Vectors.
double Dot(const Vector<3>& v0, const Vector<3>& v1);
// Returns the dot (inner) product of two Vectors.
double Dot(const Vector<4>& v0, const Vector<4>& v1);
// Returns the 3-dimensional cross product of 2 Vectors. Note that this is
// defined only for 3-dimensional Vectors.
Vector<3> Cross(const Vector<3>& v0, const Vector<3>& v1);
// Returns the square of the length of a Vector.
template <int Dimension>
double LengthSquared(const Vector<Dimension>& v) {
return Dot(v, v);
}
// Returns the geometric length of a Vector.
template <int Dimension>
double Length(const Vector<Dimension>& v) {
return sqrt(LengthSquared(v));
}
// the Vector untouched and returns false.
template <int Dimension>
bool Normalize(Vector<Dimension>* v) {
const double len = Length(*v);
if(len == 0) {
return false;
} else {
(*v) /= len;
return true;
}
}
// Returns a unit-length version of a Vector. If the given Vector has no
// length, this returns a Zero() Vector.
template <int Dimension>
Vector<Dimension> Normalized(const Vector<Dimension>& v) {
Vector<Dimension> result = v;
if(Normalize(&result))
return result;
else
return Vector<Dimension>::Zero();
}
} // namespace cardboard
#endif // CARDBOARD_SDK_UTIL_VECTORUTILS_H_