2016-03-05 21:44:57 -05:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
#include "titanic/star_control/viewport.h"
|
2017-08-30 20:05:47 -04:00
|
|
|
#include "titanic/star_control/fvector.h"
|
2017-08-24 04:05:49 -07:00
|
|
|
#include "titanic/debugger.h"
|
2017-08-23 06:16:00 -07:00
|
|
|
#include "titanic/support/simple_file.h"
|
2017-03-11 15:03:34 -05:00
|
|
|
#include "titanic/titanic.h"
|
2016-03-05 21:44:57 -05:00
|
|
|
|
2018-05-24 05:58:57 -07:00
|
|
|
#include "common/math.h"
|
|
|
|
|
2016-03-05 21:44:57 -05:00
|
|
|
namespace Titanic {
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
CViewport::CViewport() {
|
2017-08-27 05:18:12 -07:00
|
|
|
_fieldC = 0; // doesn't get used
|
|
|
|
_field10 = 800.0; // doesn't get used
|
|
|
|
_field14 = 10000.0; // doesn't get used
|
|
|
|
_centerYAngleDegrees = 20.0;
|
|
|
|
_centerZAngleDegrees = 20.0;
|
2017-03-11 14:30:31 -05:00
|
|
|
_width = 600;
|
|
|
|
_height = 340;
|
2017-08-27 05:18:12 -07:00
|
|
|
_starColor = PINK; // default for starview
|
|
|
|
_poseUpToDate = false;
|
|
|
|
Common::fill(&_valArray[0], &_valArray[2], 0.0);
|
|
|
|
_isZero = 0.0; // seems to always be zero
|
|
|
|
_pixel1OffSetX = 0.0;
|
|
|
|
_pixel2OffSetX = 0.0;
|
2016-03-05 21:44:57 -05:00
|
|
|
}
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
CViewport::CViewport(CViewport *src) :
|
2017-04-16 21:46:36 -04:00
|
|
|
_orientation(src->_orientation), _currentPose(src->_currentPose), _rawPose(src->_rawPose) {
|
2016-07-17 21:26:03 -04:00
|
|
|
_position = src->_position;
|
2016-07-17 16:43:53 -04:00
|
|
|
_fieldC = src->_fieldC;
|
|
|
|
_field10 = src->_field10;
|
|
|
|
_field14 = src->_field14;
|
2017-08-27 05:18:12 -07:00
|
|
|
_centerYAngleDegrees = src->_centerYAngleDegrees;
|
|
|
|
_centerZAngleDegrees = src->_centerZAngleDegrees;
|
2016-07-17 16:43:53 -04:00
|
|
|
_width = src->_width;
|
|
|
|
_height = src->_height;
|
|
|
|
|
2017-04-01 18:01:38 -04:00
|
|
|
_center = src->_center;
|
|
|
|
_centerVector = src->_centerVector;
|
2017-08-27 05:18:12 -07:00
|
|
|
_starColor = src->_starColor;
|
2016-07-17 16:43:53 -04:00
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
Common::copy(&src->_valArray[0], &src->_valArray[2], &_valArray[0]);
|
|
|
|
_isZero = src->_isZero;
|
|
|
|
_pixel1OffSetX = src->_pixel1OffSetX;
|
|
|
|
_pixel2OffSetX = src->_pixel2OffSetX;
|
|
|
|
_poseUpToDate = false;
|
2016-07-17 16:43:53 -04:00
|
|
|
}
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::copyFrom(const CViewport *src) {
|
2017-03-26 18:35:07 -04:00
|
|
|
error("Unused function");
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::load(SimpleFile *file, int param) {
|
2016-07-17 21:26:03 -04:00
|
|
|
_position._x = file->readFloat();
|
|
|
|
_position._y = file->readFloat();
|
|
|
|
_position._z = file->readFloat();
|
2016-03-05 21:44:57 -05:00
|
|
|
_fieldC = file->readFloat();
|
|
|
|
_field10 = file->readFloat();
|
|
|
|
_field14 = file->readFloat();
|
2017-08-27 05:18:12 -07:00
|
|
|
_centerYAngleDegrees = file->readFloat();
|
|
|
|
_centerZAngleDegrees = file->readFloat();
|
2016-10-09 14:59:58 +02:00
|
|
|
|
2016-07-17 16:43:53 -04:00
|
|
|
int widthHeight = file->readNumber();
|
2017-04-01 17:36:10 -04:00
|
|
|
_width = widthHeight & 0xffff;
|
|
|
|
_height = widthHeight >> 16;
|
2017-08-27 05:18:12 -07:00
|
|
|
int field24 = file->readNumber(); //0 = White, 2 = Pink
|
|
|
|
_starColor = (StarColor) field24;
|
2016-10-09 14:59:58 +02:00
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
for (int idx = 0; idx < 2; ++idx)
|
2016-03-05 21:44:57 -05:00
|
|
|
_valArray[idx] = file->readFloat();
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
_isZero = file->readFloat();
|
|
|
|
_pixel1OffSetX = file->readFloat();
|
|
|
|
_pixel2OffSetX = file->readFloat();
|
|
|
|
|
2017-04-16 21:46:36 -04:00
|
|
|
_orientation.load(file, param);
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-03-05 21:44:57 -05:00
|
|
|
}
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::save(SimpleFile *file, int indent) {
|
2016-07-17 21:26:03 -04:00
|
|
|
file->writeFloatLine(_position._x, indent);
|
|
|
|
file->writeFloatLine(_position._y, indent);
|
|
|
|
file->writeFloatLine(_position._z, indent);
|
2016-07-17 16:43:53 -04:00
|
|
|
file->writeFloatLine(_fieldC, indent);
|
|
|
|
file->writeFloatLine(_field10, indent);
|
|
|
|
file->writeFloatLine(_field14, indent);
|
2017-08-27 05:18:12 -07:00
|
|
|
file->writeFloatLine(_centerYAngleDegrees, indent);
|
|
|
|
file->writeFloatLine(_centerZAngleDegrees, indent);
|
2017-04-01 17:36:10 -04:00
|
|
|
file->writeNumberLine(_width | (_height << 16), indent);
|
2018-08-17 20:30:20 -07:00
|
|
|
int field24 = (int)_starColor;
|
2017-08-27 05:18:12 -07:00
|
|
|
file->writeNumberLine(field24, indent);
|
2016-07-17 16:43:53 -04:00
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
for (int idx = 0; idx < 2; ++idx)
|
2016-07-17 16:43:53 -04:00
|
|
|
file->writeFloatLine(_valArray[idx], indent);
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
file->writeFloatLine(_isZero, indent);
|
|
|
|
file->writeFloatLine(_pixel1OffSetX, indent);
|
|
|
|
file->writeFloatLine(_pixel2OffSetX, indent);
|
|
|
|
|
2017-04-16 21:46:36 -04:00
|
|
|
_orientation.save(file, indent);
|
2016-03-05 21:44:57 -05:00
|
|
|
}
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::setPosition(const FVector &v) {
|
2017-04-16 13:03:12 -04:00
|
|
|
debugC(DEBUG_INTERMEDIATE, kDebugStarfield, "Setting starmap position to %s", v.toString().c_str());
|
2016-07-17 21:26:03 -04:00
|
|
|
_position = v;
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::setPosition(const FPose &pose) {
|
2017-09-02 11:20:17 -04:00
|
|
|
_position = _position.matProdRowVect(pose);
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-04-16 17:24:41 -04:00
|
|
|
void CViewport::setOrientation(const FMatrix &m) {
|
2017-04-16 21:46:36 -04:00
|
|
|
_orientation = m;
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-07-17 21:26:03 -04:00
|
|
|
}
|
|
|
|
|
2017-05-28 15:53:52 -04:00
|
|
|
void CViewport::setOrientation(const FVector &v) {
|
|
|
|
_orientation.set(v);
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
// This never gets called
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::setC(double v) {
|
2016-07-17 20:18:20 -04:00
|
|
|
_fieldC = v;
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
// This never gets called
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::set10(double v) {
|
2016-07-17 20:18:20 -04:00
|
|
|
_field10 = v;
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
// This never gets called
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::set14(double v) {
|
2016-07-17 20:18:20 -04:00
|
|
|
_field10 = v;
|
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
void CViewport::setCenterYAngle(double angleDegrees) {
|
|
|
|
_centerYAngleDegrees = angleDegrees;
|
|
|
|
_poseUpToDate = false;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
void CViewport::setCenterZAngle(double angleDegrees) {
|
|
|
|
_centerZAngleDegrees = angleDegrees;
|
|
|
|
_poseUpToDate = false;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
void CViewport::randomizeOrientation() {
|
2017-04-16 21:46:36 -04:00
|
|
|
_orientation.identity();
|
2017-03-11 15:03:34 -05:00
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
double ranRotAngleX = g_vm->getRandomNumber(359);
|
|
|
|
double ranRotAngleY = g_vm->getRandomNumber(359);
|
|
|
|
double ranRotAngleZ = g_vm->getRandomNumber(359);
|
|
|
|
|
|
|
|
FPose m1(X_AXIS, ranRotAngleX);
|
|
|
|
FPose m2(Y_AXIS, ranRotAngleY);
|
|
|
|
FPose m3(Z_AXIS, ranRotAngleZ);
|
2018-05-22 16:03:56 +02:00
|
|
|
|
2017-04-05 21:29:32 -04:00
|
|
|
FPose s1(m1, m2);
|
|
|
|
FPose s2(s1, m3);
|
2017-03-11 15:03:34 -05:00
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
_orientation.matRProd(s2);
|
|
|
|
_poseUpToDate = false;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
void CViewport::changeStarColorPixel(StarMode mode, double pixelOffSet) {
|
|
|
|
// pixelOffset is usually 0.0, 30.0, or 28000.0
|
2017-04-01 18:45:22 -04:00
|
|
|
if (mode == MODE_PHOTO) {
|
2017-08-27 05:18:12 -07:00
|
|
|
_valArray[0] = pixelOffSet;
|
|
|
|
_valArray[1] = -pixelOffSet;
|
2016-07-17 20:18:20 -04:00
|
|
|
} else {
|
2017-08-27 05:18:12 -07:00
|
|
|
_pixel1OffSetX = pixelOffSet;
|
|
|
|
_pixel2OffSetX = -pixelOffSet;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
_isZero = 0.0;
|
|
|
|
_starColor = pixelOffSet ? PINK : WHITE;
|
2016-07-17 20:18:20 -04:00
|
|
|
}
|
2016-03-05 21:44:57 -05:00
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::reposition(double factor) {
|
2017-04-16 21:46:36 -04:00
|
|
|
_position._x = _orientation._row3._x * factor + _position._x;
|
|
|
|
_position._y = _orientation._row3._y * factor + _position._y;
|
|
|
|
_position._z = _orientation._row3._z * factor + _position._z;
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
void CViewport::changeOrientation(const FMatrix &matrix) {
|
2017-08-14 17:17:05 -07:00
|
|
|
_orientation.matLProd(matrix);
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = false;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-04-16 16:00:03 -04:00
|
|
|
FPose CViewport::getPose() {
|
2017-08-27 05:18:12 -07:00
|
|
|
if (!_poseUpToDate)
|
2016-07-17 23:18:06 -04:00
|
|
|
reset();
|
|
|
|
|
2017-04-16 16:00:03 -04:00
|
|
|
return _currentPose;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-04-16 16:00:03 -04:00
|
|
|
FPose CViewport::getRawPose() {
|
2017-08-27 05:18:12 -07:00
|
|
|
if (!_poseUpToDate)
|
2016-07-17 23:18:06 -04:00
|
|
|
reset();
|
|
|
|
|
2017-04-16 16:00:03 -04:00
|
|
|
return _rawPose;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-03-11 14:30:31 -05:00
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
// TODO: should index be used here like
|
|
|
|
// getRelativePosCentering/getRelativePosCentering2?
|
|
|
|
// CStarCamera::getRelativePosCentering is calling this with an index of
|
|
|
|
// 2 which corresponds to _isZero which has value 0.
|
|
|
|
FVector CViewport::getRelativePosNoCentering(int index, const FVector &src) {
|
|
|
|
FPose current_pose = getPose();
|
2017-09-02 11:20:17 -04:00
|
|
|
FVector dest = src.matProdRowVect(current_pose);
|
2017-04-07 21:52:36 -04:00
|
|
|
return dest;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
FVector CViewport::getRelativePosCentering(int index, const FVector &src) {
|
2017-03-11 14:30:31 -05:00
|
|
|
FVector dest;
|
2017-04-16 16:00:03 -04:00
|
|
|
FPose pose = getPose();
|
2017-09-02 11:20:17 -04:00
|
|
|
FVector tv = src.matProdRowVect(pose);
|
2017-03-11 14:30:31 -05:00
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
double val;
|
|
|
|
if (index <2) {
|
|
|
|
val = _valArray[index];
|
2017-08-30 20:05:47 -04:00
|
|
|
} else if (index == 2) {
|
2017-08-27 05:18:12 -07:00
|
|
|
val = _isZero;
|
2017-08-30 20:05:47 -04:00
|
|
|
} else if (index == 3) {
|
2017-08-27 05:18:12 -07:00
|
|
|
val = _pixel1OffSetX;
|
2017-08-30 20:05:47 -04:00
|
|
|
} else {
|
2017-08-27 05:18:12 -07:00
|
|
|
val = _pixel2OffSetX;
|
|
|
|
}
|
|
|
|
|
|
|
|
dest._x = (val + tv._x)
|
2017-04-01 18:01:38 -04:00
|
|
|
* _centerVector._x / (_centerVector._y * tv._z);
|
|
|
|
dest._y = (tv._y * _centerVector._x) / (_centerVector._z * tv._z);
|
2017-03-11 14:30:31 -05:00
|
|
|
dest._z = tv._z;
|
|
|
|
return dest;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-09-07 04:27:50 -07:00
|
|
|
// Similar to getRelativePosCentering, but uses the raw/transpose version of Pose
|
2017-09-07 04:29:21 -07:00
|
|
|
FVector CViewport::getRelativePosCenteringRaw(int index, const FVector &src) {
|
2017-03-11 14:30:31 -05:00
|
|
|
FVector dest;
|
2017-04-16 16:00:03 -04:00
|
|
|
FPose pose = getRawPose();
|
2017-09-02 11:20:17 -04:00
|
|
|
FVector tv = src.matProdRowVect(pose);
|
2017-03-11 14:30:31 -05:00
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
double val;
|
|
|
|
if (index <2) {
|
|
|
|
val = _valArray[index];
|
2017-08-30 20:05:47 -04:00
|
|
|
} else if (index == 2) {
|
2017-08-27 05:18:12 -07:00
|
|
|
val = _isZero;
|
2017-08-30 20:05:47 -04:00
|
|
|
} else if (index == 3) {
|
2017-08-27 05:18:12 -07:00
|
|
|
val = _pixel1OffSetX;
|
2017-08-30 20:05:47 -04:00
|
|
|
} else {
|
2017-08-27 05:18:12 -07:00
|
|
|
val = _pixel2OffSetX;
|
|
|
|
}
|
|
|
|
|
|
|
|
dest._x = (val + tv._x)
|
2017-04-01 18:01:38 -04:00
|
|
|
* _centerVector._x / (_centerVector._y * tv._z);
|
|
|
|
dest._y = (tv._y * _centerVector._x) / (_centerVector._z * tv._z);
|
2017-03-11 14:30:31 -05:00
|
|
|
dest._z = tv._z;
|
|
|
|
return dest;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:18:12 -07:00
|
|
|
void CViewport::getRelativeXCenterPixels(double *v1, double *v2, double *v3, double *v4) {
|
2017-04-01 18:01:38 -04:00
|
|
|
*v1 = _centerVector._x / _centerVector._y;
|
|
|
|
*v2 = _centerVector._x / _centerVector._z;
|
2017-08-27 05:18:12 -07:00
|
|
|
*v3 = _pixel1OffSetX;
|
|
|
|
*v4 = _pixel2OffSetX;
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-04-16 15:40:30 -04:00
|
|
|
void CViewport::reset() {
|
2017-04-16 21:46:36 -04:00
|
|
|
_rawPose.copyFrom(_orientation);
|
2017-04-16 16:00:03 -04:00
|
|
|
_rawPose._vector = _position;
|
2017-08-16 19:44:11 -07:00
|
|
|
_currentPose = _rawPose.inverseTransform();
|
2017-08-27 05:18:12 -07:00
|
|
|
_poseUpToDate = true;
|
2017-03-11 14:30:31 -05:00
|
|
|
|
2017-04-01 18:01:38 -04:00
|
|
|
_center = FPoint((double)_width * 0.5, (double)_height * 0.5);
|
|
|
|
_centerVector._x = MIN(_center._x, _center._y);
|
2018-05-24 05:58:57 -07:00
|
|
|
_centerVector._y = tan(Common::deg2rad<double>(_centerYAngleDegrees));
|
|
|
|
_centerVector._z = tan(Common::deg2rad<double>(_centerZAngleDegrees));
|
2016-07-17 23:18:06 -04:00
|
|
|
}
|
|
|
|
|
2017-04-16 21:46:36 -04:00
|
|
|
const FMatrix &CViewport::getOrientation() const {
|
|
|
|
return _orientation;
|
2016-07-17 21:26:03 -04:00
|
|
|
}
|
|
|
|
|
2017-08-30 20:05:47 -04:00
|
|
|
} // End of namespace Titanic
|