EMI: Refactor to use a matrix for the camera.
This commit is contained in:
parent
94dd10cb11
commit
ff9f26981c
10 changed files with 109 additions and 93 deletions
|
@ -47,7 +47,7 @@ namespace Grim {
|
|||
|
||||
GfxBase::GfxBase() :
|
||||
_renderBitmaps(true), _renderZBitmaps(true), _shadowModeActive(false),
|
||||
_currentPos(0, 0, 0), _currentQuat(0, 0, 0, 1), _dimLevel(0.0f),
|
||||
_currentPos(0, 0, 0), _dimLevel(0.0f),
|
||||
_screenWidth(0), _screenHeight(0), _isFullscreen(false),
|
||||
_scaleW(1.0f), _scaleH(1.0f), _currentShadowArray(nullptr),
|
||||
_shadowColorR(255), _shadowColorG(255), _shadowColorB(255) {
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
|
||||
virtual void setupCameraFrustum(float fov, float nclip, float fclip) = 0;
|
||||
virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest, float roll) = 0;
|
||||
virtual void positionCamera(const Math::Vector3d &pos, const Math::Matrix4 &rot) = 0;
|
||||
|
||||
virtual Math::Matrix4 getModelView() = 0;
|
||||
virtual Math::Matrix4 getProjection() = 0;
|
||||
|
@ -299,7 +300,7 @@ protected:
|
|||
bool _shadowModeActive;
|
||||
Graphics::PixelFormat _pixelFormat;
|
||||
Math::Vector3d _currentPos;
|
||||
Math::Quaternion _currentQuat;
|
||||
Math::Matrix4 _currentRot;
|
||||
float _dimLevel;
|
||||
};
|
||||
|
||||
|
|
|
@ -240,23 +240,22 @@ void GfxOpenGL::setupCameraFrustum(float fov, float nclip, float fclip) {
|
|||
}
|
||||
|
||||
void GfxOpenGL::positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest, float roll) {
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
glScaled(1, 1, -1);
|
||||
Math::Vector3d up_vec(0, 0, 1);
|
||||
|
||||
_currentPos = pos;
|
||||
_currentQuat = Math::Quaternion(interest.x(), interest.y(), interest.z(), roll);
|
||||
} else {
|
||||
Math::Vector3d up_vec(0, 0, 1);
|
||||
glRotatef(roll, 0, 0, -1);
|
||||
|
||||
glRotatef(roll, 0, 0, -1);
|
||||
if (pos.x() == interest.x() && pos.y() == interest.y())
|
||||
up_vec = Math::Vector3d(0, 1, 0);
|
||||
|
||||
if (pos.x() == interest.x() && pos.y() == interest.y())
|
||||
up_vec = Math::Vector3d(0, 1, 0);
|
||||
Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
|
||||
glMultMatrixf(lookMatrix.getData());
|
||||
glTranslated(-pos.x(), -pos.y(), -pos.z());
|
||||
}
|
||||
|
||||
Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
|
||||
glMultMatrixf(lookMatrix.getData());
|
||||
glTranslated(-pos.x(), -pos.y(), -pos.z());
|
||||
}
|
||||
void GfxOpenGL::positionCamera(const Math::Vector3d &pos, const Math::Matrix4 &rot) {
|
||||
glScaled(1, 1, -1);
|
||||
_currentPos = pos;
|
||||
_currentRot = rot;
|
||||
}
|
||||
|
||||
Math::Matrix4 GfxOpenGL::getModelView() {
|
||||
|
@ -266,8 +265,7 @@ Math::Matrix4 GfxOpenGL::getModelView() {
|
|||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
|
||||
Math::Matrix4 worldRot = _currentQuat.toMatrix();
|
||||
glMultMatrixf(worldRot.getData());
|
||||
glMultMatrixf(_currentRot.getData());
|
||||
glTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, modelView.getData());
|
||||
|
@ -508,7 +506,7 @@ void GfxOpenGL::getActorScreenBBox(const Actor *actor, Common::Point &p1, Common
|
|||
// Set up the camera coordinate system
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
Math::Matrix4 worldRot = _currentQuat.toMatrix();
|
||||
Math::Matrix4 worldRot = _currentRot;
|
||||
glMultMatrixf(worldRot.getData());
|
||||
glTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
|
||||
|
@ -568,8 +566,7 @@ void GfxOpenGL::startActorDraw(const Actor *actor) {
|
|||
|
||||
if (g_grim->getGameType() == GType_MONKEY4 && !actor->isInOverworld()) {
|
||||
// Apply the view transform.
|
||||
Math::Matrix4 worldRot = _currentQuat.toMatrix();
|
||||
glMultMatrixf(worldRot.getData());
|
||||
glMultMatrixf(_currentRot.getData());
|
||||
glTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
}
|
||||
|
||||
|
@ -684,8 +681,7 @@ void GfxOpenGL::drawShadowPlanes() {
|
|||
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
// Apply the view transform.
|
||||
Math::Matrix4 worldRot = _currentQuat.toMatrix();
|
||||
glMultMatrixf(worldRot.getData());
|
||||
glMultMatrixf(_currentRot.getData());
|
||||
glTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
|
||||
void setupCameraFrustum(float fov, float nclip, float fclip) override;
|
||||
void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest, float roll) override;
|
||||
void positionCamera(const Math::Vector3d &pos, const Math::Matrix4 &rot) override;
|
||||
|
||||
Math::Matrix4 getModelView() override;
|
||||
Math::Matrix4 getProjection() override;
|
||||
|
|
|
@ -437,39 +437,39 @@ void GfxOpenGLS::setupCameraFrustum(float fov, float nclip, float fclip) {
|
|||
}
|
||||
|
||||
void GfxOpenGLS::positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest, float roll) {
|
||||
Math::Matrix4 viewMatrix = makeRotationMatrix(Math::Angle(roll), Math::Vector3d(0, 0, 1));
|
||||
Math::Vector3d up_vec(0, 0, 1);
|
||||
|
||||
if (pos.x() == interest.x() && pos.y() == interest.y())
|
||||
up_vec = Math::Vector3d(0, 1, 0);
|
||||
|
||||
Math::Matrix4 lookMatrix = makeLookMatrix(pos, interest, up_vec);
|
||||
|
||||
_viewMatrix = viewMatrix * lookMatrix;
|
||||
_viewMatrix.transpose();
|
||||
}
|
||||
|
||||
void GfxOpenGLS::positionCamera(const Math::Vector3d &pos, const Math::Matrix4 &rot) {
|
||||
Math::Matrix4 projMatrix = _projMatrix;
|
||||
projMatrix.transpose();
|
||||
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
_currentPos = pos;
|
||||
_currentQuat = Math::Quaternion(interest.x(), interest.y(), interest.z(), roll);
|
||||
_currentPos = pos;
|
||||
_currentRot = rot;
|
||||
|
||||
Math::Matrix4 invertZ;
|
||||
invertZ(2, 2) = -1.0f;
|
||||
Math::Matrix4 invertZ;
|
||||
invertZ(2, 2) = -1.0f;
|
||||
|
||||
Math::Matrix4 viewMatrix = _currentQuat.toMatrix();
|
||||
viewMatrix.transpose();
|
||||
Math::Matrix4 viewMatrix = _currentRot;
|
||||
viewMatrix.transpose();
|
||||
|
||||
Math::Matrix4 camPos;
|
||||
camPos(0, 3) = -_currentPos.x();
|
||||
camPos(1, 3) = -_currentPos.y();
|
||||
camPos(2, 3) = -_currentPos.z();
|
||||
Math::Matrix4 camPos;
|
||||
camPos(0, 3) = -_currentPos.x();
|
||||
camPos(1, 3) = -_currentPos.y();
|
||||
camPos(2, 3) = -_currentPos.z();
|
||||
|
||||
_viewMatrix = invertZ * viewMatrix * camPos;
|
||||
_mvpMatrix = projMatrix * _viewMatrix;
|
||||
_viewMatrix.transpose();
|
||||
} else {
|
||||
Math::Matrix4 viewMatrix = makeRotationMatrix(Math::Angle(roll), Math::Vector3d(0, 0, 1));
|
||||
Math::Vector3d up_vec(0, 0, 1);
|
||||
|
||||
if (pos.x() == interest.x() && pos.y() == interest.y())
|
||||
up_vec = Math::Vector3d(0, 1, 0);
|
||||
|
||||
Math::Matrix4 lookMatrix = makeLookMatrix(pos, interest, up_vec);
|
||||
|
||||
_viewMatrix = viewMatrix * lookMatrix;
|
||||
_viewMatrix.transpose();
|
||||
}
|
||||
_viewMatrix = invertZ * viewMatrix * camPos;
|
||||
_mvpMatrix = projMatrix * _viewMatrix;
|
||||
_viewMatrix.transpose();
|
||||
}
|
||||
|
||||
|
||||
|
@ -478,7 +478,7 @@ Math::Matrix4 GfxOpenGLS::getModelView() {
|
|||
Math::Matrix4 invertZ;
|
||||
invertZ(2, 2) = -1.0f;
|
||||
|
||||
Math::Matrix4 viewMatrix = _currentQuat.toMatrix();
|
||||
Math::Matrix4 viewMatrix = _currentRot;
|
||||
viewMatrix.transpose();
|
||||
|
||||
Math::Matrix4 camPos;
|
||||
|
@ -594,7 +594,7 @@ void GfxOpenGLS::getActorScreenBBox(const Actor *actor, Common::Point &p1, Commo
|
|||
bboxPos = bboxPos + actor->getWorldPos();
|
||||
|
||||
// Set up the camera coordinate system
|
||||
Math::Matrix4 modelView = _currentQuat.toMatrix();
|
||||
Math::Matrix4 modelView = _currentRot;
|
||||
Math::Matrix4 zScale;
|
||||
zScale.setValue(2, 2, -1.0);
|
||||
modelView = modelView * zScale;
|
||||
|
@ -668,7 +668,7 @@ void GfxOpenGLS::startActorDraw(const Actor *actor) {
|
|||
|
||||
Math::Vector4d color(1.0f, 1.0f, 1.0f, actor->getEffectiveAlpha());
|
||||
|
||||
const Math::Matrix4 &viewRot = _currentQuat.toMatrix();
|
||||
const Math::Matrix4 &viewRot = _currentRot;
|
||||
Math::Matrix4 modelMatrix = actor->getFinalMatrix();
|
||||
|
||||
Math::Matrix4 normalMatrix = viewMatrix * modelMatrix;
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
virtual bool supportsShaders() override { return true; }
|
||||
virtual void setupCameraFrustum(float fov, float nclip, float fclip) override;
|
||||
virtual void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest, float roll) override;
|
||||
virtual void positionCamera(const Math::Vector3d &pos, const Math::Matrix4 &rot) override;
|
||||
|
||||
virtual Math::Matrix4 getModelView() override;
|
||||
virtual Math::Matrix4 getProjection() override;
|
||||
|
|
|
@ -125,23 +125,22 @@ void GfxTinyGL::setupCameraFrustum(float fov, float nclip, float fclip) {
|
|||
}
|
||||
|
||||
void GfxTinyGL::positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest, float roll) {
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
tglScalef(1.0, 1.0, -1.0);
|
||||
Math::Vector3d up_vec(0, 0, 1);
|
||||
|
||||
_currentPos = pos;
|
||||
_currentQuat = Math::Quaternion(interest.x(), interest.y(), interest.z(), roll);
|
||||
} else {
|
||||
Math::Vector3d up_vec(0, 0, 1);
|
||||
tglRotatef(roll, 0, 0, -1);
|
||||
|
||||
tglRotatef(roll, 0, 0, -1);
|
||||
if (pos.x() == interest.x() && pos.y() == interest.y())
|
||||
up_vec = Math::Vector3d(0, 1, 0);
|
||||
|
||||
if (pos.x() == interest.x() && pos.y() == interest.y())
|
||||
up_vec = Math::Vector3d(0, 1, 0);
|
||||
Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
|
||||
tglMultMatrixf(lookMatrix.getData());
|
||||
tglTranslatef(-pos.x(), -pos.y(), -pos.z());
|
||||
}
|
||||
|
||||
Math::Matrix4 lookMatrix = Math::makeLookAtMatrix(pos, interest, up_vec);
|
||||
tglMultMatrixf(lookMatrix.getData());
|
||||
tglTranslatef(-pos.x(), -pos.y(), -pos.z());
|
||||
}
|
||||
void GfxTinyGL::positionCamera(const Math::Vector3d &pos, const Math::Matrix4 &rot) {
|
||||
tglScalef(1.0, 1.0, -1.0);
|
||||
_currentPos = pos;
|
||||
_currentRot = rot;
|
||||
}
|
||||
|
||||
Math::Matrix4 GfxTinyGL::getModelView() {
|
||||
|
@ -151,8 +150,7 @@ Math::Matrix4 GfxTinyGL::getModelView() {
|
|||
tglMatrixMode(TGL_MODELVIEW);
|
||||
tglPushMatrix();
|
||||
|
||||
Math::Matrix4 worldRot = _currentQuat.toMatrix();
|
||||
tglMultMatrixf(worldRot.getData());
|
||||
tglMultMatrixf(_currentRot.getData());
|
||||
tglTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
|
||||
tglGetFloatv(TGL_MODELVIEW_MATRIX, modelView.getData());
|
||||
|
@ -448,7 +446,7 @@ void GfxTinyGL::getActorScreenBBox(const Actor *actor, Common::Point &p1, Common
|
|||
tglPushMatrix();
|
||||
|
||||
// Apply the view transform.
|
||||
Math::Matrix4 worldRot = _currentQuat.toMatrix();
|
||||
Math::Matrix4 worldRot = _currentRot;
|
||||
tglMultMatrixf(worldRot.getData());
|
||||
tglTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
|
||||
|
@ -508,8 +506,7 @@ void GfxTinyGL::startActorDraw(const Actor *actor) {
|
|||
|
||||
if (g_grim->getGameType() == GType_MONKEY4 && !actor->isInOverworld()) {
|
||||
// Apply the view transform.
|
||||
Math::Matrix4 worldRot = _currentQuat.toMatrix();
|
||||
tglMultMatrixf(worldRot.getData());
|
||||
tglMultMatrixf(_currentRot.getData());
|
||||
tglTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
}
|
||||
|
||||
|
@ -608,8 +605,7 @@ void GfxTinyGL::drawShadowPlanes() {
|
|||
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
// Apply the view transform.
|
||||
Math::Matrix4 worldRot = _currentQuat.toMatrix();
|
||||
tglMultMatrixf(worldRot.getData());
|
||||
tglMultMatrixf(_currentRot.getData());
|
||||
tglTranslatef(-_currentPos.x(), -_currentPos.y(), -_currentPos.z());
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
|
||||
void setupCameraFrustum(float fov, float nclip, float fclip) override;
|
||||
void positionCamera(const Math::Vector3d &pos, const Math::Vector3d &interest, float roll) override;
|
||||
void positionCamera(const Math::Vector3d &pos, const Math::Matrix4 &rot) override;
|
||||
|
||||
Math::Matrix4 getModelView() override;
|
||||
Math::Matrix4 getProjection() override;
|
||||
|
|
|
@ -381,18 +381,18 @@ void Set::Setup::loadBinary(Common::SeekableReadStream *data) {
|
|||
_bkgndZBm = nullptr;
|
||||
_bkgndBm = loadBackground(fileName);
|
||||
|
||||
char v[4 * 4];
|
||||
data->read(v, 4 * 3);
|
||||
char v[sizeof(float) * 4];
|
||||
data->read(v, sizeof(float) * 3);
|
||||
_pos = Math::Vector3d::getVector3d(v);
|
||||
|
||||
data->read(v, 4 * 3);
|
||||
_interest = Math::Vector3d::getVector3d(v);
|
||||
data->read(v, sizeof(float) * 4);
|
||||
Math::Quaternion q(get_float(v), get_float(v + 4), get_float(v + 8), get_float(v + 12));
|
||||
q.toMatrix(_rot);
|
||||
|
||||
data->read(v, 4 * 4);
|
||||
_roll = get_float(v);
|
||||
_fov = get_float(v + 4);
|
||||
_nclip = get_float(v + 8);
|
||||
_fclip = get_float(v + 12);
|
||||
data->read(v, sizeof(float) * 3);
|
||||
_fov = get_float(v);
|
||||
_nclip = get_float(v + 4);
|
||||
_fclip = get_float(v + 8);
|
||||
|
||||
delete[] fileName;
|
||||
}
|
||||
|
@ -416,8 +416,17 @@ void Set::Setup::saveState(SaveGame *savedState) const {
|
|||
}
|
||||
|
||||
savedState->writeVector3d(_pos);
|
||||
savedState->writeVector3d(_interest);
|
||||
savedState->writeFloat(_roll);
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
// Get the rotation matrix as a quaternion and write it out
|
||||
Math::Quaternion q(_rot);
|
||||
savedState->writeFloat(q.x());
|
||||
savedState->writeFloat(q.y());
|
||||
savedState->writeFloat(q.z());
|
||||
savedState->writeFloat(q.w());
|
||||
} else {
|
||||
savedState->writeVector3d(_interest);
|
||||
savedState->writeFloat(_roll);
|
||||
}
|
||||
savedState->writeFloat(_fov);
|
||||
savedState->writeFloat(_nclip);
|
||||
savedState->writeFloat(_fclip);
|
||||
|
@ -430,8 +439,17 @@ bool Set::Setup::restoreState(SaveGame *savedState) {
|
|||
_bkgndZBm = Bitmap::getPool().getObject(savedState->readLESint32());
|
||||
|
||||
_pos = savedState->readVector3d();
|
||||
_interest = savedState->readVector3d();
|
||||
_roll = savedState->readFloat();
|
||||
if (g_grim->getGameType() == GType_MONKEY4) {
|
||||
float x = savedState->readFloat();
|
||||
float y = savedState->readFloat();
|
||||
float z = savedState->readFloat();
|
||||
float w = savedState->readFloat();
|
||||
Math::Quaternion q(x, y, z, w);
|
||||
_rot = q.toMatrix();
|
||||
} else {
|
||||
_interest = savedState->readVector3d();
|
||||
_roll = savedState->readFloat();
|
||||
}
|
||||
_fov = savedState->readFloat();
|
||||
_nclip = savedState->readFloat();
|
||||
_fclip = savedState->readFloat();
|
||||
|
@ -656,7 +674,7 @@ void SetShadow::restoreState(SaveGame *savedState) {
|
|||
}
|
||||
|
||||
void Set::Setup::setupCamera() const {
|
||||
// Ignore nclip_ and fclip_ for now. This fixes:
|
||||
// Ignore nclip_ and fclip_ for now in Grim. This fixes:
|
||||
// (a) Nothing was being displayed in the Land of the Living
|
||||
// diner because lr.set set nclip to 0.
|
||||
// (b) The zbuffers for setups with different nclip or
|
||||
|
@ -664,15 +682,13 @@ void Set::Setup::setupCamera() const {
|
|||
// are important at some point, we'll need to modify the
|
||||
// zbuffer transformation in bitmap.cpp to take nclip_ and
|
||||
// fclip_ into account.
|
||||
float nclip = this->_nclip;
|
||||
float fclip = this->_fclip;
|
||||
if (g_grim->getGameType() != GType_MONKEY4) {
|
||||
nclip = 0.01f;
|
||||
fclip = 3276.8f;
|
||||
if (g_grim->getGameType() == GType_GRIM) {
|
||||
g_driver->setupCameraFrustum(_fov, 0.01f, 3276.8f);
|
||||
g_driver->positionCamera(_pos, _interest, _roll);
|
||||
} else {
|
||||
g_driver->setupCameraFrustum(_fov, _nclip, _fclip);
|
||||
g_driver->positionCamera(_pos, _rot);
|
||||
}
|
||||
|
||||
g_driver->setupCameraFrustum(_fov, nclip, fclip);
|
||||
g_driver->positionCamera(_pos, _interest, _roll);
|
||||
}
|
||||
|
||||
class Sorter {
|
||||
|
|
|
@ -112,6 +112,7 @@ public:
|
|||
ObjectState *addObjectState(int setupID, ObjectState::Position pos, const char *bitmap, const char *zbitmap, bool transparency);
|
||||
ObjectState *findState(const Common::String &filename);
|
||||
|
||||
// Setups contain the camera information and background for all views in a Set
|
||||
struct Setup { // Camera setup data
|
||||
void load(Set *set, int id, TextSplitter &ts);
|
||||
void loadBinary(Common::SeekableReadStream *data);
|
||||
|
@ -121,7 +122,10 @@ public:
|
|||
|
||||
Common::String _name;
|
||||
Bitmap::Ptr _bkgndBm, _bkgndZBm;
|
||||
|
||||
// Camera settings
|
||||
Math::Vector3d _pos, _interest;
|
||||
Math::Matrix4 _rot;
|
||||
float _roll, _fov, _nclip, _fclip;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue