You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.7 KiB
196 lines
5.7 KiB
// License: Apache 2.0. See LICENSE file in root directory.
|
|
// Copyright(c) 2021 Intel Corporation. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include <librealsense2/h/rs_types.h> // rs2_quaternion
|
|
#include "float4.h"
|
|
|
|
#include <cmath> // sqrt
|
|
#include <cstring> // memset
|
|
|
|
|
|
namespace rs2 {
|
|
|
|
|
|
struct matrix4
|
|
{
|
|
float mat[4][4];
|
|
|
|
operator float*() const
|
|
{
|
|
return (float*)&mat;
|
|
}
|
|
|
|
static matrix4 identity()
|
|
{
|
|
matrix4 m;
|
|
for (int i = 0; i < 4; i++)
|
|
m.mat[i][i] = 1.f;
|
|
return m;
|
|
}
|
|
|
|
matrix4()
|
|
{
|
|
std::memset(mat, 0, sizeof(mat));
|
|
}
|
|
|
|
matrix4(float vals[4][4])
|
|
{
|
|
std::memcpy(mat,vals,sizeof(mat));
|
|
}
|
|
|
|
// convert glGetFloatv output to matrix4
|
|
//
|
|
// float m[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
|
// into
|
|
// rs2::matrix4 m = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, {12, 13, 14, 15} };
|
|
// 0 1 2 3
|
|
// 4 5 6 7
|
|
// 8 9 10 11
|
|
// 12 13 14 15
|
|
matrix4(float vals[16])
|
|
{
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
mat[i][j] = vals[i * 4 + j];
|
|
}
|
|
}
|
|
}
|
|
|
|
float& operator()(int i, int j) { return mat[i][j]; }
|
|
const float& operator()(int i, int j) const { return mat[i][j]; }
|
|
|
|
//init rotation matrix from quaternion
|
|
matrix4(const rs2_quaternion& q)
|
|
{
|
|
mat[0][0] = 1 - 2*q.y*q.y - 2*q.z*q.z; mat[0][1] = 2*q.x*q.y - 2*q.z*q.w; mat[0][2] = 2*q.x*q.z + 2*q.y*q.w; mat[0][3] = 0.0f;
|
|
mat[1][0] = 2*q.x*q.y + 2*q.z*q.w; mat[1][1] = 1 - 2*q.x*q.x - 2*q.z*q.z; mat[1][2] = 2*q.y*q.z - 2*q.x*q.w; mat[1][3] = 0.0f;
|
|
mat[2][0] = 2*q.x*q.z - 2*q.y*q.w; mat[2][1] = 2*q.y*q.z + 2*q.x*q.w; mat[2][2] = 1 - 2*q.x*q.x - 2*q.y*q.y; mat[2][3] = 0.0f;
|
|
mat[3][0] = 0.0f; mat[3][1] = 0.0f; mat[3][2] = 0.0f; mat[3][3] = 1.0f;
|
|
}
|
|
|
|
//init translation matrix from vector
|
|
matrix4(const rs2_vector& t)
|
|
{
|
|
mat[0][0] = 1.0f; mat[0][1] = 0.0f; mat[0][2] = 0.0f; mat[0][3] = t.x;
|
|
mat[1][0] = 0.0f; mat[1][1] = 1.0f; mat[1][2] = 0.0f; mat[1][3] = t.y;
|
|
mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; mat[2][3] = t.z;
|
|
mat[3][0] = 0.0f; mat[3][1] = 0.0f; mat[3][2] = 0.0f; mat[3][3] = 1.0f;
|
|
}
|
|
|
|
rs2_quaternion normalize(rs2_quaternion a)
|
|
{
|
|
float norm = sqrtf(a.x*a.x + a.y*a.y + a.z*a.z + a.w*a.w);
|
|
rs2_quaternion res = a;
|
|
res.x /= norm;
|
|
res.y /= norm;
|
|
res.z /= norm;
|
|
res.w /= norm;
|
|
return res;
|
|
}
|
|
|
|
rs2_quaternion to_quaternion()
|
|
{
|
|
float tr[4];
|
|
rs2_quaternion res;
|
|
tr[0] = (mat[0][0] + mat[1][1] + mat[2][2]);
|
|
tr[1] = (mat[0][0] - mat[1][1] - mat[2][2]);
|
|
tr[2] = (-mat[0][0] + mat[1][1] - mat[2][2]);
|
|
tr[3] = (-mat[0][0] - mat[1][1] + mat[2][2]);
|
|
if (tr[0] >= tr[1] && tr[0] >= tr[2] && tr[0] >= tr[3])
|
|
{
|
|
float s = 2 * sqrt(tr[0] + 1);
|
|
res.w = s / 4;
|
|
res.x = (mat[2][1] - mat[1][2]) / s;
|
|
res.y = (mat[0][2] - mat[2][0]) / s;
|
|
res.z = (mat[1][0] - mat[0][1]) / s;
|
|
}
|
|
else if (tr[1] >= tr[2] && tr[1] >= tr[3]) {
|
|
float s = 2 * sqrt(tr[1] + 1);
|
|
res.w = (mat[2][1] - mat[1][2]) / s;
|
|
res.x = s / 4;
|
|
res.y = (mat[1][0] + mat[0][1]) / s;
|
|
res.z = (mat[2][0] + mat[0][2]) / s;
|
|
}
|
|
else if (tr[2] >= tr[3]) {
|
|
float s = 2 * sqrt(tr[2] + 1);
|
|
res.w = (mat[0][2] - mat[2][0]) / s;
|
|
res.x = (mat[1][0] + mat[0][1]) / s;
|
|
res.y = s / 4;
|
|
res.z = (mat[1][2] + mat[2][1]) / s;
|
|
}
|
|
else {
|
|
float s = 2 * sqrt(tr[3] + 1);
|
|
res.w = (mat[1][0] - mat[0][1]) / s;
|
|
res.x = (mat[0][2] + mat[2][0]) / s;
|
|
res.y = (mat[1][2] + mat[2][1]) / s;
|
|
res.z = s / 4;
|
|
}
|
|
return normalize(res);
|
|
}
|
|
|
|
void to_column_major(float column_major[16])
|
|
{
|
|
column_major[0] = mat[0][0];
|
|
column_major[1] = mat[1][0];
|
|
column_major[2] = mat[2][0];
|
|
column_major[3] = mat[3][0];
|
|
column_major[4] = mat[0][1];
|
|
column_major[5] = mat[1][1];
|
|
column_major[6] = mat[2][1];
|
|
column_major[7] = mat[3][1];
|
|
column_major[8] = mat[0][2];
|
|
column_major[9] = mat[1][2];
|
|
column_major[10] = mat[2][2];
|
|
column_major[11] = mat[3][2];
|
|
column_major[12] = mat[0][3];
|
|
column_major[13] = mat[1][3];
|
|
column_major[14] = mat[2][3];
|
|
column_major[15] = mat[3][3];
|
|
}
|
|
};
|
|
|
|
inline matrix4 operator*(const matrix4& a, const matrix4& b)
|
|
{
|
|
matrix4 res;
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
float sum = 0.0f;
|
|
for (int k = 0; k < 4; k++)
|
|
{
|
|
sum += a.mat[i][k] * b.mat[k][j];
|
|
}
|
|
res.mat[i][j] = sum;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
inline float4 operator*(const matrix4& a, const float4& b)
|
|
{
|
|
float4 res;
|
|
int i = 0;
|
|
res.x = a(i, 0) * b.x + a(i, 1) * b.y + a(i, 2) * b.z + a(i, 3) * b.w; i++;
|
|
res.y = a(i, 0) * b.x + a(i, 1) * b.y + a(i, 2) * b.z + a(i, 3) * b.w; i++;
|
|
res.z = a(i, 0) * b.x + a(i, 1) * b.y + a(i, 2) * b.z + a(i, 3) * b.w; i++;
|
|
res.w = a(i, 0) * b.x + a(i, 1) * b.y + a(i, 2) * b.z + a(i, 3) * b.w; i++;
|
|
return res;
|
|
}
|
|
|
|
|
|
inline matrix4 identity_matrix()
|
|
{
|
|
matrix4 data;
|
|
for( int i = 0; i < 4; i++ )
|
|
for( int j = 0; j < 4; j++ )
|
|
data.mat[i][j] = (i == j) ? 1.f : 0.f;
|
|
return data;
|
|
}
|
|
|
|
|
|
} // namespace rs2
|