3D 8 directional sprite rotation based on facing direction relative to camera direction

This topic is 911 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Greetings everyone!

I am trying to create a simple DOOM clone. I got some 8 directional sprites, which I want to draw in 3D dimentional space. I have an enemy class which has a facing direction. I also have a player with a camera. I want for the sprite to choose the correct direction depending on its facing direction and relative to the camera's viewing direction. I.e if I start going around in circles around the sprite it should rotate as well.

I want to achieve the same thing as in this animated picture:

This is what I have tried so far, but it doesn't work correctly all of the time. Only for certain angles.
// Inside the enemy classvec3 playerToSprite = this->position - player.position;vec3 direction = this->facing_direction - playerToSprite;angle = radtodeg(arctan2(direction.x, direction.y));if (angle > 90){    angle = 450 - angle;}else{    angle = 90 - angle;}// Choose the correct sprite. Sprites 0 is the East facing sprite, 1 is the NorthEast, 2 is North and it goes on clockwisethis->sprite = sprites[angle / 45];
Can you help me to fix my code?

EDIT: I managed to solve my problem. Here is the complete solution:
// Camera facing direction (in 2D)// Direction is the direction at which the camera is looking at ( in 2D )vec2 camera = vec2(            cos(degtorad(CCamera::GetMainCamera()->transform.direction)),            -sin(degtorad (CCamera::GetMainCamera()->transform.direction)));// Object facing direction (in 2D)// direction is the facing direction of the sprite, i.e. the direction at which the sprite is Looking At. ( in 2D )vec2 facing = vec2(           cos(degtorad(self->transform->direction)),            -sin(degtorad(self->transform->direction)));// Dot productdouble cosine = dot(camera, facing);double angle = radtodeg(arctan2(facing.y, facing.x) - arctan2(camera.y, camera.x));if (angle > 90.0){    angle = 450.0 - angle;}else{    angle = 90.0 - angle;}self->sprite = sprite_set[floor(angle / 45.0)];
Edited by frob
Do not mark discussions as 'solved', this is not a Q/A site.

Share on other sites

arctan parameter order is usually (y, x) -- not (x, y).

Apart from that, I'd suggest just printing out some debug values as you spin the camera to see what values you get and compare them to what you are expecting to get, noting/looking into cases where the two differ.

Share on other sites

That trick you're doing might not help you correctly.The issue is a problem of trigonometry and analytical geometry.

You have two objects to concern yourself with, the character and the camera.

Let's say that the camera is looking directly at the character. The character is facing to the west. The camera is facing north.

The issue with the method you're using is that you can not easily discriminate in the facing of the character or the camera. You can't know that for sure. So you reduce this to vector math.

Recall an axis aligned Unit Cube.

If you take the DOT product of the camera's facing vector, and the surface normal's of each face of the cubes, you can find out which of the six sides is facing the camera the most by using the largest positive value. If a result returns negative or zero, you can ignore it because it means that the normal is facing away from the camera or it's perpendicular.

When we solve this problem with the aforementioned example, the result we will get is that the south cube face is the side that's currently facing the camera. Because the character is facing left, we see his left side.

Now, lets extend this to the eight sided problem.

Build an axis aligned octagon with unit normals. You can compute this and hard code this later. Just start with a normal of (1,0,0), and rotate it around the Z axis by 45 degrees eight times.

When you run your tests, you can compute this against the eight sides.

Your character's facing will simply be a flag that determines which one of the sides he's facing, and then can be used to logically choose the right sprite depending on which normal is most present to the camera.

Hope this helps!

Edited by Tangletail

Share on other sites

I managed to solve my problem! I edited my original post with the solution. Thank you all for your support.

Share on other sites

tangent is rise over run or y/x(sin/cos), not x/y(cotangent). That is not your issue though. Your setup is arbitrary and finite. If I were at home, I would post my implementation. I will later tonight after work if an appropriate answer has not been given.

Share on other sites

You remind me of RPG Maker.

1. 1
2. 2
Rutin
19
3. 3
khawk
18
4. 4
A4L
14
5. 5

• 12
• 16
• 26
• 10
• 44
• Forum Statistics

• Total Topics
633767
• Total Posts
3013735
×