• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

3D GMS2 - Why does my camera mirror itself?

trentallain

Member
Code:
//Create
//3D camera
camera = camera_create()
gpu_set_zwriteenable(true)
gpu_set_ztestenable(true)
projection_matrix = matrix_build_projection_perspective_fov(-60, -view_get_wport(0)/view_get_hport(0), 32, 32000)
camera_set_proj_mat(camera, projection_matrix)
view_set_camera(0, camera)
camera_set_update_script(view_camera[0], camera_update_script)
global.xmove = 0
global.pan = 0
global.tilt = 45
global.distance = 1000
global.camerax = lengthdir_x(lengthdir_x(1, global.pan), global.tilt)
global.cameray = lengthdir_x(lengthdir_y(1, global.pan), global.tilt)
global.cameraz = lengthdir_y(1, global.tilt)
Code:
///camera_update_script
if keyboard_check(vk_right)
{
    if global.pan < 360 { global.pan += 1 }
    else { global.pan = 0 }
}

if keyboard_check(vk_left)
{
    if global.pan > 0 { global.pan -= 1 }
    else { global.pan = 360 }
}

if keyboard_check(vk_up) { global.tilt += 1 }
if keyboard_check(vk_down) { global.tilt -= 1 }

global.camerax = lengthdir_x(lengthdir_x(1, global.pan), global.tilt+25)
global.cameray = lengthdir_x(lengthdir_y(1, global.pan), global.tilt+25)
global.cameraz = lengthdir_y(1, global.tilt+25)

matrixlookat = matrix_build_lookat(obj_xwing.x + global.camerax * global.distance,obj_xwing.y + global.cameray * global.distance,obj_xwing.z + global.cameraz * global.distance,obj_xwing.x,obj_xwing.y,obj_xwing.z, 0,0,-1)

camera_set_view_mat(view_camera[0], matrixlookat)
When my camera gets to 2 different points (directly above and below the ground - stored in the tilt variable), it mirrors the camera and I have no idea why... Can someone help please?
 
This is the result of the way the view matrix is computed by matrix_build_lookat. When the camera points 90 degrees or more up or down (i notice you are adding 25 degrees to camera tilt, which explains the oddball 115 and 65 values), you can no longer describe the up vector sufficiently with (0,0,-1). Beyond + or - 90 degrees, the world will appear flipped. At exactly 90 degrees your camera's yaxis (up) and zaxis (look) are parallel. Therefor, your camera's xaxis vector, which is the cross product of your camera's yaxis and zaxis vectors, is (0,0,0), which basically means your world is compressed to zero size, hence the black screen.

What you need to do is to compute an up vector that is relative to the tilt and pan of your camera.
 
Last edited:

trentallain

Member
This is the result of the way the view matrix is computed by matrix_build_lookat. When the camera points 90 degrees or more up or down (i notice you are adding 25 degrees to camera tilt, which explains the oddball 115 and 65 values), you can no longer describe the up vector sufficiently with (0,0,-1). Beyond + or - 90 degrees, the world will appear flipped. At exactly 90 degrees your camera's yaxis (look) and zaxis (up) are parallel. Therefor, your camera's xaxis vector, which is the cross product of your camera's yaxis and zaxis vectors, is (0,0,0), which basically means your world is compressed to zero size, hence the black screen.

What you need to do is to compute an up vector that is relative to the tilt of your camera.
Thanks! How would I do that?
 
It's late, so I could be making a mistake here, but I think your up vector should be either this, or something similar to it (try switching it around if it doesn't work):


up_x = -dsin(global.tilt + 25)*dcos(global.pan);
up_y = dsin(global.tilt + 25)*dsin(global.pan);
up_z = -dcos(global.tilt + 25);

EDIT: corrected a mistake.

did you mean for your up direction to be toward negative z? Is that why your model was upside down? Or did you make this adjustment in order to flip the model right side up?
 

trentallain

Member
It's late, so I could be making a mistake here, but I think your up vector should be either this, or something similar to it (try switching it around if it doesn't work):


up_x = -dsin(global.tilt + 25)*dcos(global.pan);
up_y = dsin(global.tilt + 25)*dsin(global.pan);
up_z = -dcos(global.tilt + 25);

EDIT: corrected a mistake.

did you mean for your up direction to be toward negative z? Is that why your model was upside down? Or did you make this adjustment in order to flip the model right side up?
Where do I put the up_x/y/z? I tried using it to replace camerax/y/z in the line:
matrixlookat = matrix_build_lookat(obj_xwing.x + global.camerax * global.distance,obj_xwing.y + global.cameray * global.distance,obj_xwing.z + global.cameraz * global.distance,obj_xwing.x,obj_xwing.y,obj_xwing.z, 0,0,-1)
But it didn't work, so I must have put it in the wrong place.

This is the model's transformation code currently:
matrix_set(matrix_world, matrix_build(x, y, 0, global.tilt-180, -yangle, global.pan+90, scale, scale, scale))
By default pan = 0
tilt = 45
yangle = 0
 
No, you want to replace the last three arguments (0,0,-1)

What you are doing with your model's matrix is confusing to me, so there is a good chance I have made a mistake with the exact up vector calculation. And if that is the case, then most likely the fix involves just flipping signs here or there. I'm too tired to look into it any further, sorry. Hopefully I've been of some help though.
 

trentallain

Member
No, you want to replace the last three arguments (0,0,-1)

What you are doing with your model's matrix is confusing to me, so there is a good chance I have made a mistake with the exact up vector calculation. And if that is the case, then most likely the fix involves just flipping signs here or there. I'm too tired to look into it any further, sorry. Hopefully I've been of some help though.
It works, thanks so much!
 
Top