Getting the right sprite direction like in Xenogears

Started by
12 comments, last by rm3 21 years ago
Fun... lol. Okay, I''ve struggled to piece it all together, and I''ve got this code chunk... (sorry it''s in C not in that language you post (VB?), but you seem to know C quite well! =D)

	const float radAngle = DEG2RAD (xAng);		vector3d O = pos;		// O is the sprite''s position	vector3d D (O + vector3d(O.x * sin(radAngle), O.y, 		O.z * cos(radAngle)));	vector3d F = vector3d (D.x, O.y, O.z);	double theta;	const float hyp = Distance2d (D.x, D.z, O.x, O.z);	const float adj = Distance2d (O.x, O.z, F.x, F.z);	if (hyp != 0) {		if ((adj / hyp) != 1) {			theta = acos (adj / hyp);			if ((D.z > O.z) && (D.x >= O.x))				;			if ((D.z >= O.z) && (D.x < O.x))				theta = theta + (PI * 0.5);			if ((D.z < O.z) && (D.x < O.x))				theta = theta + PI;			if ((D.z <= O.z) && (D.x >= O.x))				theta = theta + 3 * PI * 0.5;		//	theta = theta + (PI * 0.5);		}		else			theta = radAngle;	}	else		theta = radAngle;	unsigned int direction = 		FABS((int)CameraAngle - (int)RAD2DEG(theta)) / 45; 


Given pos, the position of the sprite, xAng, the angle in degrees the sprite is facing, and CameraAngle, an angle in degrees the camera is rotated, "direction" should hold a number between 0 and 7 that is the correct viewable direction of the character...

Unfortunately it does not. A lot of strange directions are chosen. When will I get this to work? Only the mystics know. But I think that I can do it.

Let me just get what the goal is straight. To find the correct direction, we need to find the angle between line OF (the line between the sprite''s position, and a point in front of it?) and line OD (the line between the sprite''s position, and a point its facing?), then find the difference between this and the camera angle. My head isn''t forming this too well. Why would this work? Why is the camera position not needed - it would seem that the farther away the camera is, the less "sensitive" the sprite is to switching angles when the camera rotates - but this may not be true.

The way I''ve coded it doesn''t seem to work at all - is it a flaw in what I''ve coded, or am I not getting the process and idea right?

Thank you so much for helping... sorry I''m not getting this, don''t give up on me. I''m going to figure this out by gum. =)

Advertisement
Could you show a bunch of test data here? The values for pos, xAng, CameraAngle, hyp, adj, theta, and Direction? Include what the direction should be for this set of data. This solution is coming straight from memory so it's not perfect and requires a bit of tweaking to get it right. I suspect you still need to tweak quadrants, but I'll need to see some test data to be sure.

