Screen to World coordinates (SOLVED)

Hi,
I know that this question was there several times, but in my project is better to not use Rendercam, because I programmed window resizing much easier with default render script and I would not like to change it. So I’m trying to make to implement function from this example: Camera component manual

I only added this function to render script:

--..............
elseif message_id == hash("screen_to_world") then
    screen_to_world(message.x,message.y,0, self)
end
end

function screen_to_world(x, y, z, self)
local inv = vmath.inv(self.projection * self.view)
x = (2 * x / render.get_width()) - 1
y = (2 * y / render.get_height()) - 1
z = (2 * z) - 1
local x1 = x * inv.m00 + y * inv.m01 + z * inv.m02 + inv.m03
local y1 = x * inv.m10 + y * inv.m11 + z * inv.m12 + inv.m13
local z1 = x * inv.m20 + y * inv.m21 + z * inv.m22 + inv.m23
print(x1, y1, z1)
return x1, y1, z1
end

And I’m calling it by this message from main script:

msg.post("@render:", "screen_to_world", { x = action.x, y = action.y })

But it’s returning values like this:

Can anybody find mistakes in my script please?

I’m sorry, in the end it was very simple, just set:

self.projection = get_projection(self)

instead of:

if message_id == hash("set_view_projection") then
    self.projection = message.projection
4 Likes

This is very interesting for those of us that prefer to do things ourselves and use as few external assets as possible. It would be cool to know about your approach to handle window resizing too.

2 Likes

I am really glad.
I made resizing of the window yesterday and it’s not completely universal yet, but I’ll still finish it, if it works great, I’ll definitely share it. So far, all I wanted was for the game not to show black bars when changing the window layout or anything else, because generating the environment that creates Simplex noise for my game is computationally very demanding. So I developed a simple program that, when changing the layout to anything larger than 16: 9, zooms in on the game so that nothing that isn’t actually generated is visible. I will improve it, but this is the basic version.

function update(self, dt)
local width2, height2 = window.get_size()
if width2 > 1280 or height2 > 720 then
	if height2 - 720 > width2 - 1280 then
		msg.post("@render:", "use_fixed_projection", { zoom = height2 / 720 })
	else
		msg.post("@render:", "use_fixed_projection", { zoom = width2 / 720 })
	end
else
	msg.post("@render:", "use_fixed_projection", { zoom = 1 })
end
end

16:9

Anything larger then 16:9

Anything smaller then 16:9

1 Like

One improvement would be to not run this in update() and instead use window.set_listener() to get notified of any changes in window size:

2 Likes

Thank you very much for a very quick answer, I will correct it immediately.