Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

screen_to_world and FarZ #71

Open
zendorx opened this issue Apr 15, 2024 · 6 comments
Open

screen_to_world and FarZ #71

zendorx opened this issue Apr 15, 2024 · 6 comments

Comments

@zendorx
Copy link

zendorx commented Apr 15, 2024

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)

Снимок экрана 2024-04-15 в 15 28 44

I think that if camera stay on one place and ortographic size is same then world coordinates of mouse should remain same

@zendorx zendorx changed the title screen_to_world screen_to_world and FarZ Apr 15, 2024
@zendorx
Copy link
Author

zendorx commented Apr 15, 2024

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

@britzl
Copy link
Owner

britzl commented Apr 18, 2024

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.

@KorolevSoftware
Copy link

Здравствуйте! У меня вопрос, но, вероятно, это какая-то проблема. Я установил FarZ = 1000, установил проекцию на FIXED_ZOOM и повернул камеру (-30, 0, 0)

Поскольку я хочу разместить все GO в трехмерном пространстве, я хочу выполнить на него радиопередачу. Но я заметил, что функция screen_to_world возвращает другие координаты для положения мыши, если изменить FarZ (больше ничего не изменилось)

Снимок экрана 2024-04-15 в 15 28 44 Я думаю, что если камера остается на одном месте и ортографический размер такой же, то мировые координаты мыши должны оставаться неизменными

You fix it?

@KorolevSoftware
Copy link

I have this problem

@KorolevSoftware
Copy link

KorolevSoftware commented Jul 31, 2024

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!

@KorolevSoftware
Copy link

fix to screen_x and screen_y

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants