mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-04 01:46:42 +00:00
GRAPHICS: Overhaul of the matrix classes.
New Matrix<rows, cols> and Transform<T> (with T a matrix) classes to ease the creation of different matrix classes.
This commit is contained in:
parent
25b3704c68
commit
e9267cfec5
@ -847,7 +847,7 @@ void SoundComponent::setKey(int val) {
|
||||
// then it will just use the existing handle
|
||||
g_imuse->startSfx(_soundName.c_str());
|
||||
if (g_grim->getCurrScene()) {
|
||||
Graphics::Vector3d pos = _cost->getMatrix()._pos;
|
||||
Graphics::Vector3d pos = _cost->getMatrix().getPosition();
|
||||
g_grim->getCurrScene()->setSoundPosition(_soundName.c_str(), pos);
|
||||
}
|
||||
break;
|
||||
@ -1598,7 +1598,7 @@ void Costume::moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float
|
||||
p->setMatrix(_matrix);
|
||||
p->update();
|
||||
|
||||
Graphics::Vector3d v = lookAt - _joint3Node->_matrix._pos;
|
||||
Graphics::Vector3d v = lookAt - _joint3Node->_matrix.getPosition();
|
||||
if (v.isZero()) {
|
||||
return;
|
||||
}
|
||||
@ -1611,7 +1611,7 @@ void Costume::moveHead(bool lookingMode, const Graphics::Vector3d &lookAt, float
|
||||
if (b < 0.0f)
|
||||
yaw = 360.0f - yaw;
|
||||
|
||||
float bodyYaw = _matrix._rot.getYaw();
|
||||
float bodyYaw = _matrix.getYaw();
|
||||
p = _joint1Node->_parent;
|
||||
while (p) {
|
||||
bodyYaw += p->_yaw + p->_animYaw;
|
||||
@ -1709,8 +1709,8 @@ void Costume::setHead(int joint1, int joint2, int joint3, float maxRoll, float m
|
||||
}
|
||||
|
||||
void Costume::setPosRotate(Graphics::Vector3d pos, float pitch, float yaw, float roll) {
|
||||
_matrix._pos = pos;
|
||||
_matrix._rot.buildFromPitchYawRoll(pitch, yaw, roll);
|
||||
_matrix.setPosition(pos);
|
||||
_matrix.buildFromPitchYawRoll(pitch, yaw, roll);
|
||||
}
|
||||
|
||||
Graphics::Matrix4 Costume::getMatrix() const {
|
||||
@ -1743,7 +1743,7 @@ void Costume::saveState(SaveGame *state) const {
|
||||
|
||||
if (c) {
|
||||
state->writeLESint32(c->_visible);
|
||||
state->writeVector3d(c->_matrix._pos);
|
||||
state->writeVector3d(c->_matrix.getPosition());
|
||||
c->saveState(state);
|
||||
}
|
||||
}
|
||||
@ -1782,7 +1782,7 @@ bool Costume::restoreState(SaveGame *state) {
|
||||
|
||||
if (c) {
|
||||
c->_visible = state->readLESint32();
|
||||
c->_matrix._pos = state->readVector3d();
|
||||
c->_matrix.setPosition(state->readVector3d());
|
||||
c->restoreState(state);
|
||||
}
|
||||
}
|
||||
|
@ -668,14 +668,15 @@ void L1_GetActorNodeLocation() {
|
||||
}
|
||||
|
||||
Graphics::Matrix4 matrix;
|
||||
matrix._pos = actor->getPos();
|
||||
matrix._rot.buildFromPitchYawRoll(actor->getPitch(), actor->getYaw(), actor->getRoll());
|
||||
matrix.setPosition(actor->getPos());
|
||||
matrix.buildFromPitchYawRoll(actor->getPitch(), actor->getYaw(), actor->getRoll());
|
||||
root->setMatrix(matrix);
|
||||
root->update();
|
||||
|
||||
lua_pushnumber(node->_pivotMatrix._pos.x());
|
||||
lua_pushnumber(node->_pivotMatrix._pos.y());
|
||||
lua_pushnumber(node->_pivotMatrix._pos.z());
|
||||
Graphics::Vector3d pos(node->_pivotMatrix.getPosition());
|
||||
lua_pushnumber(pos.x());
|
||||
lua_pushnumber(pos.y());
|
||||
lua_pushnumber(pos.z());
|
||||
}
|
||||
|
||||
void L1_SetActorWalkDominate() {
|
||||
|
@ -70,7 +70,7 @@ Model::Model(const Common::String &filename, const char *data, int len, CMap *cm
|
||||
// bone wagon when approaching it from behind in set sg.
|
||||
// Using the node position looks instead more realistic, but, on the
|
||||
// other hand, it may not work right in all cases.
|
||||
Graphics::Vector3d &p = node._matrix._pos;
|
||||
Graphics::Vector3d p = node._matrix.getPosition();
|
||||
float x = p.x();
|
||||
float y = p.y();
|
||||
float z = p.z();
|
||||
@ -664,14 +664,14 @@ void ModelNode::update() {
|
||||
float animYaw = _yaw + _animYaw;
|
||||
float animRoll = _roll + _animRoll;
|
||||
|
||||
_localMatrix._pos.set(animPos.x(), animPos.y(), animPos.z());
|
||||
_localMatrix._rot.buildFromPitchYawRoll(animPitch, animYaw, animRoll);
|
||||
_localMatrix.setPosition(animPos);
|
||||
_localMatrix.buildFromPitchYawRoll(animPitch, animYaw, animRoll);
|
||||
|
||||
_matrix *= _localMatrix;
|
||||
|
||||
_pivotMatrix = _matrix;
|
||||
|
||||
_pivotMatrix.translate(_pivot.x(), _pivot.y(), _pivot.z());
|
||||
_pivotMatrix.translate(_pivot);
|
||||
|
||||
if (_mesh) {
|
||||
_mesh->_matrix = _pivotMatrix;
|
||||
|
193
graphics/matrix.h
Normal file
193
graphics/matrix.h
Normal file
@ -0,0 +1,193 @@
|
||||
/* Residual - A 3D game interpreter
|
||||
*
|
||||
* Residual is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef GRAPHICS_MATRIX_H
|
||||
#define GRAPHICS_MATRIX_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
template<int rows, int cols>
|
||||
class Matrix {
|
||||
public:
|
||||
class Row {
|
||||
public:
|
||||
Row(Matrix<rows, cols> *m, int row);
|
||||
|
||||
Row &operator=(const Row &r);
|
||||
Row &operator<<(float value);
|
||||
|
||||
private:
|
||||
Matrix<rows, cols> *_matrix;
|
||||
int _row;
|
||||
int _col;
|
||||
};
|
||||
|
||||
Matrix();
|
||||
Matrix(float *data);
|
||||
|
||||
void setToIdentity();
|
||||
|
||||
Row getRow(int row);
|
||||
|
||||
float *getData() const;
|
||||
void setData(float *data);
|
||||
float getValue(int row, int col) const;
|
||||
void setValue(int row, int col, float value);
|
||||
|
||||
float &operator()(int row, int col);
|
||||
float operator()(int row, int col) const;
|
||||
|
||||
Matrix<rows, cols> &operator=(const Matrix<rows, cols> &m);
|
||||
Matrix<rows, cols> &operator*=(const Matrix<rows, cols> &m);
|
||||
|
||||
private:
|
||||
float _values[rows][cols];
|
||||
};
|
||||
|
||||
|
||||
template <int m, int n, int p>
|
||||
Matrix<m, n> operator*(const Matrix<m, p> &m1, const Matrix<p, n> &m2);
|
||||
|
||||
|
||||
|
||||
|
||||
template<int rows, int cols>
|
||||
Matrix<rows, cols>::Matrix() {
|
||||
setToIdentity();
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
Matrix<rows, cols>::Matrix(float *data) {
|
||||
setData(data);
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
void Matrix<rows, cols>::setToIdentity() {
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
for (int j = 0; j < cols; ++j) {
|
||||
setValue(i, j, (i == j ? 1.f : 0.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
typename Matrix<rows, cols>::Row Matrix<rows, cols>::getRow(int row) {
|
||||
return Row(this, row);
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
float *Matrix<rows, cols>::getData() const {
|
||||
return _values[0];
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
void Matrix<rows, cols>::setData(float *data) {
|
||||
for (int row = 0; row < rows; ++row) {
|
||||
for (int col = 0; col < cols; ++col) {
|
||||
setValue(row, col, data[row * rows + col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
float Matrix<rows, cols>::getValue(int row, int col) const {
|
||||
return _values[row][col];
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
void Matrix<rows, cols>::setValue(int row, int col, float v) {
|
||||
operator()(row, col) = v;
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
float &Matrix<rows, cols>::operator()(int row, int col) {
|
||||
return _values[row][col];
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
float Matrix<rows, cols>::operator()(int row, int col) const {
|
||||
return getValue(row, col);
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
Matrix<rows, cols> &Matrix<rows, cols>::operator=(const Matrix<rows, cols> &m) {
|
||||
for (int row = 0; row < rows; ++row) {
|
||||
for (int col = 0; col < cols; ++col) {
|
||||
setValue(row, col, m(row, col));
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
Matrix<rows, cols> &Matrix<rows, cols>::operator*=(const Matrix<rows, cols> &m) {
|
||||
*this = *this * m;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
Matrix<rows, cols>::Row::Row(Matrix<rows, cols> *m, int row) :
|
||||
_matrix(m), _row(row), _col(0) {
|
||||
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
typename Matrix<rows, cols>::Row &Matrix<rows, cols>::Row::operator=(const Row &r) {
|
||||
_col = r._col;
|
||||
_row = r._row;
|
||||
_matrix = r._matrix;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<int rows, int cols>
|
||||
typename Matrix<rows, cols>::Row &Matrix<rows, cols>::Row::operator<<(float value) {
|
||||
assert(_col < cols);
|
||||
_matrix->setValue(_row, _col++, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <int m, int n, int p>
|
||||
Matrix<m, n> operator*(const Matrix<m, p> &m1, const Matrix<p, n> &m2) {
|
||||
Matrix<m, n> result;
|
||||
for (int row = 0; row < m; ++row) {
|
||||
for (int col = 0; col < n; ++col) {
|
||||
float sum(0.0f);
|
||||
for (int j = 0; j < p; ++j)
|
||||
sum += m1(row, j) * m2(j, col);
|
||||
result(row, col) = sum;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -26,20 +26,21 @@
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
void Matrix3::setAsIdentity() {
|
||||
_right.set(1.f, 0.f, 0.f);
|
||||
_up.set(0.f, 1.f, 0.f);
|
||||
_at.set(0.f, 0.f, 1.f);
|
||||
Matrix3x3::Matrix3x3() :
|
||||
Matrix(), Rotation3D(this) {
|
||||
|
||||
}
|
||||
|
||||
void Matrix3::buildFromPitchYawRoll(float pitch, float yaw, float roll) {
|
||||
Matrix3 temp;
|
||||
void Matrix3x3::transform(Vector3d *v) const {
|
||||
|
||||
constructAroundYaw(yaw);
|
||||
temp.constructAroundPitch(pitch);
|
||||
(*this) *= temp;
|
||||
temp.constructAroundRoll(roll);
|
||||
(*this) *= temp;
|
||||
Matrix<3, 1> m;
|
||||
m(0, 0) = v->x();
|
||||
m(1, 0) = v->y();
|
||||
m(2, 0) = v->z();
|
||||
|
||||
m = *this * m;
|
||||
|
||||
v->set(m(0, 0), m(1, 0), m(2, 0));
|
||||
}
|
||||
|
||||
#define DEGTORAD(a) (a * LOCAL_PI / 180.0)
|
||||
@ -53,133 +54,4 @@ float DegreeToRadian(float degrees) {
|
||||
return (float)DEGTORAD(degrees);
|
||||
}
|
||||
|
||||
// right
|
||||
void Matrix3::constructAroundPitch(float pitch) {
|
||||
float cosa;
|
||||
float sina;
|
||||
|
||||
cosa = (float)cos(DegreeToRadian(pitch));
|
||||
sina = (float)sin(DegreeToRadian(pitch));
|
||||
|
||||
_right.set(1.f, 0.f, 0.f);
|
||||
_up.set(0.f, cosa, sina);
|
||||
_at.set(0.f, -sina, cosa);
|
||||
}
|
||||
|
||||
// up
|
||||
void Matrix3::constructAroundYaw(float yaw) {
|
||||
float cosa;
|
||||
float sina;
|
||||
|
||||
cosa = (float)cos(DegreeToRadian(yaw));
|
||||
sina = (float)sin(DegreeToRadian(yaw));
|
||||
|
||||
_right.set(cosa, sina, 0.f);
|
||||
_up.set(-sina, cosa, 0.f);
|
||||
_at.set(0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
// at
|
||||
void Matrix3::constructAroundRoll(float roll) {
|
||||
float cosa;
|
||||
float sina;
|
||||
|
||||
cosa = (float)cos(DegreeToRadian(roll));
|
||||
sina = (float)sin(DegreeToRadian(roll));
|
||||
|
||||
_right.set(cosa, 0.f, -sina);
|
||||
_up.set(0.f, 1.f, 0.f);
|
||||
_at.set(sina, 0.f, cosa);
|
||||
}
|
||||
|
||||
/*
|
||||
0 1 2 3
|
||||
4 5 6 7
|
||||
8 9 10 11
|
||||
*/
|
||||
|
||||
// WARNING: Still buggy in some occasions.
|
||||
void Matrix3::getPitchYawRoll(float* pPitch, float* pYaw, float* pRoll) const {
|
||||
float D;
|
||||
float C;
|
||||
float ftrx;
|
||||
float ftry;
|
||||
float angle_x;
|
||||
float angle_y;
|
||||
float angle_z;
|
||||
|
||||
angle_y = D = -asin(_right.z()); /* Calculate Y-axis angle */
|
||||
C = cos(angle_y);
|
||||
angle_y = RadianToDegree(angle_y);
|
||||
|
||||
if (fabs( C ) > 0.005) { /* Gimball lock? */
|
||||
ftrx = _at.z() / C; /* No, so get X-axis angle */
|
||||
ftry = _up.z() / C;
|
||||
|
||||
angle_x = RadianToDegree(atan2(ftry, ftrx));
|
||||
|
||||
ftrx = _right.x() / C; /* Get Z-axis angle */
|
||||
ftry = _right.y() / C;
|
||||
|
||||
angle_z = RadianToDegree(atan2(ftry, ftrx));
|
||||
} else { /* Gimball lock has occurred */
|
||||
angle_x = 0; /* Set X-axis angle to zqero */
|
||||
|
||||
ftrx = _at.x(); /* And calculate Z-axis angle */
|
||||
ftry = _up.x();
|
||||
|
||||
angle_z = RadianToDegree(atan2(ftry, ftrx));
|
||||
}
|
||||
|
||||
/* return only positive angles in [0,360] */
|
||||
if (angle_x < 0) angle_x += 360;
|
||||
if (angle_y < 0) angle_y += 360;
|
||||
if (angle_z < 0) angle_z += 360;
|
||||
|
||||
if (pPitch)
|
||||
*pPitch = angle_x;
|
||||
|
||||
if (pYaw)
|
||||
*pYaw = angle_z;
|
||||
|
||||
if (pRoll)
|
||||
*pRoll = angle_y;
|
||||
}
|
||||
|
||||
float Matrix3::getPitch() const {
|
||||
float pitch;
|
||||
|
||||
getPitchYawRoll(&pitch, 0, 0);
|
||||
|
||||
return pitch;
|
||||
}
|
||||
|
||||
float Matrix3::getYaw() const {
|
||||
float yaw;
|
||||
|
||||
getPitchYawRoll(0, &yaw, 0);
|
||||
|
||||
return yaw;
|
||||
}
|
||||
|
||||
float Matrix3::getRoll() const {
|
||||
float roll;
|
||||
|
||||
getPitchYawRoll(0, 0, &roll);
|
||||
|
||||
return roll;
|
||||
}
|
||||
|
||||
void Matrix3::transform(Vector3d* v) const {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
|
||||
x = v->dotProduct(_right.x(), _up.x(), _at.x());
|
||||
y = v->dotProduct(_right.y(), _up.y(), _at.y());
|
||||
z = v->dotProduct(_right.z(), _up.z(), _at.z());
|
||||
|
||||
v->set(x, y, z);
|
||||
}
|
||||
|
||||
} // end of namespace Graphics
|
||||
|
@ -25,19 +25,18 @@
|
||||
#ifndef GRAPHICS_MATRIX3_H
|
||||
#define GRAPHICS_MATRIX3_H
|
||||
|
||||
#include "graphics/matrix.h"
|
||||
#include "graphics/transform.h"
|
||||
#include "graphics/vector3d.h"
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
// matrix 3 is a rotation matrix
|
||||
class Matrix3 {
|
||||
template<class T>
|
||||
class Rotation3D : public Transform<T> {
|
||||
public:
|
||||
Vector3d _right;
|
||||
Vector3d _up;
|
||||
Vector3d _at;
|
||||
Rotation3D(T *matrix);
|
||||
|
||||
void buildFromPitchYawRoll(float pitch, float yaw, float roll);
|
||||
void setAsIdentity();
|
||||
|
||||
void constructAroundPitch(float pitch);
|
||||
void constructAroundYaw(float yaw);
|
||||
@ -49,39 +48,125 @@ public:
|
||||
float getYaw() const;
|
||||
float getRoll() const;
|
||||
|
||||
void transform(Vector3d* v) const;
|
||||
|
||||
// operators
|
||||
Matrix3& operator *=(const Matrix3& s) {
|
||||
float rx = s._right.dotProduct(_right.x(), _up.x(), _at.x());
|
||||
float ry = s._right.dotProduct(_right.y(), _up.y(), _at.y());
|
||||
float rz = s._right.dotProduct(_right.z(), _up.z(), _at.z());
|
||||
|
||||
float ux = s._up.dotProduct(_right.x(), _up.x(), _at.x());
|
||||
float uy = s._up.dotProduct(_right.y(), _up.y(), _at.y());
|
||||
float uz = s._up.dotProduct(_right.z(), _up.z(), _at.z());
|
||||
|
||||
float ax = s._at.dotProduct(_right.x(), _up.x(), _at.x());
|
||||
float ay = s._at.dotProduct(_right.y(), _up.y(), _at.y());
|
||||
float az = s._at.dotProduct(_right.z(), _up.z(), _at.z());
|
||||
|
||||
_right.set(rx,ry,rz);
|
||||
_up.set(ux,uy,uz);
|
||||
_at.set(ax,ay,az);
|
||||
|
||||
return *this;
|
||||
}
|
||||
Matrix3& operator =(const Matrix3& s) {
|
||||
_right = s._right;
|
||||
_up = s._up;
|
||||
_at = s._at;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class Matrix3x3 : public Matrix<3, 3>, public Rotation3D<Matrix3x3> {
|
||||
public:
|
||||
Matrix3x3();
|
||||
|
||||
void transform(Vector3d* v) const;
|
||||
};
|
||||
|
||||
typedef Matrix3x3 Matrix3;
|
||||
|
||||
float RadianToDegree(float rad);
|
||||
float DegreeToRadian(float degrees);
|
||||
|
||||
|
||||
template<class T>
|
||||
Rotation3D<T>::Rotation3D(T *matrix) :
|
||||
Transform<T>(matrix) {
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Rotation3D<T>::buildFromPitchYawRoll(float pitch, float yaw, float roll) {
|
||||
T temp;
|
||||
|
||||
constructAroundYaw(yaw);
|
||||
temp.constructAroundPitch(pitch);
|
||||
(*this->getMatrix()) *= temp;
|
||||
temp.constructAroundRoll(roll);
|
||||
(*this->getMatrix()) *= temp;
|
||||
}
|
||||
|
||||
// at, around x-axis
|
||||
template<class T>
|
||||
void Rotation3D<T>::constructAroundRoll(float roll) {
|
||||
float cosa = (float)cos(DegreeToRadian(roll));
|
||||
float sina = (float)sin(DegreeToRadian(roll));
|
||||
|
||||
this->getMatrix()->getRow(0) << 1.f << 0.f << 0.f;
|
||||
this->getMatrix()->getRow(1) << 0.f << cosa << -sina;
|
||||
this->getMatrix()->getRow(2) << 0.f << sina << cosa;
|
||||
}
|
||||
|
||||
// right
|
||||
template<class T>
|
||||
void Rotation3D<T>::constructAroundPitch(float pitch) {
|
||||
float cosa = (float)cos(DegreeToRadian(pitch));
|
||||
float sina = (float)sin(DegreeToRadian(pitch));
|
||||
|
||||
this->getMatrix()->getRow(0) << cosa << 0.f << sina;
|
||||
this->getMatrix()->getRow(1) << 0.f << 1.f << 0.f;
|
||||
this->getMatrix()->getRow(2) << -sina << 0.f << cosa;
|
||||
}
|
||||
|
||||
// up
|
||||
template<class T>
|
||||
void Rotation3D<T>::constructAroundYaw(float yaw) {
|
||||
float cosa = (float)cos(DegreeToRadian(yaw));
|
||||
float sina = (float)sin(DegreeToRadian(yaw));
|
||||
|
||||
this->getMatrix()->getRow(0) << cosa << -sina << 0.f;
|
||||
this->getMatrix()->getRow(1) << sina << cosa << 0.f;
|
||||
this->getMatrix()->getRow(2) << 0.f << 0.f << 1.f;
|
||||
}
|
||||
|
||||
/*
|
||||
0 * 1 2 3
|
||||
4 5 6 7
|
||||
8 9 10 11
|
||||
*/
|
||||
template<class T>
|
||||
void Rotation3D<T>::getPitchYawRoll(float *pPitch, float *pYaw, float *pRoll) const {
|
||||
// based on http://planning.cs.uiuc.edu/node103.html
|
||||
if (pYaw) {
|
||||
*pYaw = RadianToDegree(atan2f(this->getMatrix()->getValue(1, 0),
|
||||
this->getMatrix()->getValue(0, 0)));
|
||||
}
|
||||
|
||||
if (pPitch) {
|
||||
float a = this->getMatrix()->getValue(2, 1);
|
||||
float b = this->getMatrix()->getValue(2, 2);
|
||||
float mag = sqrt(a * a + b * b);
|
||||
*pPitch = RadianToDegree(atan2f(-this->getMatrix()->getValue(2, 0), mag));
|
||||
}
|
||||
|
||||
if (pRoll) {
|
||||
*pRoll = RadianToDegree(atan2f(this->getMatrix()->getValue(2, 1),
|
||||
this->getMatrix()->getValue(2, 2)));
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
float Rotation3D<T>::getPitch() const {
|
||||
float pitch;
|
||||
|
||||
getPitchYawRoll(&pitch, 0, 0);
|
||||
|
||||
return pitch;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
float Rotation3D<T>::getYaw() const {
|
||||
float yaw;
|
||||
|
||||
getPitchYawRoll(0, &yaw, 0);
|
||||
|
||||
return yaw;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
float Rotation3D<T>::getRoll() const {
|
||||
float roll;
|
||||
|
||||
getPitchYawRoll(0, 0, &roll);
|
||||
|
||||
return roll;
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace Graphics
|
||||
|
||||
#endif
|
||||
|
@ -26,17 +26,41 @@
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
Matrix4::Matrix4() {
|
||||
_pos.set(0.f, 0.f, 0.f);
|
||||
_rot.setAsIdentity();
|
||||
Matrix4::Matrix4() :
|
||||
Matrix(), Rotation3D(this) {
|
||||
|
||||
}
|
||||
|
||||
void Matrix4::translate(float x, float y, float z) {
|
||||
Vector3d v;
|
||||
void Matrix4::transform(Vector3d *v, bool trans) const {
|
||||
Matrix<4, 1> m;
|
||||
m(0, 0) = v->x();
|
||||
m(1, 0) = v->y();
|
||||
m(2, 0) = v->z();
|
||||
m(3, 0) = (trans ? 1.f : 0.f);
|
||||
|
||||
v.set(x, y, z);
|
||||
_rot.transform(&v);
|
||||
_pos += v;
|
||||
m = *this * m;
|
||||
|
||||
v->set(m(0, 0), m(1, 0), m(2, 0));
|
||||
}
|
||||
|
||||
Vector3d Matrix4::getPosition() const {
|
||||
return Vector3d(getValue(3, 0), getValue(3, 1), getValue(3, 2));
|
||||
}
|
||||
|
||||
void Matrix4::setPosition(const Vector3d &v) {
|
||||
setValue(3, 0, v.x());
|
||||
setValue(3, 1, v.y());
|
||||
setValue(3, 2, v.z());
|
||||
}
|
||||
|
||||
void Matrix4::translate(const Vector3d &vec) {
|
||||
Vector3d v(vec);
|
||||
transform(&v, false);
|
||||
|
||||
operator()(3, 0) += v.x();
|
||||
operator()(3, 1) += v.y();
|
||||
operator()(3, 2) += v.z();
|
||||
}
|
||||
|
||||
} // end of namespace Graphics
|
||||
|
||||
|
@ -30,34 +30,17 @@
|
||||
namespace Graphics {
|
||||
|
||||
// matrix 4 is a rotation matrix + position
|
||||
class Matrix4 {
|
||||
class Matrix4 : public Matrix<4, 4>, public Rotation3D<Matrix4> {
|
||||
public:
|
||||
Matrix3 _rot;
|
||||
Vector3d _pos;
|
||||
|
||||
Matrix4();
|
||||
|
||||
Matrix4& operator =(const Matrix4& s) {
|
||||
_pos = s._pos;
|
||||
_rot = s._rot;
|
||||
void transform(Vector3d *v, bool translate) const;
|
||||
|
||||
return *this;
|
||||
}
|
||||
Vector3d getPosition() const;
|
||||
void setPosition(const Vector3d &v);
|
||||
|
||||
Matrix4& operator *=(const Matrix4& s) {
|
||||
Vector3d v;
|
||||
void translate(const Vector3d &v);
|
||||
|
||||
v = s._pos;
|
||||
_rot.transform(&v);
|
||||
_pos += v;
|
||||
_rot *= s._rot;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void translate(float x, float y, float z);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // end of namespace Graphics
|
||||
|
56
graphics/transform.h
Normal file
56
graphics/transform.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* Residual - A 3D game interpreter
|
||||
*
|
||||
* Residual is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef GRAPHICS_TRANSFORM_H
|
||||
#define GRAPHICS_TRANSFORM_H
|
||||
|
||||
namespace Graphics {
|
||||
|
||||
template<class T>
|
||||
class Transform {
|
||||
public:
|
||||
Transform(T *matrix);
|
||||
|
||||
protected:
|
||||
inline T *getMatrix() const;
|
||||
|
||||
private:
|
||||
T *_matrix;
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
Transform<T>::Transform(T *matrix) :
|
||||
_matrix(matrix) {
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T *Transform<T>::getMatrix() const {
|
||||
return _matrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user