defold-orthographic
defold-orthographic copied to clipboard
screen_to_world and FarZ
Hello! I have question, but probably it is some kind of issue. I set FarZ = 1000, set projection to FIXED_ZOOM and rotated camera (-30, 0, 0)
Since I want to place all GO in 3d space I want to raycast to it. But I noticed that function screen_to_world returns different coordinates for mouse position if change FarZ (nothing else changed)
I think that if camera stay on one place and ortographic size is same then world coordinates of mouse should remain same
Update, if FarZ + NearZ == 0 than world position is right in space of camera object. But if NearZ -1 and FarZ 5000 than it returns coordinate far from camera for 2500 points
I haven't looked into this very closely but it is likely that the screen to world calculation is not correct when the camera is rotated on the x or y axis.
Здравствуйте! У меня вопрос, но, вероятно, это какая-то проблема. Я установил FarZ = 1000, установил проекцию на FIXED_ZOOM и повернул камеру (-30, 0, 0)
Поскольку я хочу разместить все GO в трехмерном пространстве, я хочу выполнить на него радиопередачу. Но я заметил, что функция screen_to_world возвращает другие координаты для положения мыши, если изменить FarZ (больше ничего не изменилось)
Я думаю, что если камера остается на одном месте и ортографический размер такой же, то мировые координаты мыши должны оставаться неизменными
You fix it?
I have this problem
local function calculate_view_new(camera, camera_world_pos, camera_world_rotation, offset)
local rot = camera_world_rotation
local pos = camera_world_pos - vmath.rotate(rot, OFFSET)
if offset then
pos = pos + offset
end
local look_at = pos + vmath.rotate(rot, VECTOR3_MINUS1_Z)
local up = vmath.rotate(rot, VECTOR3_UP)
local view = vmath.matrix4_look_at(pos, look_at, up)
return view
end
function M.screen_to_world_ray(camera_id, screen, plane_normal, point_on_plane)
screen.x = screen.x * DISPLAY_WIDTH / WINDOW_WIDTH
screen.y = screen.y * DISPLAY_HEIGHT / WINDOW_HEIGHT
local camera = cameras[camera_id]
local camera_world_position = go.get_world_position(camera.id)
local camera_world_rotation = go.get_world_rotation(camera.id)
-- Phasa 1 camera local
local projection = camera.projection
local idle_view = calculate_view_new(camera, camera_world_position, vmath.quat())
-- Base
local viewport = camera.viewport or VECTOR4
local viewport_width = viewport.z * DISPLAY_WIDTH / WINDOW_WIDTH
local viewport_height = viewport.w * DISPLAY_HEIGHT / WINDOW_HEIGHT
local viewport_left = viewport.x * DISPLAY_WIDTH / WINDOW_WIDTH
local viewport_bottom = viewport.y * DISPLAY_HEIGHT / WINDOW_HEIGHT
local s = vmath.vector3(screen)
s.x = (s.x - viewport_left) * (DISPLAY_WIDTH / viewport_width)
s.y = (s.y - viewport_bottom) * (DISPLAY_HEIGHT / viewport_height)
local camera_local_position = M.unproject(idle_view, projection, s)
camera_local_position.z = camera_world_position.z
-- Phasa 2 rotation
local from_rotation = camera_local_position - camera_world_position
from_rotation = vmath.rotate(camera_world_rotation, from_rotation)
from_rotation = from_rotation + camera_world_position
local direction = vmath.rotate(camera_world_rotation, vmath.vector3(0,0, -1))
-- Phase 3 projection to plane
local denom = vmath.dot(plane_normal, direction)
if denom == 0 then
-- ray is perpendicular to plane normal, so there are either 0 or infinite intersections
return
end
local t = vmath.dot(point_on_plane - from_rotation, plane_normal)/denom
print(from_rotation+ t*direction)
return from_rotation+ t*direction
end
function on_input(self, action_id, action)
local word_pos = camera.screen_to_world_ray(hash("/camera"), vmath.vector3(action.screen_x, action.screen_y, 0), vmath.vector3(0, 0, -1), vmath.vector3(0))
action.x = word_pos.x
action.y = word_pos.y
msg.post("#cursor", "input", { action_id = action_id, action = action })
end
I make this and add to camera.lua. And this work great!
fix to screen_x and screen_y