"LookAt" Function?

General Programming help in C, C++ or ASM, Compiling / Debugging, and R3000A Central Processing Unit (CPU) information
Post Reply
User avatar
MrQuetch
Active PSXDEV User
Active PSXDEV User
Posts: 42
Joined: Apr 01, 2018
I am a: Programmer and artist.
Motto: You can accomplish anything.
Location: United States

"LookAt" Function?

Post by MrQuetch » April 3rd, 2018, 6:30 am

Hello, everyone.

I have noticed that for a lot of different gaming consoles there are "LookAt" functions. Basically, I would like to set a point for a camera in 3D space, and have it look at another point somewhere else in 3D space. Would the PS1 happen to have the equivalent of that? If so, where could I find one? If not, how could I go about creating my own?

I have been looking through the PS1 SDK, but have not found anything yet. I'm assuming this is an easy problem with an easy fix.

Any help is appreciated. Thanks.

User avatar
LameGuy64
Verified
Psy-Q Enthusiast
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:

Post by LameGuy64 » April 21st, 2018, 11:55 am

I have this lookat routine which may do just the trick:

Code: Select all

void crossProduct(SVECTOR *v0, SVECTOR *v1, VECTOR *out) {

	out->vx = ((v0->vy*v1->vz)-(v0->vz*v1->vy))>>12;
	out->vy = ((v0->vz*v1->vx)-(v0->vx*v1->vz))>>12;
	out->vz = ((v0->vx*v1->vy)-(v0->vy*v1->vx))>>12;

}

void LookAt(VECTOR *eye, VECTOR *at, SVECTOR *up, MATRIX *mtx) {

	VECTOR taxis;
	SVECTOR zaxis;
	SVECTOR xaxis;
	SVECTOR yaxis;
	VECTOR pos;
	VECTOR vec;

	setVector(&taxis, at->vx-eye->vx, at->vy-eye->vy, at->vz-eye->vz);
	VectorNormalS(&taxis, &zaxis);
    crossProduct(&zaxis, up, &taxis);
	VectorNormalS(&taxis, &xaxis);
	crossProduct(&zaxis, &xaxis, &taxis);
	VectorNormalS(&taxis, &yaxis);

	mtx->m[0][0] = xaxis.vx;	mtx->m[1][0] = yaxis.vx;	mtx->m[2][0] = zaxis.vx;
	mtx->m[0][1] = xaxis.vy;	mtx->m[1][1] = yaxis.vy;	mtx->m[2][1] = zaxis.vy;
	mtx->m[0][2] = xaxis.vz;	mtx->m[1][2] = yaxis.vz;	mtx->m[2][2] = zaxis.vz;

	//ApplyMatrixLV(mtx, eye, &vec);
	//TransMatrix(mtx, &vec);

	//mtx->t[0] = eye->vx;
	//mtx->t[1] = eye->vy;
	//mtx->t[2] = eye->vz;

	pos.vx = -eye->vx;//>>12;
	pos.vy = -eye->vy;//>>12;
	pos.vz = -eye->vz;//>>12;

	ApplyMatrixLV(mtx, &pos, &vec);
	TransMatrix(mtx, &vec);
}
Syntax should be similar to OpenGL's lookat function. Reply back if you have any troubles.
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.

User avatar
MrQuetch
Active PSXDEV User
Active PSXDEV User
Posts: 42
Joined: Apr 01, 2018
I am a: Programmer and artist.
Motto: You can accomplish anything.
Location: United States

Post by MrQuetch » May 1st, 2018, 10:24 am

LameGuy64 wrote: April 21st, 2018, 11:55 am I have this lookat routine which may do just the trick:

Code: Select all

void crossProduct(SVECTOR *v0, SVECTOR *v1, VECTOR *out) {

	out->vx = ((v0->vy*v1->vz)-(v0->vz*v1->vy))>>12;
	out->vy = ((v0->vz*v1->vx)-(v0->vx*v1->vz))>>12;
	out->vz = ((v0->vx*v1->vy)-(v0->vy*v1->vx))>>12;

}

void LookAt(VECTOR *eye, VECTOR *at, SVECTOR *up, MATRIX *mtx) {

	VECTOR taxis;
	SVECTOR zaxis;
	SVECTOR xaxis;
	SVECTOR yaxis;
	VECTOR pos;
	VECTOR vec;

	setVector(&taxis, at->vx-eye->vx, at->vy-eye->vy, at->vz-eye->vz);
	VectorNormalS(&taxis, &zaxis);
    crossProduct(&zaxis, up, &taxis);
	VectorNormalS(&taxis, &xaxis);
	crossProduct(&zaxis, &xaxis, &taxis);
	VectorNormalS(&taxis, &yaxis);

	mtx->m[0][0] = xaxis.vx;	mtx->m[1][0] = yaxis.vx;	mtx->m[2][0] = zaxis.vx;
	mtx->m[0][1] = xaxis.vy;	mtx->m[1][1] = yaxis.vy;	mtx->m[2][1] = zaxis.vy;
	mtx->m[0][2] = xaxis.vz;	mtx->m[1][2] = yaxis.vz;	mtx->m[2][2] = zaxis.vz;

	//ApplyMatrixLV(mtx, eye, &vec);
	//TransMatrix(mtx, &vec);

	//mtx->t[0] = eye->vx;
	//mtx->t[1] = eye->vy;
	//mtx->t[2] = eye->vz;

	pos.vx = -eye->vx;//>>12;
	pos.vy = -eye->vy;//>>12;
	pos.vz = -eye->vz;//>>12;

	ApplyMatrixLV(mtx, &pos, &vec);
	TransMatrix(mtx, &vec);
}
Syntax should be similar to OpenGL's lookat function. Reply back if you have any troubles.
Hi, LameGuy64.

I'm sorry for the late reply. I thought this was going to be an easy fix, but it looks like it's going to take longer than I expected. Regardless of the length, thank you for the snippet of code. It's been awhile since I programmed for the PS1, so I'm going to familiarize myself with it again before I implement this piece. I will let you know if I run into any trouble.

Kyoril
Interested PSXDEV User
Interested PSXDEV User
Posts: 7
Joined: Mar 13, 2022
I am a: Programmer
PlayStation Model: SCPH-5552
Discord: Kyoril#9629
Location: Germany

Post by Kyoril » May 26th, 2022, 10:02 pm

Hi LameGuy64,

since MrQuetch didn't respond and I stumbled upon this thread, I want to assure you that the method works just fine, although there needs to be some clarification.

For it to work, the vector input needed to be as follows:

eye: VECTOR with each component multiplied by ONE
at: VECTOR with every component divided by ONE (which was really strange...)
up: SVECTOR with ONE (why SVECTOR when it still needs * ONE? I used setVector(&up, 0, -ONE, 0) which worked for me)
matrix: &view.view where view was my GsVIEW2.

Hope this helps and maybe somebody knows answers for the questions I added to my description :D

Anyway, thanks for sharing this method, it was a huge help and gave me some general AHA moments when working with 3D.

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests