diff options
author | Paul Gilbert | 2017-09-02 11:12:55 -0400 |
---|---|---|
committer | GitHub | 2017-09-02 11:12:55 -0400 |
commit | 2518de30a4a0d9c942791ee78f29fa42ab268375 (patch) | |
tree | bd060dfc222c18e1df25937ea4506492bdb25de6 /engines | |
parent | a46d126e7380718cf5effd9eb9cadd5584641a45 (diff) | |
parent | 4e586ba43d9eeff96555be38c89f60209e7ddb0a (diff) | |
download | scummvm-rg350-2518de30a4a0d9c942791ee78f29fa42ab268375.tar.gz scummvm-rg350-2518de30a4a0d9c942791ee78f29fa42ab268375.tar.bz2 scummvm-rg350-2518de30a4a0d9c942791ee78f29fa42ab268375.zip |
Merge pull request #1005 from dafioram/DVectorDAffineDestruction
TITANIC: DVectorDAffineDestruction
Diffstat (limited to 'engines')
19 files changed, 365 insertions, 762 deletions
diff --git a/engines/titanic/module.mk b/engines/titanic/module.mk index 60997f4e68..617e262396 100644 --- a/engines/titanic/module.mk +++ b/engines/titanic/module.mk @@ -434,8 +434,6 @@ MODULE_OBJS := \ star_control/base_stars.o \ star_control/camera_auto_mover.o \ star_control/camera_mover.o \ - star_control/daffine.o \ - star_control/dvector.o \ star_control/fmatrix.o \ star_control/fpoint.o \ star_control/fpose.o \ diff --git a/engines/titanic/star_control/daffine.cpp b/engines/titanic/star_control/daffine.cpp deleted file mode 100644 index 616042d715..0000000000 --- a/engines/titanic/star_control/daffine.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM 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 program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "titanic/star_control/daffine.h" -#include "titanic/star_control/fmatrix.h" // includes FVector -#include "titanic/star_control/matrix_inv.h" -#include "titanic/star_control/matrix_transform.h" - -namespace Titanic { - -DAffine::DAffine() : - _col1(0.0, 0.0, 0.0), _col2(0.0, 0.0, 0.0), _col3(0.0, 0.0, 0.0), _col4(0.0, 0.0, 0.0) { -} - -DAffine::DAffine(int mode, const DVector &src) { - switch (mode) { - case 0: - _col1._x = 1.0; - _col2._y = 1.0; - _col3._z = 1.0; - _col4 = src; - break; - - case 1: - _col1._x = src._x; - _col2._y = src._y; - _col3._z = src._z; - break; - - default: - _col1._x = 1.0; - _col2._y = 1.0; - _col3._z = 1.0; - break; - } -} - -DAffine::DAffine(Axis axis, double angleDeg) { - setRotationMatrix(axis, angleDeg); -} - -DAffine::DAffine(const FMatrix &src) { - _col1 = src._row1; - _col2 = src._row2; - _col3 = src._row3; -} - -void DAffine::clear() { - _col1._x = 0.0; - _col1._y = 0.0; - _col1._z = 0.0; - _col2._x = 0.0; - _col2._y = 0.0; - _col2._z = 0.0; - _col3._x = 0.0; - _col3._y = 0.0; - _col3._z = 0.0; - _col4._x = 0.0; - _col4._y = 0.0; - _col4._z = 0.0; -} - -// Source: https://en.wikipedia.org/wiki/Rotation_matrix -void DAffine::setRotationMatrix(Axis axis, double angleDeg) { - clear(); - - double sinVal = sin(angleDeg * Deg2Rad); - double cosVal = cos(angleDeg * Deg2Rad); - - switch (axis) { - case X_AXIS: - _col1._x = 1.0; - _col2._y = cosVal; - _col2._z = sinVal; - _col3._y = -sinVal; - _col3._z = cosVal; - break; - - case Y_AXIS: - _col1._x = cosVal; - _col1._z = -sinVal; - _col2._y = 1.0; - _col3._x = sinVal; - _col3._z = cosVal; - break; - - case Z_AXIS: - _col1._x = cosVal; - _col1._y = sinVal; - _col2._x = -sinVal; - _col2._y = cosVal; - _col3._z = 1.0; - break; - - default: - break; - } -} - -DAffine DAffine::inverseTransform() const { - DAffine m; - - // Create a 4x4 matrix so that the column 4 - // for the inverse can be obtained, - // it is not simply -inv(R)*_col4 - // Load input matrix - double A[16]={_col1._x,_col1._y,_col1._z, 0.0, - _col2._x,_col2._y,_col2._z, 0.0, - _col3._x,_col3._y,_col3._z, 0.0, - _col4._x,_col4._y,_col4._z, 1.0}; - // Inverse matrix - double B[16]={}; - - // B contains inverse of A - matrix4Inverse(A,B); - - // Inverse of rotation matrix is the transpose - // While B contains the inverse of the rotation - // this method is more numerically accurate - m._col1._x = _col1._x; - m._col2._x = _col1._y; - m._col3._x = _col1._z; - m._col1._y = _col2._x; - m._col2._y = _col2._y; - m._col3._y = _col2._z; - m._col1._z = _col3._x; - m._col2._z = _col3._y; - m._col3._z = _col3._z; - - m._col4._x = B[12]; - m._col4._y = B[13]; - m._col4._z = B[14]; - - return m; -} - -//TODO: Check math and provide source -void DAffine::loadTransform(const CMatrixTransform &src) { - double total = src.fn1(); - double factor = (total <= 0.0) ? 0.0 : 2.0 / total; - DVector temp1V = src._vector * factor; - DVector temp2V = temp1V * src._vector; - - double val1 = temp1V._y * src._vector._x; - double val2 = temp1V._z * src._vector._x; - double val3 = temp1V._z * src._vector._y; - double val4 = temp1V._x * src._field0; - double val5 = temp1V._y * src._field0; - double val6 = temp1V._z * src._field0; - - _col1._x = 1.0 - (temp2V._z + temp2V._y); - _col1._y = val1 + val6; - _col1._z = val2 - val5; - _col2._x = val1 - val6; - _col2._y = 1.0 - (temp2V._z + temp2V._x); - _col2._z = val3 + val4; - _col3._x = val2 + val5; - _col3._y = val3 - val4; - _col3._z = 1.0 - (temp2V._y + temp2V._x); - _col4._x = 0; - _col4._y = 0; - _col4._z = 0; -} - -//TODO: Check math and provide source -DAffine DAffine::compose(const DAffine &m) { - DAffine dm; - dm._col1._x = m._col3._x * _col1._z + m._col2._x * _col1._y - + m._col1._x * _col1._x; - dm._col1._y = _col1._x * m._col1._y + m._col3._y * _col1._z - + m._col2._y * _col1._y; - dm._col1._z = _col1._x * m._col1._z + m._col3._z * _col1._z - + m._col2._z * _col1._y; - dm._col2._x = m._col1._x * _col2._x + _col2._y * m._col2._x - + _col2._z * m._col3._x; - dm._col2._y = _col2._y * m._col2._y + _col2._z * m._col3._y - + m._col1._y * _col2._x; - dm._col2._z = m._col1._z * _col2._x + _col2._y * m._col2._z - + _col2._z * m._col3._z; - dm._col3._x = m._col1._x * _col3._x + _col3._y * m._col2._x - + _col3._z * m._col3._x; - dm._col3._y = _col3._y * m._col2._y + _col3._z * m._col3._y - + m._col1._y * _col3._x; - dm._col3._z = m._col2._z * _col3._y + m._col3._z * _col3._z - + m._col1._z * _col3._x; - dm._col4._x = m._col1._x * _col4._x + _col4._y * m._col2._x - + _col4._z * m._col3._x + m._col4._x; - dm._col4._y = _col4._z * m._col3._y + _col4._y * m._col2._y - + _col4._x * m._col1._y + m._col4._y; - dm._col4._z = _col4._y * m._col2._z + _col4._x * m._col1._z - + _col4._z * m._col3._z + m._col4._z; - - return dm; -} - -} // End of namespace Titanic diff --git a/engines/titanic/star_control/daffine.h b/engines/titanic/star_control/daffine.h deleted file mode 100644 index 041d376933..0000000000 --- a/engines/titanic/star_control/daffine.h +++ /dev/null @@ -1,87 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM 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 program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef TITANIC_DAFFINE_H -#define TITANIC_DAFFINE_H - -#include "titanic/star_control/dvector.h" -#include "titanic/star_control/fvector.h" // definition of Axis enum - -namespace Titanic { - -class FMatrix; -class CMatrixTransform; - -/** - * Affine transformation. - * - * Handles transformation functions between affine spaces, - * which preserves points, straight lines and planes - */ -class DAffine { -private: - static DAffine *_static; -public: - DVector _col1; - DVector _col2; - DVector _col3; - DVector _col4; -public: - DAffine(); - // TODO: consider making mode an enum since that is more helpful when it is used in code - DAffine(int mode, const DVector &src); - DAffine(Axis axis, double angleDeg); - DAffine(const FMatrix &src); - - /** - * Sets all elements to zero - */ - void clear(); - - /** - * Sets up an affine matrix for rotating on a given axis by an amount in degrees - */ - void setRotationMatrix(Axis axis, double angleDeg); - - /** - * Return the Inverse of this Daffine - */ - DAffine inverseTransform() const; - - /** - * Change this Daffine to have its first three columns be some mapping from src matrix - * and the 4rth column to be (three) zeros. The mapping is not as simple as replacing - * matching row/colmn indices - */ - void loadTransform(const CMatrixTransform &src); - - /** - * Do the affine product between this Daffine on the right - * and the m Daffine matrix on the left. This product is NOT the same - * as multiplying two matrices of dimensions 3x4. - */ - DAffine compose(const DAffine &m); -}; - -} // End of namespace Titanic - -#endif /* TITANIC_DAFFINE_H */ diff --git a/engines/titanic/star_control/dvector.cpp b/engines/titanic/star_control/dvector.cpp deleted file mode 100644 index 73ffd5be54..0000000000 --- a/engines/titanic/star_control/dvector.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM 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 program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "titanic/star_control/dvector.h" -#include "titanic/star_control/daffine.h" - -namespace Titanic { - -bool DVector::normalize(double & hyp) { - hyp = sqrt(_x * _x + _y * _y + _z * _z); - if (hyp==0) { - return false; - } - - _x *= 1.0 / hyp; - _y *= 1.0 / hyp; - _z *= 1.0 / hyp; - return true; -} - -double DVector::getDistance(const DVector &src) { - return sqrt((src._x - _x) * (src._x - _x) + (src._y - _y) * (src._y - _y) + (src._z - _z) * (src._z - _z)); -} - -DVector DVector::dAffMatrixProdVec(const DAffine &m) { - DVector dest; - dest._x = m._col1._x * _x - + m._col2._x * _y + m._col3._x * _z - + m._col4._x; - - dest._y = m._col1._y * _x - + m._col2._y * _y + m._col3._y * _z - + m._col4._y; - - dest._z = m._col1._z * _x - + m._col2._z * _y + m._col3._z * _z - + m._col4._z; - - return dest; -} - -void DVector::rotVectAxisY(double angleDeg) { - double sinVal = sin(angleDeg * Deg2Rad); - double cosVal = cos(angleDeg * Deg2Rad); - double x = cosVal * _x - sinVal * _z; - double z = cosVal * _z + sinVal * _x; - - _x = x; - _z = z; -} - -DVector DVector::getAnglesAsVect() const { - DVector vector = *this; - DVector dest; - - if (!vector.normalize(dest._x)) { - // Makes this vector have magnitude=1, put the scale amount in dest._x, - // but if it is unsuccessful, crash - assert(dest._x); - } - - dest._y = acos(vector._y); // radian distance/angle that this vector's y component is from the +y axis, - // result is restricted to [0,pi] - dest._z = atan2(vector._x,vector._z); // result is restricted to [-pi,pi] - - return dest; -} - -DAffine DVector::getFrameTransform(const DVector &v) { - DAffine matrix1, matrix2, matrix3, matrix4; - - DVector vector1 = getAnglesAsVect(); - matrix1.setRotationMatrix(X_AXIS, vector1._y * Rad2Deg); - matrix2.setRotationMatrix(Y_AXIS, vector1._z * Rad2Deg); - matrix3 = matrix1.compose(matrix2); - matrix4 = matrix3.inverseTransform(); - - vector1 = v.getAnglesAsVect(); - matrix1.setRotationMatrix(X_AXIS, vector1._y * Rad2Deg); - matrix2.setRotationMatrix(Y_AXIS, vector1._z * Rad2Deg); - matrix3 = matrix1.compose(matrix2); - - return matrix4.compose(matrix3); -} - -DAffine DVector::formRotXY() const { - DVector v1 = getAnglesAsVect(); - DAffine m1, m2; - m1.setRotationMatrix(X_AXIS, v1._y * Rad2Deg); - m2.setRotationMatrix(Y_AXIS, v1._z * Rad2Deg); - return m1.compose(m2); -} - -} // End of namespace Titanic diff --git a/engines/titanic/star_control/dvector.h b/engines/titanic/star_control/dvector.h deleted file mode 100644 index a1c67d7382..0000000000 --- a/engines/titanic/star_control/dvector.h +++ /dev/null @@ -1,136 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM 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 program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef TITANIC_DVECTOR_H -#define TITANIC_DVECTOR_H - -#include "titanic/star_control/fvector.h" - -namespace Titanic { - -class DAffine; - -/** - * Double based vector class. - * @remarks TODO: See if it can be merged with FVector - */ -class DVector { -public: - double _x, _y, _z; -public: - DVector() : _x(0), _y(0), _z(0) {} - DVector(double x, double y, double z) : _x(x), _y(y), _z(z) {} - DVector(const FVector &v) : _x(v._x), _y(v._y), _z(v._z) {} - - /** - * Attempts to normalizes the vector so the length from origin equals 1.0 - * Return value is whether or not it was successful in normalizing - * First argument is scale value that normalizes the vector - * TODO: split this function into 2. One that calculates the normalization - * and another that does the normalization. The 2nd would assert if a - * normalization of one was requested. This is cleaner than the current - * implementation. - */ - bool normalize(double &); - - /** - * Returns the distance between this vector and the passed one - */ - double getDistance(const DVector &src); - - /** - * Returns the matrix product with this vector and - * also does a z translations. Doesn't change this vector - */ - DVector dAffMatrixProdVec(const DAffine &m); - - /** - * Rotate this vector about the Y axis - */ - void rotVectAxisY(double angleDeg); - - /** - * Returns a vector, v, that represents a magnitude, and two angles in radians - * 1. Scale this vector to be unit magnitude and store scale in x component of v - * 2. X rotation angle from +y axis of this vector is put in y component of v - * 3. z component output of v is the 4-quadrant angle that z makes with x (Y axis rotation) - */ - DVector getAnglesAsVect() const; - - /** - * Returns a matrix that contains the frame rotation based on this vector and - * a vector rotation based on input vector v - */ - DAffine getFrameTransform(const DVector &v); - - /** - * Constructs an affine matrix that does a x then a y axis frame rotation - * based on the orientation of this vector - */ - DAffine formRotXY() const; - - /** - * Returns true if the passed vector equals this one - */ - bool operator==(const DVector &src) const { - return _x == src._x && _y == src._y && _z == src._z; - } - - /** - * Returns true if the passed vector does not equal this one - */ - bool operator!=(const DVector &src) const { - return _x != src._x || _y != src._y || _z != src._z; - } - - DVector operator+(const DVector &delta) const { - return DVector(_x + delta._x, _y + delta._y, _z + delta._z); - } - - DVector operator-(const DVector &delta) const { - return DVector(_x - delta._x, _y - delta._y, _z - delta._z); - } - - void operator+=(const DVector &delta) { - _x += delta._x; - _y += delta._y; - _z += delta._z; - } - - void operator-=(const DVector &delta) { - _x -= delta._x; - _y -= delta._y; - _z -= delta._z; - } - - const DVector operator*(double right) const { - return DVector(_x * right, _y * right, _z * right); - } - - const DVector operator*(const DVector &right) const { - return DVector(_x * right._x, _y * right._y, _z * right._z); - } -}; - -} // End of namespace Titanic - -#endif /* TITANIC_DVECTOR_H */ diff --git a/engines/titanic/star_control/fmatrix.cpp b/engines/titanic/star_control/fmatrix.cpp index bb002fa4b3..4a2183c5eb 100644 --- a/engines/titanic/star_control/fmatrix.cpp +++ b/engines/titanic/star_control/fmatrix.cpp @@ -21,7 +21,6 @@ */ #include "titanic/star_control/fmatrix.h" -#include "titanic/star_control/daffine.h" #include "titanic/support/simple_file.h" namespace Titanic { @@ -52,22 +51,12 @@ FMatrix::FMatrix(const FVector &row1, const FVector &row2, const FVector &row3) _row3 = row3; } -FMatrix::FMatrix(const DAffine &src) { - copyFrom(src); -} - FMatrix::FMatrix(const FMatrix &src) { _row1 = src._row1; _row2 = src._row2; _row3 = src._row3; } -void FMatrix::copyFrom(const DAffine &src) { - _row1 = src._col1; - _row2 = src._col2; - _row3 = src._col3; -} - void FMatrix::load(SimpleFile *file, int param) { _row1._x = file->readFloat(); _row1._y = file->readFloat(); @@ -116,12 +105,6 @@ void FMatrix::set(const FVector &row1, const FVector &row2, const FVector &row3) _row3 = row3; } -void FMatrix::set(const DVector &row1, const DVector &row2, const DVector &row3) { - _row1 = row1; - _row2 = row2; - _row3 = row3; -} - void FMatrix::set(const FVector &v) { _row3 = v; _row2 = _row3.swapComponents(); diff --git a/engines/titanic/star_control/fmatrix.h b/engines/titanic/star_control/fmatrix.h index 6d118a73a6..c5bf3ed9e3 100644 --- a/engines/titanic/star_control/fmatrix.h +++ b/engines/titanic/star_control/fmatrix.h @@ -27,20 +27,13 @@ namespace Titanic { -class DAffine; -class DVector; class SimpleFile; /** * Floating point matrix class. - * @remarks TODO: See if it can be merged with DAffine + */ class FMatrix { -private: - /** - * Copys data from a given source - */ - void copyFrom(const DAffine &src); public: FVector _row1; FVector _row2; @@ -48,7 +41,6 @@ public: public: FMatrix(); FMatrix(const FVector &, const FVector &, const FVector &); - FMatrix(const DAffine &src); FMatrix(const FMatrix &src); /** @@ -82,11 +74,6 @@ public: void set(const FVector &row1, const FVector &row2, const FVector &row3); /** - * Sets the data for the matrix - */ - void set(const DVector &row1, const DVector &row2, const DVector &row3); - - /** * Sets the data for the matrix from a vector */ void set(const FVector &v); diff --git a/engines/titanic/star_control/fpose.cpp b/engines/titanic/star_control/fpose.cpp index bb508228fe..34a7a40d29 100644 --- a/engines/titanic/star_control/fpose.cpp +++ b/engines/titanic/star_control/fpose.cpp @@ -21,6 +21,8 @@ */ #include "titanic/star_control/fpose.h" +#include "titanic/star_control/matrix_transform.h" +#include "titanic/star_control/matrix_inv.h" namespace Titanic { @@ -36,9 +38,9 @@ void fposeProd(const FPose &a, const FPose &m, FPose &C) { C._row3._x = m._row1._x * a._row3._x + a._row3._z * m._row3._x + a._row3._y * m._row2._x; C._row3._y = a._row3._y * m._row2._y + a._row3._z * m._row3._y + a._row3._x * m._row1._y; C._row3._z = a._row3._x * m._row1._z + a._row3._y * m._row2._z + a._row3._z * m._row3._z; - C._vector._x = m._row1._x * a._vector._x + a._vector._y * m._row2._x + a._vector._z * m._row3._x + m._vector._x; - C._vector._y = a._vector._z * m._row3._y + a._vector._y * m._row2._y + a._vector._x * m._row1._y + a._vector._y; - C._vector._z = a._vector._y * m._row2._z + a._vector._z * m._row3._z + a._vector._x * m._row1._z + m._vector._z; + C._vector._x = a._vector._x * m._row1._x + a._vector._y * m._row2._x + a._vector._z * m._row3._x + m._vector._x; + C._vector._y = a._vector._x * m._row1._y + a._vector._y * m._row2._y + a._vector._z * m._row3._y + m._vector._y; + C._vector._z = a._vector._x * m._row1._z + a._vector._y * m._row2._z + a._vector._z * m._row3._z + m._vector._z; } // Member functions @@ -59,6 +61,29 @@ FPose::FPose(const FPose &s1, const FPose &s2) { fposeProd(s1, s2, *this); } +FPose::FPose(int mode, const FVector &src) { + switch (mode) { + case 0: + _row1._x = 1.0; + _row2._y = 1.0; + _row3._z = 1.0; + _vector = src; + break; + + case 1: + _row1._x = src._x; + _row2._y = src._y; + _row3._z = src._z; + break; + + default: + _row1._x = 1.0; + _row2._y = 1.0; + _row3._z = 1.0; + break; + } +} + void FPose::identity() { FMatrix::identity(); _vector.clear(); @@ -114,6 +139,13 @@ void FPose::setRotationMatrix(Axis axis, float amount) { _vector.clear(); } +void FPose::rotVectAxisY(double angleDeg) { + _row1.rotVectAxisY(angleDeg); + _row2.rotVectAxisY(angleDeg); + _row3.rotVectAxisY(angleDeg); + _vector.rotVectAxisY(angleDeg); +} + void FPose::copyFrom(const FPose &src) { _row1 = src._row1; _row2 = src._row2; @@ -128,29 +160,82 @@ void FPose::copyFrom(const FMatrix &src) { } FPose FPose::inverseTransform() const { - FPose result; - - result._row1._x = _row1._x; - result._row2._x = _row1._y; - result._row3._x = _row1._z; - result._row1._y = _row2._x; - result._row2._y = _row2._y; - result._row3._y = _row2._z; - result._row1._z = _row3._x; - result._row2._z = _row3._y; - result._row3._z = _row3._z; - - result._vector._x = -(_vector._x * result._row1._x - + _vector._y * result._row2._x - + _vector._z * result._row3._x); - result._vector._y = -(_vector._x * result._row1._y - + _vector._y * result._row2._y - + _vector._z * result._row3._y); - result._vector._z = -(_vector._x * result._row1._z - + _vector._y * result._row2._z - + _vector._z * result._row3._z); - - return result; + FPose matrix_inv; + + matrix_inv._row1._x = _row1._x; + matrix_inv._row2._x = _row1._y; + matrix_inv._row3._x = _row1._z; + matrix_inv._row1._y = _row2._x; + matrix_inv._row2._y = _row2._y; + matrix_inv._row3._y = _row2._z; + matrix_inv._row1._z = _row3._x; + matrix_inv._row2._z = _row3._y; + matrix_inv._row3._z = _row3._z; + + float A[16]={_row1._x,_row1._y,_row1._z, 0.0, + _row2._x,_row2._y,_row2._z, 0.0, + _row3._x,_row3._y,_row3._z, 0.0, + _vector._x,_vector._y,_vector._z, 1.0}; + // Inverse matrix + float B[16]={}; + + // B contains inverse of A + matrix4Inverse<float>(A,B); + matrix_inv._vector._x=B[12]; + matrix_inv._vector._y=B[13]; + matrix_inv._vector._z=B[14]; + + return matrix_inv; +} + +//TODO: Check math and provide source +void FPose::loadTransform(const CMatrixTransform &src) { + double total = src.fn1(); + double factor = (total <= 0.0) ? 0.0 : 2.0 / total; + FVector temp1V = src._vector * factor; + FVector temp2V = temp1V * src._vector; + + double val1 = temp1V._y * src._vector._x; + double val2 = temp1V._z * src._vector._x; + double val3 = temp1V._z * src._vector._y; + double val4 = temp1V._x * src._field0; + double val5 = temp1V._y * src._field0; + double val6 = temp1V._z * src._field0; + + _row1._x = 1.0 - (temp2V._z + temp2V._y); + _row1._y = val1 + val6; + _row1._z = val2 - val5; + _row2._x = val1 - val6; + _row2._y = 1.0 - (temp2V._z + temp2V._x); + _row2._z = val3 + val4; + _row3._x = val2 + val5; + _row3._y = val3 - val4; + _row3._z = 1.0 - (temp2V._y + temp2V._x); + _vector._x = 0; + _vector._y = 0; + _vector._z = 0; +} + +FPose FPose::compose(const FMatrix &m) { + FPose dm; + FPose am; + am._row1 = m._row1; + am._row2 = m._row2; + am._row3 = m._row3; + + fposeProd(*this,am,dm); + + return dm; +} + +FPose FPose::compose2(const FPose &m) { + FPose dm; + dm._row1 = _row1.MatProdRowVect(m); + dm._row2 = _row2.MatProdRowVect(m); + dm._row3 = _row3.MatProdRowVect(m); + dm._vector = _vector.MatProdRowVect(m); + + return dm; } } // End of namespace Titanic diff --git a/engines/titanic/star_control/fpose.h b/engines/titanic/star_control/fpose.h index 5287ff0516..d2a6923184 100644 --- a/engines/titanic/star_control/fpose.h +++ b/engines/titanic/star_control/fpose.h @@ -27,9 +27,10 @@ namespace Titanic { +class CMatrixTransform; + /* * This class combines a position and orientation in 3D space - * TODO: Merge with DAffine */ class FPose : public FMatrix { public: @@ -38,7 +39,7 @@ public: FPose(); FPose(Axis axis, float amount); FPose(const FPose &src); - + FPose(int mode, const FVector &src); /** * This fpose is the fpose product of s1 (on the left) and s2 (on the right) */ @@ -55,6 +56,10 @@ public: void setRotationMatrix(Axis axis, float val); /** + * Rotate this FPose about the Y axis + */ + void rotVectAxisY(double angleDeg); + /** * Copy from the specified source pose */ void copyFrom(const FPose &src); @@ -65,9 +70,30 @@ public: void copyFrom(const FMatrix &src); /** + * Change this Daffine to have its first three columns be some mapping from src matrix + * and the 4rth column to be (three) zeros. The mapping is not as simple as replacing + * matching row/colmn indices + */ + void loadTransform(const CMatrixTransform &src); + + /** * The inverse of rotation and the position vector */ FPose inverseTransform() const; + + /** + * Multiplication between this FPose (4x3) and a FMatrix (3x3) + * This is done by making the matrix be a FPose with a last row + * of zeros + */ + FPose compose(const FMatrix &m); + + /** + * Multiplication between this FPose (4x3) and another FPose + * This FPose is on the left and m is on the right. + * The last row of m is added to the output component wise + */ + FPose compose2(const FPose &m); }; /** diff --git a/engines/titanic/star_control/fvector.cpp b/engines/titanic/star_control/fvector.cpp index d880a134f5..4fd17bf883 100644 --- a/engines/titanic/star_control/fvector.cpp +++ b/engines/titanic/star_control/fvector.cpp @@ -21,16 +21,11 @@ */ #include "titanic/star_control/fvector.h" -#include "titanic/star_control/dvector.h" #include "titanic/star_control/fpose.h" -//#include "common/algorithm.h" //#include "common/textconsole.h" namespace Titanic { -FVector::FVector(const DVector &src) : _x(src._x), _y(src._y), _z(src._z) { -} - FVector FVector::swapComponents() const { return FVector( (ABS(_x - _y) < 0.00001 && ABS(_y - _z) < 0.00001 && @@ -48,6 +43,16 @@ FVector FVector::crossProduct(const FVector &src) const { ); } +void FVector::rotVectAxisY(float angleDeg) { + float sinVal = sin(angleDeg * Deg2Rad); + float cosVal = cos(angleDeg * Deg2Rad); + float x = cosVal * _x - sinVal * _z; + float z = cosVal * _z + sinVal * _x; + + _x = x; + _z = z; +} + bool FVector::normalize(float & hyp) { hyp = sqrt(_x * _x + _y * _y + _z * _z); if (hyp==0) { @@ -73,6 +78,23 @@ FVector FVector::addAndNormalize(const FVector &v) const { return tempV; } +FVector FVector::getAnglesAsVect() const { + FVector vector = *this; + FVector dest; + + if (!vector.normalize(dest._x)) { + // Makes this vector have magnitude=1, put the scale amount in dest._x, + // but if it is unsuccessful, crash + assert(dest._x); + } + + dest._y = acos(vector._y); // radian distance/angle that this vector's y component is from the +y axis, + // result is restricted to [0,pi] + dest._z = atan2(vector._x,vector._z); // result is restricted to [-pi,pi] + + return dest; +} + float FVector::getDistance(const FVector &src) const { float xd = src._x - _x; float yd = src._y - _y; @@ -89,6 +111,34 @@ FVector FVector::MatProdRowVect(const FPose &pose) const { return v; } +FPose FVector::getFrameTransform(const FVector &v) { + FPose matrix1, matrix2, matrix3, matrix4; + + FVector vector1 = getAnglesAsVect(); + matrix1.setRotationMatrix(X_AXIS, vector1._y * Rad2Deg); + matrix2.setRotationMatrix(Y_AXIS, vector1._z * Rad2Deg); + fposeProd(matrix1,matrix2,matrix3); + matrix4 = matrix3.inverseTransform(); + + vector1 = v.getAnglesAsVect(); + matrix1.setRotationMatrix(X_AXIS, vector1._y * Rad2Deg); + matrix2.setRotationMatrix(Y_AXIS, vector1._z * Rad2Deg); + fposeProd(matrix1,matrix2,matrix3); + fposeProd(matrix4,matrix3,matrix1); + + return matrix1; +} + +FPose FVector::formRotXY() const { + FVector v1 = getAnglesAsVect(); + FPose m1, m2; + m1.setRotationMatrix(X_AXIS, v1._y * Rad2Deg); + m2.setRotationMatrix(Y_AXIS, v1._z * Rad2Deg); + FPose m3; + fposeProd(m1,m2,m3); + return m3; +} + Common::String FVector::toString() const { return Common::String::format("(%.3f,%.3f,%.3f)", _x, _y, _z); } diff --git a/engines/titanic/star_control/fvector.h b/engines/titanic/star_control/fvector.h index 5303702699..6f4c48303f 100644 --- a/engines/titanic/star_control/fvector.h +++ b/engines/titanic/star_control/fvector.h @@ -32,11 +32,9 @@ const double Deg2Rad = 1.0 / Rad2Deg; enum Axis { X_AXIS, Y_AXIS, Z_AXIS }; class FPose; -class DVector; /** * Floating point vector class. - * @remarks TODO: See if it can be merged with DVector */ class FVector { public: @@ -44,7 +42,6 @@ public: public: FVector() : _x(0), _y(0), _z(0) {} FVector(float x, float y, float z) : _x(x), _y(y), _z(z) {} - FVector(const DVector &src); /** * Clears the vector @@ -66,6 +63,11 @@ public: FVector crossProduct(const FVector &src) const; /** + * Rotate this vector about the Y axis + */ + void rotVectAxisY(float angleDeg); + + /** * Attempts to normalizes the vector so the length from origin equals 1.0 * Return value is whether or not it was successful in normalizing * First argument is scale value that normalizes the vector @@ -83,6 +85,14 @@ public: FVector addAndNormalize(const FVector &v) const; /** + * Returns a vector, v, that represents a magnitude, and two angles in radians + * 1. Scale this vector to be unit magnitude and store scale in x component of v + * 2. X rotation angle from +y axis of this vector is put in y component of v + * 3. z component output of v is the 4-quadrant angle that z makes with x (Y axis rotation) + */ + FVector getAnglesAsVect() const; + + /** * Returns the distance between a specified point and this one */ float getDistance(const FVector &src) const; @@ -94,6 +104,18 @@ public: FVector MatProdRowVect(const FPose &pose) const; /** + * Returns a matrix that contains the frame rotation based on this vector and + * a vector rotation based on input vector v + */ + FPose getFrameTransform(const FVector &v); + + /** + * Constructs an affine matrix that does a x then a y axis frame rotation + * based on the orientation of this vector + */ + FPose formRotXY() const; + + /** * Returns true if the passed vector equals this one */ bool operator==(const FVector &src) const { @@ -119,6 +141,10 @@ public: return FVector(_x * right, _y * right, _z * right); } + const FVector operator*(const FVector &right) const { + return FVector(_x * right._x, _y * right._y, _z * right._z); + } + void operator+=(const FVector &delta) { _x += delta._x; _y += delta._y; diff --git a/engines/titanic/star_control/matrix_inv.h b/engines/titanic/star_control/matrix_inv.h index 21eb1d3a6f..642c414717 100644 --- a/engines/titanic/star_control/matrix_inv.h +++ b/engines/titanic/star_control/matrix_inv.h @@ -52,11 +52,12 @@ namespace Titanic { // 4x4 Matrix m is column major, e.x., m[3] is the row 4 column 1 element // Modified version of MESA 3D library function (MIT license) -bool matrix4Inverse(const double m[16], double invOut[16]) +template <typename T> +bool matrix4Inverse(const T m[16], T invOut[16]) { - double temp_inv[16]; - double determinant; - double determinant_inv; + T temp_inv[16]; + T determinant; + T determinant_inv; int i; temp_inv[0] = m[5] * m[10] * m[15] - diff --git a/engines/titanic/star_control/matrix_transform.cpp b/engines/titanic/star_control/matrix_transform.cpp index 4f1324d310..0511ba678b 100644 --- a/engines/titanic/star_control/matrix_transform.cpp +++ b/engines/titanic/star_control/matrix_transform.cpp @@ -21,7 +21,7 @@ */ #include "titanic/star_control/matrix_transform.h" -#include "titanic/star_control/daffine.h" +#include "titanic/star_control/fpose.h" #include "common/textconsole.h" namespace Titanic { @@ -55,47 +55,47 @@ CMatrixTransform CMatrixTransform::resize(double factor) const { return dest; } -void CMatrixTransform::fn4(const DAffine &m) { - double total = m._col1._x + m._col3._z + m._col2._y + 1.0; +void CMatrixTransform::fn4(const FMatrix &m) { + double total = m._row1._x + m._row3._z + m._row2._y + 1.0; if (total <= 0.00001) { - total = m._col3._z; + total = m._row3._z; - if (m._col1._x <= m._col3._z) { - if (m._col2._y > total) - total = m._col2._y; - } else if (m._col1._x > total) { - total = m._col1._x; + if (m._row1._x <= m._row3._z) { + if (m._row2._y > total) + total = m._row2._y; + } else if (m._row1._x > total) { + total = m._row1._x; } - if (total == m._col1._x) { - double val1 = sqrt(m._col1._x - -1.0 - m._col2._y - m._col3._z); + if (total == m._row1._x) { + double val1 = sqrt(m._row1._x - -1.0 - m._row2._y - m._row3._z); double val2 = 0.5 / val1; _vector._x = val1 * 0.5; - _field0 = (m._col2._z - m._col3._y) * val2; - _vector._y = (m._col2._x + m._col1._y) * val2; - _vector._z = (m._col3._x + m._col1._z) * val2; - } else if (total == m._col2._y) { - double val1 = sqrt(m._col2._y - -1.0 - m._col3._z - m._col1._x); + _field0 = (m._row2._z - m._row3._y) * val2; + _vector._y = (m._row2._x + m._row1._y) * val2; + _vector._z = (m._row3._x + m._row1._z) * val2; + } else if (total == m._row2._y) { + double val1 = sqrt(m._row2._y - -1.0 - m._row3._z - m._row1._x); double val2 = 0.5 / val1; _vector._y = val1 * 0.5; - _field0 = (m._col3._x - m._col1._z) * val2; - _vector._z = (m._col3._y + m._col2._z) * val2; - _vector._x = (m._col2._x + m._col1._y) * val2; - } else if (total == m._col3._z) { - double val1 = sqrt(m._col3._z - -1.0 - m._col1._x - m._col2._y); + _field0 = (m._row3._x - m._row1._z) * val2; + _vector._z = (m._row3._y + m._row2._z) * val2; + _vector._x = (m._row2._x + m._row1._y) * val2; + } else if (total == m._row3._z) { + double val1 = sqrt(m._row3._z - -1.0 - m._row1._x - m._row2._y); double val2 = 0.5 / val1; _vector._z = val1 * 0.5; - _field0 = (m._col1._y - m._col2._x) * val2; - _vector._x = (m._col3._x + m._col1._z) * val2; - _vector._y = (m._col3._y + m._col2._z) * val2; + _field0 = (m._row1._y - m._row2._x) * val2; + _vector._x = (m._row3._x + m._row1._z) * val2; + _vector._y = (m._row3._y + m._row2._z) * val2; } } else { double val1 = 0.5 / sqrt(total); _field0 = sqrt(total) * 0.5; - _vector._x = (m._col2._z - m._col3._y) * val1; - _vector._y = (m._col3._x - m._col1._z) * val1; - _vector._z = (m._col1._y - m._col2._x) * val1; + _vector._x = (m._row2._z - m._row3._y) * val1; + _vector._y = (m._row3._x - m._row1._z) * val1; + _vector._z = (m._row1._y - m._row2._x) * val1; } } diff --git a/engines/titanic/star_control/matrix_transform.h b/engines/titanic/star_control/matrix_transform.h index 92d4fbff22..7d0f753a4e 100644 --- a/engines/titanic/star_control/matrix_transform.h +++ b/engines/titanic/star_control/matrix_transform.h @@ -23,11 +23,11 @@ #ifndef TITANIC_MATRIX_TRANSFORM_H #define TITANIC_MATRIX_TRANSFORM_H -#include "titanic/star_control/dvector.h" +#include "titanic/star_control/fvector.h" namespace Titanic { -class Daffine; +class FMatrix; class CMatrixTransform { private: @@ -35,7 +35,7 @@ private: CMatrixTransform resize(double factor) const; public: double _field0; - DVector _vector; + FVector _vector; public: CMatrixTransform() : _field0(1.0) {} @@ -50,7 +50,7 @@ public: void copyFrom(const CMatrixTransform &src); double fn1() const; - void fn4(const DAffine &m); + void fn4(const FMatrix &m); CMatrixTransform fn5(double percent, const CMatrixTransform &src); }; diff --git a/engines/titanic/star_control/orientation_changer.cpp b/engines/titanic/star_control/orientation_changer.cpp index a0c5c73fbe..78dfd4b53c 100644 --- a/engines/titanic/star_control/orientation_changer.cpp +++ b/engines/titanic/star_control/orientation_changer.cpp @@ -21,7 +21,8 @@ */ #include "titanic/star_control/orientation_changer.h" -#include "titanic/star_control/daffine.h" +#include "titanic/star_control/fpose.h" +#include "titanic/star_control/fmatrix.h" namespace Titanic { @@ -41,7 +42,7 @@ FMatrix COrientationChanger::getOrientation(double percent) { } else { CMatrixTransform tfm = _sub1.fn5(percent, _sub2); - DAffine m1; + FPose m1; m1.loadTransform(tfm); return m1; } diff --git a/engines/titanic/star_control/star_camera.cpp b/engines/titanic/star_control/star_camera.cpp index c9cffd481f..ce083dee78 100644 --- a/engines/titanic/star_control/star_camera.cpp +++ b/engines/titanic/star_control/star_camera.cpp @@ -23,7 +23,6 @@ #include "titanic/star_control/star_camera.h" #include "titanic/debugger.h" #include "titanic/star_control/camera_mover.h" -#include "titanic/star_control/daffine.h" #include "titanic/star_control/fmatrix.h" #include "titanic/star_control/fpoint.h" #include "titanic/star_control/marked_camera_mover.h" @@ -319,21 +318,22 @@ void CStarCamera::setViewportAngle(const FPoint &angles) { case TWO_LOCKED: { FVector tempV2; - DAffine m1, m2, sub; - DVector mrow1, mrow2, mrow3; - DVector tempV1, diffV, multV, multV2, tempV3, tempV4, tempV5, tempV6, tempV7; - DVector tempV8, tempV9, tempV10, tempV11, tempV12; - DVector tempV13, tempV14, tempV15, tempV16; + FPose m1; + FVector mrow1, mrow2, mrow3; + FVector tempV1, diffV, multV, multV2, tempV3, tempV7; - DAffine subX(0, _lockedStarsPos._row1); - DAffine subY(Y_AXIS, angles._y); + FPose subX(0, _lockedStarsPos._row1); + FPose subY(Y_AXIS, angles._y); tempV1 = _lockedStarsPos._row2 - _lockedStarsPos._row1; diffV = tempV1; m1 = diffV.formRotXY(); - m1 = m1.compose(subX); - subX = m1.inverseTransform(); - subX = subX.compose(subY); + FPose m11; + fposeProd(m1,subX,m11); + + subX = m11.inverseTransform(); + FPose m12; + fposeProd(subX,subY,m12); FMatrix m3 = _viewport.getOrientation(); tempV2 = _viewport._position; @@ -361,22 +361,22 @@ void CStarCamera::setViewportAngle(const FPoint &angles) { tempV7._y = m3._row3._y * rowScale2 + tempV3._y; tempV7._x = m3._row3._x * rowScale2 + tempV3._x; - mrow3 = tempV8 = tempV7; - tempV3 = tempV3.dAffMatrixProdVec(subX); - mrow1 = mrow1.dAffMatrixProdVec(subX); - mrow2 = mrow2.dAffMatrixProdVec(subX); - mrow3 = mrow3.dAffMatrixProdVec(subX); + mrow3 = tempV7; + tempV3 = tempV3.MatProdRowVect(m12); + mrow1 = mrow1.MatProdRowVect(m12); + mrow2 = mrow2.MatProdRowVect(m12); + mrow3 = mrow3.MatProdRowVect(m12); - tempV3 = tempV3.dAffMatrixProdVec(m1); - mrow1 = mrow1.dAffMatrixProdVec(m1); - mrow2 = mrow2.dAffMatrixProdVec(m1); - mrow3 = mrow3.dAffMatrixProdVec(m1); + tempV3 = tempV3.MatProdRowVect(m11); + mrow1 = mrow1.MatProdRowVect(m11); + mrow2 = mrow2.MatProdRowVect(m11); + mrow3 = mrow3.MatProdRowVect(m11); mrow1 -= tempV3; mrow2 -= tempV3; mrow3 -= tempV3; - double unusedScale=0.0; + float unusedScale=0.0; if (!mrow1.normalize(unusedScale) || !mrow2.normalize(unusedScale) || !mrow3.normalize(unusedScale)) { @@ -385,11 +385,9 @@ void CStarCamera::setViewportAngle(const FPoint &angles) { assert(unusedScale); } - tempV16 = tempV3; - m3.set(mrow1, mrow2, mrow3); _viewport.setOrientation(m3); - _viewport.setPosition(tempV16); + _viewport.setPosition(tempV3); break; } @@ -521,83 +519,81 @@ bool CStarCamera::lockMarker2(CViewport *viewport, const FVector &secondStarPosi _isInLockingProcess = true; FVector firstStarPosition = _lockedStarsPos._row1; - DAffine m2(0, firstStarPosition); // Identity matrix and col4 as the 1st stars position - DVector starDelta = secondStarPosition - firstStarPosition; - DAffine m1 = starDelta.formRotXY(); - m1 = m1.compose(m2); - m2 = m1.inverseTransform(); - - DVector oldPos = _viewport._position; - DAffine m4; - m4._col1 = viewport->_position; - m4._col2 = DVector(0.0, 0.0, 0.0); - m4._col3 = DVector(0.0, 0.0, 0.0); - m4._col4 = DVector(0.0, 0.0, 0.0); + FPose m3(0, firstStarPosition); // Identity matrix and row4 as the 1st stars position + FVector starDelta = secondStarPosition - firstStarPosition; + FPose m10 = starDelta.formRotXY(); + FPose m11; + fposeProd(m10,m3,m11); + + m10 = m11.inverseTransform(); + + FVector oldPos = _viewport._position; + + FPose m4; + m4._row1 = viewport->_position; + m4._row2 = FVector(0.0, 0.0, 0.0); + m4._row3 = FVector(0.0, 0.0, 0.0); + m4._vector = FVector(0.0, 0.0, 0.0); FMatrix newOr = viewport->getOrientation(); - double yVal1 = newOr._row1._y * rowScale2; - double zVal1 = newOr._row1._z * rowScale2; - double xVal1 = newOr._row2._x * rowScale2; - double yVal2 = newOr._row2._y * rowScale2; - double zVal2 = newOr._row2._z * rowScale2; - double zVal3 = zVal1 + m4._col1._z; - double yVal3 = yVal1 + m4._col1._y; - double xVal2 = newOr._row1._x * rowScale2 + m4._col1._x; - double zVal4 = zVal2 + m4._col1._z; - double yVal4 = yVal2 + m4._col1._y; - double xVal3 = xVal1 + m4._col1._x; - - DVector tempV4(xVal2, yVal3, zVal3); - DVector tempV3(xVal3, yVal4, zVal4); - m4._col3 = tempV4; + float yVal1 = newOr._row1._y * rowScale2; + float zVal1 = newOr._row1._z * rowScale2; + float xVal1 = newOr._row2._x * rowScale2; + float yVal2 = newOr._row2._y * rowScale2; + float zVal2 = newOr._row2._z * rowScale2; + float zVal3 = zVal1 + m4._row1._z; + float yVal3 = yVal1 + m4._row1._y; + float xVal2 = newOr._row1._x * rowScale2 + m4._row1._x; + float zVal4 = zVal2 + m4._row1._z; + float yVal4 = yVal2 + m4._row1._y; + float xVal3 = xVal1 + m4._row1._x; + + FVector tempV4(xVal2, yVal3, zVal3); + FVector tempV3(xVal3, yVal4, zVal4); + m4._row3 = tempV4; FVector tempV5; tempV5._x = newOr._row3._x * rowScale2; tempV5._y = newOr._row3._y * rowScale2; - m4._col2 = tempV3; - - tempV3._x = tempV5._x + m4._col1._x; - tempV3._y = tempV5._y + m4._col1._y; - tempV3._z = newOr._row3._z * rowScale2 + m4._col1._z; - m4._col4 = tempV3; - - DVector viewPosition = oldPos.dAffMatrixProdVec(m2); - m4._col1 = m4._col1.dAffMatrixProdVec(m2); - m4._col3 = m4._col3.dAffMatrixProdVec(m2); - m4._col2 = m4._col2.dAffMatrixProdVec(m2); - m4._col4 = m4._col4.dAffMatrixProdVec(m2); - - double minDistance; - // Find the angle of rotation for m4._col1 that gives the minimum distance to viewPosition - double minDegree = calcAngleForMinDist(viewPosition,m4._col1,minDistance); - - m4._col1.rotVectAxisY((double)minDegree); - m4._col2.rotVectAxisY((double)minDegree); - m4._col3.rotVectAxisY((double)minDegree); - m4._col4.rotVectAxisY((double)minDegree); - m4._col1 = m4._col1.dAffMatrixProdVec(m1); - m4._col2 = m4._col2.dAffMatrixProdVec(m1); - m4._col3 = m4._col3.dAffMatrixProdVec(m1); - m4._col4 = m4._col4.dAffMatrixProdVec(m1); - - m4._col3 -= m4._col1; - m4._col2 -= m4._col1; - m4._col4 -= m4._col1; - - - - double unusedScale=0.0; - if (!m4._col2.normalize(unusedScale) || - !m4._col3.normalize(unusedScale) || - !m4._col4.normalize(unusedScale) ) { + m4._row2 = tempV3; + + tempV3._x = tempV5._x + m4._row1._x; + tempV3._y = tempV5._y + m4._row1._y; + tempV3._z = newOr._row3._z * rowScale2 + m4._row1._z; + m4._vector = tempV3; + + + FVector viewPosition2 = oldPos.MatProdRowVect(m10); + m3 = m4.compose2(m10); + + float minDistance; + FVector x1(viewPosition2); + FVector x2(m3._row1); + // Find the angle of rotation for m4._row1 that gives the minimum distance to viewPosition + float minDegree = calcAngleForMinDist(x1,x2,minDistance); + + m3.rotVectAxisY((double)minDegree); + FPose m13; + m13 = m3.compose2(m11); + + m13._row3 -= m13._row1; + m13._row2 -= m13._row1; + m13._vector -= m13._row1; + + + + float unusedScale=0.0; + if (!m13._row2.normalize(unusedScale) || + !m13._row3.normalize(unusedScale) || + !m13._vector.normalize(unusedScale) ) { // Do the normalizations, put the scale amount in unusedScale, // but if any of the normalizations are unsuccessful, crash assert(unusedScale); } - newOr.set(m4._col3, m4._col2, m4._col4); + newOr.set(m13._row3, m13._row2, m13._vector); - FVector newPos = m4._col1; + FVector newPos = m13._row1; FMatrix oldOr = _viewport.getOrientation(); // WORKAROUND: set old position to new position (1st argument), this prevents @@ -619,7 +615,9 @@ bool CStarCamera::lockMarker3(CViewport *viewport, const FVector &thirdStarPosit FVector newPos = viewport->_position; FVector oldPos = _viewport._position; - _mover->transitionBetweenPosOrients(oldPos, newPos, oldOr, newOr); + // WORKAROUND: set old position to new position (1st argument), this prevents + // locking issues when locking the 3rd star. Fixes #9961. + _mover->transitionBetweenPosOrients(newPos, newPos, oldOr, newOr); CStarVector *sv = new CStarVector(this, thirdStarPosition); _mover->setVector(sv); @@ -627,20 +625,20 @@ bool CStarCamera::lockMarker3(CViewport *viewport, const FVector &thirdStarPosit return true; } -double CStarCamera::calcAngleForMinDist(DVector &x, DVector &y, double &minDistance) { - DVector tempPos; +float CStarCamera::calcAngleForMinDist(FVector &x, FVector &y, float &minDistance) { + FVector tempPos; minDistance = 1.0e20; - double minDegree = 0.0; - double degInc = 1.0; // one degree steps + float minDegree = 0.0; + float degInc = 1.0; // one degree steps int nDegrees = floor(360.0/degInc); for (int i = 0; i < nDegrees; ++i) { tempPos = y; - tempPos.rotVectAxisY((double)degInc*i); - double distance = x.getDistance(tempPos); + tempPos.rotVectAxisY((float)degInc*i); + float distance = x.getDistance(tempPos); if (distance < minDistance) { minDistance = distance; - minDegree = (double) degInc*i; + minDegree = (float) degInc*i; } } return minDegree; diff --git a/engines/titanic/star_control/star_camera.h b/engines/titanic/star_control/star_camera.h index 72c26c12a6..3ffb74950a 100644 --- a/engines/titanic/star_control/star_camera.h +++ b/engines/titanic/star_control/star_camera.h @@ -211,7 +211,7 @@ public: * The angle is in degrees. * Also returns the minimum distance calculated */ - double calcAngleForMinDist(DVector &x, DVector &y, double &minDistance); + float calcAngleForMinDist(FVector &x, FVector &y, float &minDistance); /** * Returns true for whether the camera has been moved diff --git a/engines/titanic/star_control/unmarked_camera_mover.cpp b/engines/titanic/star_control/unmarked_camera_mover.cpp index c1459ec372..200d549ce1 100644 --- a/engines/titanic/star_control/unmarked_camera_mover.cpp +++ b/engines/titanic/star_control/unmarked_camera_mover.cpp @@ -23,8 +23,7 @@ #include "titanic/star_control/unmarked_camera_mover.h" #include "titanic/debugger.h" #include "titanic/star_control/base_stars.h" // includes class CStarVector -#include "titanic/star_control/dvector.h" -#include "titanic/star_control/daffine.h" +#include "titanic/star_control/fpose.h" #include "titanic/star_control/error_code.h" #include "titanic/star_control/fmatrix.h" // includes class FVector #include "titanic/titanic.h" @@ -50,10 +49,10 @@ void CUnmarkedCameraMover::transitionBetweenOrientations(const FVector &v1, cons if (isLocked()) decLockCount(); - DVector vector1 = v1; - DVector vector2 = v2; - DAffine matrix1 = vector2.getFrameTransform(vector1); - DAffine matrix2 = matrix1.compose(m); + FVector vector1 = v1; + FVector vector2 = v2; + FPose matrix1 = vector2.getFrameTransform(vector1); + FPose matrix2 = matrix1.compose(m); _autoMover.setOrientations(m, matrix2); incLockCount(); diff --git a/engines/titanic/star_control/viewport.h b/engines/titanic/star_control/viewport.h index ae10fb3c94..d5c35b6317 100644 --- a/engines/titanic/star_control/viewport.h +++ b/engines/titanic/star_control/viewport.h @@ -119,7 +119,7 @@ public: * Applys a rotation matrix to the current * orientation */ - void changeOrientation(const FMatrix &matrix);\ + void changeOrientation(const FMatrix &matrix); FPose getPose(); FPose getRawPose(); |