Created a free look utility which only works on win32 right now. It lets the user fly around with the mouse and keyboard. Had to add some ugly matrix functions to the math utilities.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3005 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
donkopunchstania
2009-04-19 10:10:45 +00:00
parent b4c22390ac
commit 93348abc18
11 changed files with 303 additions and 14 deletions

View File

@ -20,6 +20,8 @@
#include "Common.h"
#include "MathUtil.h"
#include <cmath>
static u32 saved_sse_state = _mm_getcsr();
static const u32 default_sse_state = _mm_getcsr();
@ -40,3 +42,106 @@ void SaveSSEState()
{
saved_sse_state = _mm_getcsr();
}
void MatrixMul(int n, const float *a, const float *b, float *result)
{
for(int i = 0; i < n; ++i) {
for(int j= 0; j < n; ++j) {
float temp = 0;
for(int k = 0; k < n; ++k) {
temp += a[i * n + k] * b[k * n + j];
}
result[i * n + j] = temp;
}
}
}
void Matrix33::LoadIdentity(Matrix33 &mtx)
{
memset(mtx.data, 0, sizeof(mtx.data));
mtx.data[0] = 1.0f;
mtx.data[4] = 1.0f;
mtx.data[8] = 1.0f;
}
void Matrix33::RotateX(Matrix33 &mtx, float rad)
{
float s = sin(rad);
float c = cos(rad);
memset(mtx.data, 0, sizeof(mtx.data));
mtx.data[0] = 1;
mtx.data[4] = c;
mtx.data[5] = -s;
mtx.data[7] = s;
mtx.data[8] = c;
}
void Matrix33::RotateY(Matrix33 &mtx, float rad)
{
float s = sin(rad);
float c = cos(rad);
memset(mtx.data, 0, sizeof(mtx.data));
mtx.data[0] = c;
mtx.data[2] = s;
mtx.data[4] = 1;
mtx.data[6] = -s;
mtx.data[8] = c;
}
void Matrix33::Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result)
{
MatrixMul(3, a.data, b.data, result.data);
}
void Matrix33::Multiply(const Matrix33 &a, const float vec[3], float result[3])
{
for(int i = 0; i < 3; ++i) {
result[i] = 0;
for(int k = 0; k < 3; ++k) {
result[i] += a.data[i * 3 + k] * vec[k];
}
}
}
void Matrix44::LoadIdentity(Matrix44 &mtx)
{
memset(mtx.data, 0, sizeof(mtx.data));
mtx.data[0] = 1.0f;
mtx.data[5] = 1.0f;
mtx.data[10] = 1.0f;
mtx.data[15] = 1.0f;
}
void Matrix44::LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33)
{
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
mtx.data[i * 4 + j] = m33.data[i * 3 + j];
}
}
for(int i = 0; i < 3; ++i) {
mtx.data[i * 4 + 3] = 0;
mtx.data[i + 12] = 0;
}
mtx.data[15] = 1.0f;
}
void Matrix44::Set(Matrix44 &mtx, const float mtxArray[16])
{
for(int i = 0; i < 16; ++i) {
mtx.data[i] = mtxArray[i];
}
}
void Matrix44::Translate(Matrix44 &mtx, const float vec[3])
{
LoadIdentity(mtx);
mtx.data[3] = vec[0];
mtx.data[7] = vec[1];
mtx.data[11] = vec[2];
}
void Matrix44::Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result)
{
MatrixMul(4, a.data, b.data, result.data);
}

View File

@ -36,4 +36,36 @@ void LoadDefaultSSEState();
#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
// ugly matrix implementation
class Matrix33
{
public:
static void LoadIdentity(Matrix33 &mtx);
// set mtx to be a rotation matrix around the x axis
static void RotateX(Matrix33 &mtx, float rad);
// set mtx to be a rotation matrix around the y axis
static void RotateY(Matrix33 &mtx, float rad);
// set result = a x b
static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result);
static void Multiply(const Matrix33 &a, const float vec[3], float result[3]);
float data[9];
};
class Matrix44
{
public:
static void LoadIdentity(Matrix44 &mtx);
static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33);
static void Set(Matrix44 &mtx, const float mtxArray[16]);
static void Translate(Matrix44 &mtx, const float vec[3]);
static void Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result);
float data[16];
};
#endif // _MATH_UTIL_H_

View File

