What I have implemented already
I have implemented an app which is able to render to the screen a list of polygons, with a specific static camera setting (position, look at and up vector), all in plain Java AWT without OpenGL.
I apply a model-view matrix first, then projection-to-2D matrix and then a viewport matrix.
I also implemented some basic transformation matrices on the world, such as translation, rotation of X/Y/Z axis around lookAt point and scaling around lookAt point.
What I want to achieve now
I want to be able to "move" in the world. Specifically, I want to navigate forward, backward, left and right with the keyboard arrows, and to be able to look at different points with the mouse. Just like in real games.
I guess this is done via changing the camera parameters each time and render the world again.
Is it that simple, though?
Moving in the world is just adding x,y values to camera position and look at a point?
In addition, is moving the mouse is just adding x,y to the look at a point?
Do I have to touch the up vector under any condition?
Informative answers, with additional relevant links, would also really help.
first take a look at Understanding 4x4 homogenous transform matrices
extract your camera axises vectors
If you look at the 1st image in the linked answer you will see where are the vectors stored. Beware if you got transposed layout then the vectors are also transposed.
movement
The movement is easy you just
add/sub
the direction vector to the origin of your camera matrix. For example my cameras haveZ-
as a forward direction. So I takeZ-axis
vector from the matrix (which is in my case already unit) multiply it with speed and time (of the timer interval where the movement code is running). Here is example how my movement code usually looks like:The
keys
is my class holding single bit bool for eaach of the 16 bit key code allowing me to handle multiple pressed keys at once. Theeye.rep
is my class holding both direct and inverse transformation matrix. Its memberlpos_set
takes a 3D vector transforms it from local to global coordinates and set this as matrix origin. It has the same effect as the above process I mentioned. Thedeg
is just constant 1 degree in radians andlrot?
are the local rotations see next bullet.rotations
I do not use Euler angles as I hate them. They got glitches needed handling poles differently and often causing problems. Have you play any games and the camera angular rotation got stuck not allowing you rotate where you want? Or even reverse? Then it is due to Euler angles used for camera.
I use local rotations
lrot?
instead (see the linked answer how they work). They have no bounds or glitches. The only thing that you need to take in mind is accuracy. If you are rotating matrix many times you loosing precision. So every few rotations ensure its orthogonality or orthonormality. For that you need just use cross product to make the axises perpendicular again and set their length to1
or whatever you use. I have a counter in my matrix class incrementing each change and when it hits a treshold the orthonormality is restored.As you can see I use numpad for the movements the arrows are for turn left/right and go forward/backward. Most people nowadays use
WSAD
but that is extremly uncomfortable for me. The code is taken from one of my VCL apps so you need to change the events to match yours.You can also add mouse handler for turning ... In case you need Joystick see
but I doubt if it is applicable for JAVA as it is for Windows.
You can implement this behavior with a structured management of matrices. Especially the view matrix. Adding something to the x/y position is not correct in most cases because the camera may be rotated.
Let's denote the current view matrix with
V
. If you want to move the camera, you have to calculate a new view transform:, where
Translate(a, b, c)
is a translation matrix.-x
represents the movement in the left/right direction.-y
represents up/down.-z
represents forward/backward.If you want to rotate the camera, this can be done similarly:
, where
Rotate(-angle, axis)
is a rotation matrix. Use rotation about the x-axis to look up/down and rotation about the y-axis to look left/right. Rotation about the z-axis is usually not needed because it introduces a roll to the camera.The reason why most parameters are negated is that view transforms are inverse transforms. I.e. they do not position the camera object, but they re-position the world as if the camera was at the origin.