Advertisement

3D World - movement as a state machine ???

Started by June 16, 2004 02:00 AM
22 comments, last by Yaniv Shekel 20 years, 5 months ago
Quote: Original post by python_regious

Anyway, I don't get what the problem is Yaniv. I've read your posts multiple times now, and I just can't seem to find it...


Well thanks all for your contributions I'm glad my problem generated the discussion of infinite vs. finite in computing. I still though have the same original problem. Let me try to explain again. Say that the camera is positioned on a spaceship. The spaceship can move forwards and backwards and make 90 degree turns right/left/up/down. The world which is arranged around the (0,0,0) cartesian point must then rearrange itself, (in my mind the camera is stationary and the world moves). I keep, for that purpose, a position vector, like you said, but a discrete count of the "up" vector and the "forward" vector. The discretization is into constants: FORWARD, BACK, LEFT, RIGHT, UP, DOWN. I treat my up and forward vectors as state variables and update them and the position vectors according to the last position the last up direction the last forward direction and the current user input. The update is done in a vast multitude of "if"s. No mathematics is used for that and I do not know if any exist. In a discrete world which does mimic the real world you can't update the position (I think) with an ever expanding amount of if queries. How then, do you update your vectors?
Quote: Original post by AndyL

You've got no storage of the absolute locations of the objects? Only their location relative to the player?

I'd worry about rounding errors personaly. Especialy on rotations.


Or maybe I missunderstood you. That's very possible.


I do store the absolute locations of the objects but must rearrange them as the camera "moves". What do you mean "Especially on rotations"?

One more thing I'm sorry I didn't get back to you all but I guess I live in a different time zone.
Advertisement
Ok, I think you're thinking about this all wrong.

You're keeping the world coordinates of your objects, thats good. You don't need to re-arrange anything though, because of the camera. You just multiply the modelview matrix by the frame of the object, then by the frame of the camera. ( Or close to that, my brain hasn't turned on fully yet ).

Now, lets have an example. You have a camera, it has 4 vectors. Your camera object just got a signal to move in the direction [5,5,5]. Well, thats pretty simple to do, you'd just add that vector to the position vector of the camera.

Ok, now lets say you want to rotate the camera, so to make it turn left or right. To do this, you want to rotate it around the up vector, by a certain numbef of degrees. What I do, is take the front vector, rotate that around the up vector, by the required amount, then use a cross product of the new front vector and the up vector to get the new side vector. Ok?

This is all pretty simple really, it's just maths (Ok, it may not be simple, depending on your mathematical background). There's no need to make the camera vectors take on specific, pre-defined values, calculate it on the fly.
If at first you don't succeed, redefine success.
I think what he's getting at is that he has seperate 'states' for each of the six directions his camera can be facing in, and looks up the 3D world vector in a table when he needs to convert to world space. Sort of like, in a Galaga-style game, your ship might have three possible states, STATE_MOVING_LEFT, STATE_STATIONARY, and STATE_MOVING RIGHT. Yaniv's taken this to a whole nother level by having STATE_GOING_UPWARDS, STATE_GOING_DOWNWARDS, STATE_GOING_LEFTWARDS, etc.

To answer the OP's question - Yes, this is an OK way of doing things if you want to keep your movement discrete, but as you say it's going to get ugly if you want to allow the player to move in any direction they want. Usually in this situation, instead of storing a single state which says 'the player is going up and left', we store a vector of three numbers that represents the player's velocity.

For instance, if the vector (0, 1, 0) represents movement straight upwards, (1, 0, 0) is movement to the north, and (0, 0, 1) is movement to the east, then you could give your player a velocity of (1, 0, 1), which would be moving northeast with a speed of 1.4.

Quote: Original post by python_regious
You just multiply the modelview matrix by the frame of the object, then by the frame of the camera.


Maybe I'm doing things the wrong way but I usually start by multiplying by the inverse of the camera's position/orientation and then by the object's.
This way I can push/pop the matrix to keep the camera-transformed matrix when rendering all objects.
SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
Quote: Original post by python_regious

You just multiply the modelview matrix by the frame of the object, then by the frame of the camera.
....
you'd just add that vector to the position vector of the camera.


Thanks all for your responses!
Two questions:
1) What do you mean by frame?
2) Which is the position vector? Is it the leftmost column in the 4x4 matrix?

Now if I keep a velocity vector as fractoid suggests I just have to translate(?) my modelview matrix by it. What about my current position? I guess also that if I want to keep constant movement I must normalize the vector. And well, the thing that irks me most is, how do I calculate that vector on a lefthand turn, say? Do I first translate the matrix (therefore adding the vector?)and then rotate it. Well I just get more and more confused as I write this!!!
Advertisement
Frame : A coordinate reference. Also called a frame of reference. Basically a 4x4 matrix consisting of the 3 basis vectors, and the position of the frame.

The position vector is the right most column, using column major matrices ( what OpenGL uses ). Row major matrices would use the bottom row ( this is what D3D uses ). Luckily the memory configuration that OpenGL and Direct3D uses is the same.

If you want to keep an arbitary velocity vector, then it gets a little more complicated. Here's a little overview of what you'd have to do, but personally I'd start with something a little easier.

You'd have the camera matrix that stores the cameras orientation and position. You'd have a velocity vector that defines in what direction the camera frame is moving. You'd also have some acceleration vectors.

Now, every frame, you'd need to change the direction of the velocity vector, based on the acceleration vectors. Firstly, resolve the acceleration vectors, to get a singular resultant acceleration. Now, you have to rotate the camera frame, using the acceleration vector and the velocity vector. You'd rotate the frame along the vector product of the velocity vector and acceleration vector, by the angle inbetween them. Then you'd translate the frame by the new velocity vector to get it's new displacement.

However, based on the rest of your post, that last paragraph will seem like a foreign language to you. I suggest you read up on vector and matrix operations ( rotating vectors, different methods to do this ), and on basic physics modelling (using vectors to model displacement, velocity, and acceleration. The constant acceleration equations, and so forth ). There are numerous articles on this site to do with this sort of thing. Also, rememeber google is your friend! :)

As I said previously, I wouldn't start on worrying about the whole accelerations and so forth bit yet, you don't really need to to write a camera, just get it working using input from your keyboard/mouse to manually trasnform the camera.
If at first you don't succeed, redefine success.
I've been going over what you all said again and I think I might have it. Please tell me if I got it right. I keep the camera as a matrix made up of 4 vectors: forward, side, up and position. These vectors are the columns. When I want to move in a certain direction I increment/decrement the values of the position vector. When I want to turn I rotate the matrix by a predifined angle around the appropriate vector and cross product the new vector and the rotate axis to obtain the third vector and replace it in the proper place in the matrix.
You're almost there!

You've got it on the translation bit. Though, to get the camera to move up/down, forward/backward based on the cameras orientation you're going to have to add the up/front vectors (muliplied by a scalar) from the position vector.

You're correct about the rotation sense. You may have to normalise your vectors too, as they can become unnormalised (due to rounding errors and so forth ).

Have fun! :)
If at first you don't succeed, redefine success.
Quote: Original post by AndyL

I'd worry about rounding errors personaly. Especialy on rotations.


Well guys, with all your help I may actually be on my way. I did encounter roundoff errors on rotations, where I am trying to implement python_regious' scheme. What is the best way to get rid of them?

This topic is closed to new replies.

Advertisement