(And I'm actually quite terrible with C/C++, but I can at least read it )

[edited by - Tri on March 25, 2003 7:28:43 PM]

[edited by - Tri on March 25, 2003 8:07:40 PM]
OK, here''s my test code, just so you know where it''s printing stuff (all of the vout << ):

void Test (vector3d pos, float xAng, float CameraAngle,		   ostream &vout){	const float radAngle = DEG2RAD (xAng);	vector3d O = pos;// O is the sprite''s position	vector3d D (O + vector3d(O.x * sin(radAngle), O.y,	O.z * cos(radAngle)));	vector3d F = vector3d (D.x, O.y, O.z);	double theta;	const float hyp = Distance2d (D.x, D.z, O.x, O.z);	const float adj = Distance2d (O.x, O.z, F.x, F.z);	// report	vout << "Pos.x: " << pos.x << " Pos.z " << pos.z << endl;	vout << "Sprite Angle (degrees): " << xAng << endl;	vout << "HYP: " << hyp << endl;	vout << "ADJ: " << adj << endl;	if (hyp != 0) {		if ((adj / hyp) != 1) {			theta = acos (adj / hyp);			vout << "THETA (before quadrant checking): " << theta << endl;			vout << "THETA (in degrees): " << RAD2DEG(theta) << endl;			if ((D.z > O.z) && (D.x >= O.x))			;			if ((D.z >= O.z) && (D.x < O.x))			theta = theta + (PI * 0.5);			if ((D.z < O.z) && (D.x < O.x))			theta = theta + PI;			if ((D.z <= O.z) && (D.x >= O.x))			theta = theta + 3 * PI * 0.5;			//theta = theta + (PI * 0.5);		}		else			theta = radAngle;	}	else		theta = radAngle;	vout << "THETA (after q. check): " << theta << endl;	vout << "THETA (in degrees): " << RAD2DEG(theta) << endl;	unsigned int direction =	FABS((int)CameraAngle - (int)RAD2DEG(theta)) / 45;} 


Here''s some test outputs (a bunch of test outputs) Pos.y is always 0:

Pos.x: 32 Pos.z 32
Sprite Angle (degrees): 45
HYP: 32
ADJ: 22.6274
THETA (before quadrant checking): 0.785398
THETA (in degrees): 45
THETA (after q. check): 0.785398
THETA (in degrees): 45

Pos.x: 32 Pos.z 32
Sprite Angle (degrees): 0
HYP: 32
ADJ: 0
THETA (before quadrant checking): 1.5708
THETA (in degrees): 90
THETA (after q. check): 1.5708
THETA (in degrees): 90

Pos.x: 32 Pos.z 32
Sprite Angle (degrees): 135
HYP: 32
ADJ: 22.6274
THETA (before quadrant checking): 0.785398
THETA (in degrees): 45
THETA (after q. check): 5.49779
THETA (in degrees): 315

Pos.x: 32 Pos.z 32
Sprite Angle (degrees): 180
HYP: 32
ADJ: 1.90735e-006
THETA (before quadrant checking): 1.5708
THETA (in degrees): 90
THETA (after q. check): 4.71239
THETA (in degrees): 270

Pos.x: 16 Pos.z 14
Sprite Angle (degrees): 45
HYP: 15.0333
ADJ: 11.3137
THETA (before quadrant checking): 0.71883
THETA (in degrees): 41.1859
THETA (after q. check): 0.71883
THETA (in degrees): 41.1859

Pos.x: 16 Pos.z 14
Sprite Angle (degrees): 90
HYP: 16
ADJ: 16
THETA (after q. check): 1.5708
THETA (in degrees): 90

Pos.x: 16 Pos.z 14
Sprite Angle (degrees): 180
HYP: 14
ADJ: 9.53674e-007
THETA (before quadrant checking): 1.5708
THETA (in degrees): 90
THETA (after q. check): 4.71239
THETA (in degrees): 270

Pos.x: 16 Pos.z 14
Sprite Angle (degrees): 270
HYP: 16
ADJ: 16
THETA (after q. check): 4.71239
THETA (in degrees): 270

A terrible mess... some of the results really are weird. All of the results where there''s no "before quadrant checking" had hyp == 0 or adj/hyp == 1...

Any other things I should test?
~
I dunno. I took this thing and tried it out over here, but I couldn't come up with anything. I can tell you that the calculation of theta before the quadrant check is correct. I also have the following test data with desired answers:

At xAng = 45, Pos = (32, 0, 32):
CameraAngle = 0, Direction should be 3
CameraAngle = 45, Direction should be 4
CameraAngle = 90, Direction should be 5
CameraAngle = 135, Direction should be 6
CameraAngle = 180, Direction should be 7
CameraAngle = 225, Direction should be 0
CameraAngle = 270, Direction should be 1
CameraAngle = 315, Direction should be 2
CameraAngle = 360, Direction should be 3

When I worked on this before, I had camera position and target. They need to be accounted for here, but I've forgotten how to do that, except for deriving the target from the camera direction. I thought direction was enough, but I guess not :/ I do remember it took me a few days to solve it. Sorry I can't be of much help right now. Perhaps in a few days I'll have thought of something, but for now you should try to figure out how to incorporate the camera's position into the calculation. Good luck!

[edited by - Tri on March 25, 2003 10:57:14 PM]

This topic is closed to new replies.

Advertisement