Browse Source

Added some useful info on perspective transformations based on research. Also added a math source file with a custom rotation matrix routine, which isn't quite working as it should yet.

master
Nico de Poel 3 years ago
parent
commit
78b8585093
  1. 3
      CMakeLists.txt
  2. 41
      main.c
  3. 34
      qmath.c
  4. 8
      qmath.h

3
CMakeLists.txt

@ -11,7 +11,8 @@ project(
HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk"
) )
psn00bsdk_add_executable(template STATIC main.c)
file(GLOB _sources *.c)
psn00bsdk_add_executable(template STATIC ${_sources})
psn00bsdk_target_incbin(template PRIVATE mdl_player player.ps1mdl) psn00bsdk_target_incbin(template PRIVATE mdl_player player.ps1mdl)
psn00bsdk_target_incbin(template PRIVATE tim_player_f player_f.tim) psn00bsdk_target_incbin(template PRIVATE tim_player_f player_f.tim)

41
main.c

@ -25,6 +25,7 @@
#include <psxgpu.h> #include <psxgpu.h>
#include <inline_c.h> #include <inline_c.h>
#include "ps1mdl.h" #include "ps1mdl.h"
#include "qmath.h"
#define OTLEN 1024 #define OTLEN 1024
@ -213,7 +214,7 @@ void init(void)
FntLoad(960, 0); FntLoad(960, 0);
// Open up a test font text stream of 100 characters // Open up a test font text stream of 100 characters
FntOpen(0, 8, 320, 224, 0, 100);
FntOpen(0, 8, SCREENWIDTH, SCREENHEIGHT, 0, 200);
nextpri = primbuff[0]; nextpri = primbuff[0];
@ -229,9 +230,13 @@ void init(void)
loadModel(mdl_quaddama, &quadModel); loadModel(mdl_quaddama, &quadModel);
loadSkin(tim_quaddama_f, tim_quaddama_b, &quadSkin); loadSkin(tim_quaddama_f, tim_quaddama_b, &quadSkin);
// Perspective calculations are quite simple, with Go = GeomOffset and Gs = GeomScreen, view coordinates are transformed to screen coordinates as such:
// x' = vx * Gs / vz + Go.x
// y' = vy * Gs / vz + Go.y
// z' = (vz - 1) / 4 (depth does not appear to be affected by any parameters)
InitGeom(); InitGeom();
gte_SetGeomOffset(SCREENWIDTH >> 1, SCREENHEIGHT >> 1); gte_SetGeomOffset(SCREENWIDTH >> 1, SCREENHEIGHT >> 1);
gte_SetGeomScreen(180); // Screen depth for FOV control. Essentially the Z position of the vanishing point.
gte_SetGeomScreen(180); // Screen depth for FOV control. Determines the distance of the camera to the near plane.
// Set texture page for the entire drawing environment. Nice in some cases perhaps, but not what we need. // Set texture page for the entire drawing environment. Nice in some cases perhaps, but not what we need.
//draw[0].tpage = getTPage(playerFrontTex.mode & 0x3, 0, playerFrontTex.prect->x, playerFrontTex.prect->y); //draw[0].tpage = getTPage(playerFrontTex.mode & 0x3, 0, playerFrontTex.prect->x, playerFrontTex.prect->y);
@ -415,7 +420,7 @@ void drawModel(MATRIX *view_matrix, ps1mdl_t *model, ps1skin_t *skin, int frameC
// Model world position and rotation // Model world position and rotation
MATRIX model_mtx; MATRIX model_mtx;
RotMatrix(&model->rotation, &model_mtx);
RotMatrixQ(&model->rotation, &model_mtx);
TransMatrix(&model_mtx, &model->position); TransMatrix(&model_mtx, &model->position);
// Adjust light direction by the model's rotation relative to the world // Adjust light direction by the model's rotation relative to the world
@ -525,13 +530,6 @@ void drawStuff(int counter)
{ {
ClearOTagR(ot[db], OTLEN); ClearOTagR(ot[db], OTLEN);
FntPrint(-1, "Image x %d y %d w %d h %d mode 0x%x\n", playerSkin.front.prect.x, playerSkin.front.prect.y, playerSkin.front.prect.w, playerSkin.front.prect.h, playerSkin.front.mode);
FntPrint(-1, "Model: %d tris, %d verts\n", playerModel.header->triangleCount, playerModel.header->vertexCount);
FntPrint(-1, "Trsf: (%d, %d, %d)\n", outPos.vx, outPos.vy, outPos.vz);
// Draw the last created text stream
FntFlush(-1);
gte_SetBackColor(48, 48, 48); // Ambient light color gte_SetBackColor(48, 48, 48); // Ambient light color
gte_SetColorMatrix(&light_cols); // Light color (up to three different lights) gte_SetColorMatrix(&light_cols); // Light color (up to three different lights)
@ -541,7 +539,7 @@ void drawStuff(int counter)
MATRIX view_matrix; MATRIX view_matrix;
SVECTOR trot = { -cam_rot.vx, -cam_rot.vy, -cam_rot.vz, 0 }; // Inverse camera rotation (in Quake coordinates) SVECTOR trot = { -cam_rot.vx, -cam_rot.vy, -cam_rot.vz, 0 }; // Inverse camera rotation (in Quake coordinates)
VECTOR tpos = { -cam_pos.vx, -cam_pos.vy, -cam_pos.vz }; // Inverse camera position (in Quake coordinates) VECTOR tpos = { -cam_pos.vx, -cam_pos.vy, -cam_pos.vz }; // Inverse camera position (in Quake coordinates)
RotMatrix(&trot, &view_matrix); // Set camera rotation part of the view matrix
RotMatrixQ(&trot, &view_matrix); // Set camera rotation part of the view matrix
ApplyMatrixLV(&view_matrix, &tpos, &tpos); // Apply camera rotation to camera position ApplyMatrixLV(&view_matrix, &tpos, &tpos); // Apply camera rotation to camera position
TransMatrix(&view_matrix, &tpos); // Apply transformed position to the translation part of the view matrix TransMatrix(&view_matrix, &tpos); // Apply transformed position to the translation part of the view matrix
@ -552,6 +550,13 @@ void drawStuff(int counter)
drawModel(&view_matrix, &shamblerModel, &shamblerSkin, counter >> 2); drawModel(&view_matrix, &shamblerModel, &shamblerSkin, counter >> 2);
//drawModel(&view_matrix, &ogreModel, &ogreSkin, counter >> 2); //drawModel(&view_matrix, &ogreModel, &ogreSkin, counter >> 2);
drawModel(&view_matrix, &quadModel, &quadSkin, 0); drawModel(&view_matrix, &quadModel, &quadSkin, 0);
FntPrint(-1, "Camera pos = (%d, %d, %d) rot = (%d, %d, %d)\n", cam_pos.vx, cam_pos.vy, cam_pos.vz, cam_rot.vx, cam_rot.vy, cam_rot.vz);
FntPrint(-1, "Model: %d tris, %d verts\n", playerModel.header->triangleCount, playerModel.header->vertexCount);
FntPrint(-1, "Trsf: (%d, %d, %d)\n", outPos.vx, outPos.vy, outPos.vz);
// Draw the last created text stream
FntFlush(-1);
} }
void handleInput() void handleInput()
@ -566,19 +571,19 @@ void handleInput()
// Determine direction vectors of the camera // Determine direction vectors of the camera
MATRIX cam_mtx; MATRIX cam_mtx;
RotMatrix(&cam_rot, &cam_mtx);
RotMatrixQ(&cam_rot, &cam_mtx);
u_short buttons = *((u_short*)(padBuffer[0]+2)); u_short buttons = *((u_short*)(padBuffer[0]+2));
if (!(buttons & PAD_UP)) if (!(buttons & PAD_UP))
{ {
// Move forward
// Move forward (+Y)
cam_pos.vx += (cam_mtx.m[0][1] * moveSpeed) >> 12; cam_pos.vx += (cam_mtx.m[0][1] * moveSpeed) >> 12;
cam_pos.vy += (cam_mtx.m[1][1] * moveSpeed) >> 12; cam_pos.vy += (cam_mtx.m[1][1] * moveSpeed) >> 12;
cam_pos.vz += (cam_mtx.m[2][1] * moveSpeed) >> 12; cam_pos.vz += (cam_mtx.m[2][1] * moveSpeed) >> 12;
} }
if (!(buttons & PAD_DOWN)) if (!(buttons & PAD_DOWN))
{ {
// Move backward
// Move backward (-Y)
cam_pos.vx -= (cam_mtx.m[0][1] * moveSpeed) >> 12; cam_pos.vx -= (cam_mtx.m[0][1] * moveSpeed) >> 12;
cam_pos.vy -= (cam_mtx.m[1][1] * moveSpeed) >> 12; cam_pos.vy -= (cam_mtx.m[1][1] * moveSpeed) >> 12;
cam_pos.vz -= (cam_mtx.m[2][1] * moveSpeed) >> 12; cam_pos.vz -= (cam_mtx.m[2][1] * moveSpeed) >> 12;
@ -595,28 +600,28 @@ void handleInput()
} }
if (!(buttons & PAD_TRIANGLE)) if (!(buttons & PAD_TRIANGLE))
{ {
// Move up
// Move up (+Z)
cam_pos.vx += (cam_mtx.m[0][2] * moveSpeed) >> 12; cam_pos.vx += (cam_mtx.m[0][2] * moveSpeed) >> 12;
cam_pos.vy += (cam_mtx.m[1][2] * moveSpeed) >> 12; cam_pos.vy += (cam_mtx.m[1][2] * moveSpeed) >> 12;
cam_pos.vz += (cam_mtx.m[2][2] * moveSpeed) >> 12; cam_pos.vz += (cam_mtx.m[2][2] * moveSpeed) >> 12;
} }
if (!(buttons & PAD_CROSS)) if (!(buttons & PAD_CROSS))
{ {
// Move down
// Move down (-Z)
cam_pos.vx -= (cam_mtx.m[0][2] * moveSpeed) >> 12; cam_pos.vx -= (cam_mtx.m[0][2] * moveSpeed) >> 12;
cam_pos.vy -= (cam_mtx.m[1][2] * moveSpeed) >> 12; cam_pos.vy -= (cam_mtx.m[1][2] * moveSpeed) >> 12;
cam_pos.vz -= (cam_mtx.m[2][2] * moveSpeed) >> 12; cam_pos.vz -= (cam_mtx.m[2][2] * moveSpeed) >> 12;
} }
if (!(buttons & PAD_L1)) if (!(buttons & PAD_L1))
{ {
// Strafe left
// Strafe left (-X)
cam_pos.vx -= (cam_mtx.m[0][0] * moveSpeed) >> 12; cam_pos.vx -= (cam_mtx.m[0][0] * moveSpeed) >> 12;
cam_pos.vy -= (cam_mtx.m[1][0] * moveSpeed) >> 12; cam_pos.vy -= (cam_mtx.m[1][0] * moveSpeed) >> 12;
cam_pos.vz -= (cam_mtx.m[2][0] * moveSpeed) >> 12; cam_pos.vz -= (cam_mtx.m[2][0] * moveSpeed) >> 12;
} }
if (!(buttons & PAD_R1)) if (!(buttons & PAD_R1))
{ {
// Strafe right
// Strafe right (+X)
cam_pos.vx += (cam_mtx.m[0][0] * moveSpeed) >> 12; cam_pos.vx += (cam_mtx.m[0][0] * moveSpeed) >> 12;
cam_pos.vy += (cam_mtx.m[1][0] * moveSpeed) >> 12; cam_pos.vy += (cam_mtx.m[1][0] * moveSpeed) >> 12;
cam_pos.vz += (cam_mtx.m[2][0] * moveSpeed) >> 12; cam_pos.vz += (cam_mtx.m[2][0] * moveSpeed) >> 12;

34
qmath.c

@ -0,0 +1,34 @@
#include "qmath.h"
MATRIX *RotMatrixQ(SVECTOR *r, MATRIX *m)
{
short s[3],c[3];
MATRIX tm[3];
s[0] = isin(r->vx); s[1] = isin(r->vy); s[2] = isin(r->vz);
c[0] = icos(r->vx); c[1] = icos(r->vy); c[2] = icos(r->vz);
// mY (roll)
m->m[0][0] = c[1]; m->m[0][1] = 0; m->m[0][2] = s[1];
m->m[1][0] = 0; m->m[1][1] = ONE; m->m[1][2] = 0;
m->m[2][0] = -s[1]; m->m[2][1] = 0; m->m[2][2] = c[1];
// mX (pitch)
tm[0].m[0][0] = ONE; tm[0].m[0][1] = 0; tm[0].m[0][2] = 0;
tm[0].m[1][0] = 0; tm[0].m[1][1] = c[0]; tm[0].m[1][2] = -s[0];
tm[0].m[2][0] = 0; tm[0].m[2][1] = s[0]; tm[0].m[2][2] = c[0];
// mZ (yaw)
tm[1].m[0][0] = c[2]; tm[1].m[0][1] = -s[2]; tm[1].m[0][2] = 0;
tm[1].m[1][0] = s[2]; tm[1].m[1][1] = c[2]; tm[1].m[1][2] = 0;
tm[1].m[2][0] = 0; tm[1].m[2][1] = 0; tm[1].m[2][2] = ONE;
PushMatrix();
MulMatrix0( m, &tm[1], &tm[2] );
MulMatrix0( &tm[2], &tm[0], m );
PopMatrix();
return m;
}

8
qmath.h

@ -0,0 +1,8 @@
#ifndef __QMATH_H__
#define __QMATH_H__
#include <psxgte.h>
MATRIX *RotMatrixQ(SVECTOR *r, MATRIX *m);
#endif // __QMATH_H__
Loading…
Cancel
Save