@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "MathUtil.h"
#include "Profiler.h"
#include <cmath>
@ -45,6 +46,11 @@ static int nNormalMatricesChanged[2]; // min,max
static int nPostTransformMatricesChanged[2]; // min,max
static int nLightsChanged[2]; // min,max
static Matrix33 s_viewRotationMatrix;
static Matrix33 s_viewInvRotationMatrix;
static float s_fViewTranslationVector[3];
static float s_fViewRotation[2];
void UpdateViewport();
void VertexShaderManager::Init()
@ -59,6 +65,8 @@ void VertexShaderManager::Init()
memset(&xfregs, 0, sizeof(xfregs));
memset(xfmem, 0, sizeof(xfmem));
ResetView();
}
void VertexShaderManager::Shutdown()
@ -69,7 +77,7 @@ void VertexShaderManager::Shutdown()
// =======================================================================================
// Syncs the shader constant buffers with xfmem
// ----------------
void VertexShaderManager::SetConstants(bool proj_hax_1,bool SMG_hack)
void VertexShaderManager::SetConstants(bool proj_hax_1,bool SMG_hack, bool freeLook)
{
//nTransformMatricesChanged[0] = 0; nTransformMatricesChanged[1] = 256;
//nNormalMatricesChanged[0] = 0; nNormalMatricesChanged[1] = 96;
@ -293,10 +301,29 @@ void VertexShaderManager::SetConstants(bool proj_hax_1,bool SMG_hack)
}
PRIM_LOG("Projection: %f %f %f %f %f %f\n", xfregs.rawProjection[0], xfregs.rawProjection[1], xfregs.rawProjection[2], xfregs.rawProjection[3], xfregs.rawProjection[4], xfregs.rawProjection[5]);
SetVSConstant4fv(C_PROJECTION, &g_fProjectionMatrix[0]);
SetVSConstant4fv(C_PROJECTION+1, &g_fProjectionMatrix[4]);
SetVSConstant4fv(C_PROJECTION+2, &g_fProjectionMatrix[8]);
SetVSConstant4fv(C_PROJECTION+3, &g_fProjectionMatrix[12]);
if (freeLook) {
Matrix44 mtxA;
Matrix44 mtxB;
Matrix44 viewMtx;
Matrix44::Translate(mtxA, s_fViewTranslationVector);
Matrix44::LoadMatrix33(mtxB, s_viewRotationMatrix);
Matrix44::Multiply(mtxB, mtxA, viewMtx); // view = rotation x translation
Matrix44::Set(mtxB, g_fProjectionMatrix);
Matrix44::Multiply(mtxB, viewMtx, mtxA); // mtxA = projection x view
SetVSConstant4fv(C_PROJECTION, &mtxA.data[0]);
SetVSConstant4fv(C_PROJECTION+1, &mtxA.data[4]);
SetVSConstant4fv(C_PROJECTION+2, &mtxA.data[8]);
SetVSConstant4fv(C_PROJECTION+3, &mtxA.data[12]);
}
else {
SetVSConstant4fv(C_PROJECTION, &g_fProjectionMatrix[0]);
SetVSConstant4fv(C_PROJECTION+1, &g_fProjectionMatrix[4]);
SetVSConstant4fv(C_PROJECTION+2, &g_fProjectionMatrix[8]);
SetVSConstant4fv(C_PROJECTION+3, &g_fProjectionMatrix[12]);
}
}
}
@ -430,3 +457,46 @@ void VertexShaderManager::SetMaterialColor(int index, u32 data)
s_fMaterials[ind++] = ((data>>8)&0xFF)/255.0f;
s_fMaterials[ind] = ((data)&0xFF)/255.0f;
}
void VertexShaderManager::TranslateView(float x, float y)
{
float result[3];
float vector[3] = { x,0,y };
Matrix33::Multiply(s_viewInvRotationMatrix, vector, result);
for(int i = 0; i < 3; i++) {
s_fViewTranslationVector[i] += result[i];
}
bProjectionChanged = true;
}
void VertexShaderManager::RotateView(float x, float y)
{
s_fViewRotation[0] += x;
s_fViewRotation[1] += y;
Matrix33 mx;
Matrix33 my;
Matrix33::RotateX(mx, s_fViewRotation[1]);
Matrix33::RotateY(my, s_fViewRotation[0]);
Matrix33::Multiply(mx, my, s_viewRotationMatrix);
// reverse rotation
Matrix33::RotateX(mx, -s_fViewRotation[1]);
Matrix33::RotateY(my, -s_fViewRotation[0]);
Matrix33::Multiply(my, mx, s_viewInvRotationMatrix);
bProjectionChanged = true;
}
void VertexShaderManager::ResetView()
{
memset(s_fViewTranslationVector, 0, sizeof(s_fViewTranslationVector));
Matrix33::LoadIdentity(s_viewRotationMatrix);
Matrix33::LoadIdentity(s_viewInvRotationMatrix);
s_fViewRotation[0] = s_fViewRotation[1] = 0.0f;
bProjectionChanged = true;
}

View File

@ -28,7 +28,7 @@ public:
static void Shutdown();
// constant management
static void SetConstants(bool proj_hax_1, bool SMG_hack);
static void SetConstants(bool proj_hax_1, bool SMG_hack, bool freeLook);
static void SetViewport(float* _Viewport);
static void SetViewportChanged();
@ -37,6 +37,10 @@ public:
static void SetTexMatrixChangedA(u32 Value);
static void SetTexMatrixChangedB(u32 Value);
static void SetMaterialColor(int index, u32 data);
static void TranslateView(float x, float y);
static void RotateView(float x, float y);
static void ResetView();
};
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4);