Page 1 of 1

"LookAt" Function?

Posted: April 3rd, 2018, 6:30 am
by MrQuetch
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.

Re: "LookAt" Function?

Posted: April 21st, 2018, 11:55 am
by LameGuy64
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.

Re: "LookAt" Function?

Posted: May 1st, 2018, 10:24 am
by MrQuetch
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.

Re: "LookAt" Function?

Posted: May 26th, 2022, 10:02 pm
by Kyoril
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.