Is it possible to use SetRotMatrix/SetTransMatrix for geometry and camera at the same time?
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Is it possible to use SetRotMatrix/SetTransMatrix for geometry and camera at the same time?
Hi PSXDEV. I have a small question about SetRotMatrix (SRM) and SetTransMatrix (STM).
In this example i have one SRM and STM for camera (viev.viev) and second for 3d primitive (omtx). But i can't make them work together. So... Is it possible to use SetRotMatrix/SetTransMatrix for geometry and camera at the same time?
► Show Spoiler
-
LameGuy64 Verified
- Psy-Q Enthusiast
- Posts: 388
- Joined: Apr 10, 2013
- I am a: Hobbyist Game Developer
- Motto: Commercial or not, play it!
- PlayStation Model: H2000/7000
- Location: Philippines
- Contact:
I usually just have a pair of vectors for both the camera position and angle and then applying it to a matrix using the first person view matrix logic from my examples featuring a first person style camera.
Putting the relevant code here for easy reference:
To place objects relative to the camera matrix, I do the following matrix calculations:
Object position and rotation must be absolute world-space coordinates. As in, no need to manually translate them relative to camera coordinates beforehand as the logic already does that for you. This method has worked really well for me so far.
If you plan to do a third person view I highly recommend using the LookAt function example I posted sometime ago on this forum. You can use the matrix it generates as the camera view directly.
Putting the relevant code here for easy reference:
Code: Select all
VECTOR cam_pos; // Camera position
SVECTOR cam_rot; // Camera rotation
MATRIX cam_mat; // Camera matrix
VECTOR vec; // Just a temporary
RotMatrix( &cam_rot, &cam_mat );
ApplyMatrixLV( &cam_mat, &cam_pos, &vec );
TransMatrix( &cam_mat, &vec );
SetRotMatrix( &mtx );
SetTransMatrix( &mtx );
< sort your level geometry >
Code: Select all
VECTOR obj_pos; // Object position
SVECTOR obj_rot; // Object rotation
MATRIX obj_mtx; // Object matrix
MATRIX tmp_mtx; // Just a temporary
RotMatrix( &obj_rot, &obj_mtx );
TransMatrix( &obj_mtx, &obj_pos );
// The following 2 lines are only needed for lighting (light_mtx is your light direction matrix)
MulMatrix0( &light_mtx, &obj_mtx, &tmp_mtx );
SetLightMatrix( &tmp_mtx );
// tmp_mtx will be the matrix of the object relative to the camera
CompMatrixLV( &cam_mtx, &obj_mtx, &tmp_mtx );
SetRotMatrix( &tmp_mtx );
SetTransMatrix( &tmp_mtx );
< sort your object >
SetRotMatrix( &mtx ); // Revert back to camera matrix
SetTransMatrix( &mtx ); // (not needed if you're just sorting objects)
If you plan to do a third person view I highly recommend using the LookAt function example I posted sometime ago on this forum. You can use the matrix it generates as the camera view directly.
Please don't forget to include my name if you share my work around. Credit where it is due.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
CompMatrixLV( &cam_mtx, &obj_mtx, &tmp_mtx );
cam_mtx? Not cam_mat? This is fine?
cam_mtx? Not cam_mat? This is fine?
-
LameGuy64 Verified
- Psy-Q Enthusiast
- Posts: 388
- Joined: Apr 10, 2013
- I am a: Hobbyist Game Developer
- Motto: Commercial or not, play it!
- PlayStation Model: H2000/7000
- Location: Philippines
- Contact:
That's just my preferred naming convention. You can name it whatever you want really.
Please don't forget to include my name if you share my work around. Credit where it is due.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Okay, this is code for camera (Looks familiar, doesn't it? :D):
So, my CompMatrixLV would be look like this?
CompMatrixLV(&view.view, &omtx, &tmtx);
Code: Select all
void CalculateCamera() {
// This function simply calculates the viewpoint matrix based on the camera coordinates...
// It must be called on every frame before drawing any objects.
//View handler
GsVIEW2 view;
// Temporary
VECTOR vec;
// Copy the camera (base) matrix for the viewpoint matrix
view.view = Camera.coord2.coord;
view.super = WORLD;
RotMatrix(&Camera.rot, &view.view);
ApplyMatrixLV(&view.view, &Camera.pos, &vec);
TransMatrix(&view.view, &vec);
// This is for geometry
SetRotMatrix(&view.view);
SetTransMatrix(&view.view);
// Set the viewpoint matrix to the GTE
GsSetView2(&view);
}
CompMatrixLV(&view.view, &omtx, &tmtx);
-
LameGuy64 Verified
- Psy-Q Enthusiast
- Posts: 388
- Joined: Apr 10, 2013
- I am a: Hobbyist Game Developer
- Motto: Commercial or not, play it!
- PlayStation Model: H2000/7000
- Location: Philippines
- Contact:
That should do it for the first person camera. I'm not sure how libgs would treat it though as I haven't used that library in a long time as I usually use plain libgte+libgpu for graphics.
Please don't forget to include my name if you share my work around. Credit where it is due.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Code: Select all
CompMatrixLV(&view.view, &omtx, &tmtx);
► Show Spoiler
-
LameGuy64 Verified
- Psy-Q Enthusiast
- Posts: 388
- Joined: Apr 10, 2013
- I am a: Hobbyist Game Developer
- Motto: Commercial or not, play it!
- PlayStation Model: H2000/7000
- Location: Philippines
- Contact:
Ah, looks like things aren't z-sorting right. Nothing to do with matrices at least.
How do you sort TMDs into the ordering table? Also, I see my old lightbulb model .
How do you sort TMDs into the ordering table? Also, I see my old lightbulb model .
Please don't forget to include my name if you share my work around. Credit where it is due.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Using your TMD code and light model for testing (LinkModel + PutObject) :)How do you sort TMDs into the ordering table?
But this 2 boxes - not TMD.
Code: Select all
int Draw3DBoxF4(u_char semitrans, int start_fade_dist, int end_fade_dist, VECTOR scale, VECTOR pos, SVECTOR rot, CVECTOR *color, DIVPOLYGON4 div, POLY_F4 *obj) {
MATRIX lmtx; // Light Matrix
MATRIX omtx; // Object Matrix
MATRIX tmtx; // Temporary
SVECTOR **vp;
int i;
int nclip;
long p, OTz, Flag;
u_char p_count = 6;
/* GTE has 1 matrix register, so it is better to push the
* matrix to preserve the current matrix register. */
PushMatrix();
// Rotate, translate and scale the matrix according to the specified coordinates
RotMatrix(&rot, &omtx);
TransMatrix(&omtx, &pos);
ScaleMatrix(&omtx, &scale);
// tmtx will be the matrix of the object relative to the camera
CompMatrixLV(&view.view, &omtx, &tmtx);
SetRotMatrix(&tmtx);
SetTransMatrix(&tmtx);
vp = v;
NumPrims_local=0;
for (i = 0; i < p_count; i++, obj++, vp += 4) {
obj = (POLY_F4*)myPrimPtr;
nclip = RotAverageNclip4(
vp[0], vp[1], vp[2], vp[3],
(long *)&obj->x0, (long *)&obj->x1,
(long *)&obj->x3, (long *)&obj->x2,
&p, &OTz, &Flag);
if ((nclip > 0) && (OTz > start_fade_dist)) {
SetPolyF4(obj);
color[i].cd = obj->code;
SetSemiTrans(obj, semitrans);
OTc = OTz>>(14-OT_LENGTH);
if (end_fade_dist == 0 || (OTc < end_fade_dist)) {
// High LOD level (subdivided)
if (OTc < (LOD_LV2+(LOD_LV2_DISTANCE))) {
setRGB0(obj, color[i].r, color[i].g, color[i].b);
AddPrim((u_long *)myOT[ActiveBuffer].org, obj);
if (OTc < (LOD_LV1+(LOD_LV1_DISTANCE)))
div.ndiv = 2;
else div.ndiv = 1;
//Our mesh will be divided by 4.
DivideF4(
&vp[0], &vp[1], &vp[3], &vp[2],
color[i],
obj, (u_long *)myOT[ActiveBuffer].org,
&div);
// Increment primitive list pointer
myPrimPtr += POLY_F4_size*((1<<(div.ndiv))<<(div.ndiv));
NumPrims_local += ((1<<(div.ndiv))<<(div.ndiv));
// Low LOD level (no subdivision)
} else {
setRGB0(obj, color[i].r, color[i].g, color[i].b);
AddPrim((u_long *)myOT[ActiveBuffer].org, obj);
myPrimPtr += POLY_F4_size;
NumPrims_local += 1;
}
}
}
}
PopMatrix();
return (NumPrims_local);
}
Code: Select all
void PRIM_poly_tst() {
RECT ClearRect = { 0, 0, 384, 512 };
POLY_F4 s[6]; /* cube surface*/
CVECTOR c[2][6]; /* cube colors*/
DIVPOLYGON4 div;
//MATRIX omtx;
VECTOR cube_pos[2] = {0,0,0,0};
VECTOR cube_scl[2] = {0,0,0,0};
SVECTOR cube_rot[2] = {0,0,0,0};
VECTOR bulb_pos = {0,-230,0,0};
SVECTOR bulb_rot = {0,0,0,0};
int cube_size = 196;
int cube2_size = 196;
int total_prim_size = 0;
int i,cbe;
u_char abs = false;
ResetGraph(0);
ClearImage2(&ClearRect, 0, 0, 0);
ClearImage (&ClearRect, 0, 0, 0);
/* set surface colors */
for (cbe = 0; cbe < 2; cbe++) {
for (i = 0; i < 6; i++) {
c[cbe][i].r = SetRandomNUM(255); /* R */
c[cbe][i].g = SetRandomNUM(255); /* G */
c[cbe][i].b = SetRandomNUM(255); /* B */
}
}
init3d(0);
SetPlayerCam(ONE*1, ONE*1, ONE*1, 0, 0);
//OBJ POS
for (cbe = 0; cbe < 2; cbe++) {
cube_pos[0].vz = 270;
cube_pos[1].vz = ((cube_pos[0].vz + 50) * 2);
cube_scl[cbe].vx = cube_scl[cbe].vy = cube_scl[cbe].vz = 1024*3;
}
ObjectCount += LinkModel((u_long*)tmd_bulb, &Object[0]); // Light bulb as a test-TMD
g_iGS_R = g_iGS_G = g_iGS_B = 50;
FntLoad(960, 256);
FntOpen(0, 0, SCREENXRES, SCREENYRES, 0, 1024);
// Set the screen resolution to the 'div' environment
div.pih = SCREENXRES;
div.piv = SCREENYRES;
VSyncCallback(SetAnalogControl);
while (1) {
sp_cursor();
GsSetProjection(FOV);
SetPad(PORT1,PORT2);
if ( (button[0] & B_CIRCLE) && (button[0] & T_L2) ) break;
if ( (button[0] & S_SELECT) ) {
SetPlayerCam(ONE*1, ONE*1, ONE*1, 0, 0);
}
if ( (button[0] & D_UP) ) {
FOV++;
}
if ( (button[0] & D_DOWN) ) {
FOV--;
}
for (cbe = 0; cbe < 2; cbe++) {
if ( (button[0] & T_L1) ) {
cube_rot[cbe].vy+=10;
}
if ( (button[0] & T_L2) ) {
cube_rot[cbe].vy-=10;
}
if ( (button[0] & T_R1) ) {
cube_pos[cbe].vz+=10;
}
if ( (button[0] & T_R2) ) {
cube_pos[cbe].vz-=10;
}
if ( (button[0] & D_LEFT) ) {
cube_scl[cbe].vx-=50;
cube_scl[cbe].vy-=50;
cube_scl[cbe].vz-=50;
}
if ( (button[0] & D_RIGHT) ) {
cube_scl[cbe].vx+=50;
cube_scl[cbe].vy+=50;
cube_scl[cbe].vz+=50;
}
}
if ( (button[0] & B_SQUARE) ) abs = true;
if ( (button[0] & B_CIRCLE) ) abs = false;
FntPrint("\n\n %c 3D CUBE Test %c\n", cursor[pos], cursor[pos]);
FntPrint("\n Camera: X %d Y %d Z %d\n PAN %d TIL %d", Camera.pos.vx,Camera.pos.vy,Camera.pos.vz,Camera.rot.vy,Camera.rot.vx);
FntPrint("\n Cube: VX %d VY %d VZ %d", cube_pos[0].vx,cube_pos[0].vy,cube_pos[0].vz);
//FntPrint("\n Prims: %d/%d",Draw3DBoxF4(cube_size, false, false, cube_pos, cube_rot, c, div, s),MAX_PRIMS);
FntPrint("\n OTc: %d", OTc);
PrepDisp();
Player[0].x += Player[0].vx;
Player[0].y += Player[0].vy;
Player[0].z += Player[0].vz;
Player[0].pan += Player[0].panv;
Player[0].til += Player[0].tilv;
Player[0].vx *=0.9f;
Player[0].vy *=0.9f;
Player[0].vz *=0.9f;
Player[0].panv *=0.9f;
Player[0].tilv *=0.9f;
Camera.pos.vx = Player[0].x/ONE;
Camera.pos.vy = Player[0].y/ONE;
Camera.pos.vz = Player[0].z/ONE;
Camera.rot.vy = -Player[0].pan;
Camera.rot.vx = -Player[0].til;
CalculateCamera();
for (cbe = 0; cbe < 2; cbe++)
Draw3DBoxF4(abs, 0, 150, cube_scl[cbe], cube_pos[cbe], cube_rot[cbe], c[cbe], div, s);
PutObject(bulb_pos, bulb_rot, &Object[0]);
Display();
}
}
-
LameGuy64 Verified
- Psy-Q Enthusiast
- Posts: 388
- Joined: Apr 10, 2013
- I am a: Hobbyist Game Developer
- Motto: Commercial or not, play it!
- PlayStation Model: H2000/7000
- Location: Philippines
- Contact:
Ah, you need to Z sort your primitives using the OTz result.
That should fix your Z sorting issues. Also, you may want to do some if checks to make sure that OTc does not exceed the size of your OT array.
Code: Select all
DivideF4(
&vp[0], &vp[1], &vp[3], &vp[2],
color[i],
obj, (u_long *)myOT[ActiveBuffer].org+OTc,
&div);
and...
AddPrim((u_long *)myOT[ActiveBuffer].org+OTc, obj);
Please don't forget to include my name if you share my work around. Credit where it is due.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.
DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.
-
NITROYUASH Verified
- Serious PSXDEV User
- Posts: 124
- Joined: Jan 07, 2018
- I am a: Game Designer
- PlayStation Model: SCPH-5502
- Location: Russian Federation
- Contact:
Yes, it's actually fix my problems with OTz (OTc)! Actually, i have seen this in Psy-Q examples, but didn't try to use for some reasons. Thank you so much!
Who is online
Users browsing this forum: No registered users and 8 guests