Cursor to world? (Top- down [2.5D])

Hello,

I’m working on a 2.5D gamemode. However, I have an issue that needs to be resolved. Here’s a demonstration of what i’m trying to do:

http://vxservers.net/cursortoworld.png

On this image, there are two important things. One: The green line. This is mean to make 2D 3D (hence 2.5D), so the green line is touching the ground. The red circle, is what I want to select. I want to get the cursor’s position, and translate it to world coordinates, for example, I will check the world coordinates of the cursor, and compare it with and object, and if they both match, it will select the object. How would I do this? Thanks.

What about this?

Use a traceline in the direction of the normalized vector returned by the function above. Obviously the trace origin should be the screen’s origin since that’s where the normalized direction vector is relative to.
For the length you probably just want to use some rediculously massive distance multiplier that will ensure it will always hit something (don’t go crazy and exceed 64 bit double size)

For ents you can just see what the vector hits or write a lil bit of code to see if the vector’s hit pos is within some distance of the entity.

Alternatively you can also just keep everything in screen space.
You can use vector:ToScreen to get a table with the x pos, good, and visibility of a world vector in screen space. You can simply project an object’s pounding box noto the screen and then check if the mouse is within the bounding box. This might be a bit more finicky but it should achieve comparable results and is a bit more intuitive than using a ray trace into the 3d world which could give somewhat glitchy selection when the ray hits undesired objects in it’s path.

Adapted from the wiki:



local tr = util.QuickTrace( CameraPosition, gui.ScreenToVector( gui.MousePos() ) )
local hitent = tr.Entity


hitent will be the entity your mouse was over, which will return Worldspawn (which you could filter out using hitent==game.GetWorld()) if you were pointing at the ground.

I’ve already tried that. It returns a normalized vector, I have to convert that to a global vector, but I don’t know how.

[editline]3rd May 2014[/editline]

However, I do see example one, it may be part of what i’m looking for.

To get entity and hitpos(just hitpos) use that
[lua]
local tr = util.QuickTrace( CameraPosition, gui.ScreenToVector( gui.MousePos() ) )
local hitent = tr.Entity
local hitpos = tr.hitPos
[/lua](lol exactly the same but added hitpos)
And always check if tr.Entity is valid
[lua]if !hitent or !IsValid(hitent) then return end[/lua] or something like that

[lua]
local tr = util.QuickTrace( Vector(camVectorX - 380, camVectorY, playerZPos * zoomAmount), gui.ScreenToVector( gui.MousePos() ) )
local hitent = tr.Entity
local hitpos = tr.hitPos
chat.AddText(tostring(hitpos))
[/lua]

returns nil.

First letter must be uppercase H. Do PrintTable( tr ).



HitBox	=	0
HitNonWorld	=	false
HitGroup	=	0
HitPos	=	-380.004425 42.686554 1023.522949
FractionLeftSolid	=	0
StartSolid	=	false
Hit	=	false
HitWorld	=	false
SurfaceProps	=	0
HitSky	=	false
Normal	=	-0.004425 0.686561 -0.727058
PhysicsBone	=	0
HitTexture	=	**empty**
HitNormal	=	0.000000 0.000000 0.000000
Entity	=	[NULL Entity]
Fraction	=	1
StartPos	=	-380.000000 42.000000 1024.250000
HitNoDraw	=	false


[editline]3rd May 2014[/editline]

If it helps, this is how i’m modifying the camera:
[lua]
function WL.EngageCamera( ply, pos, angles, fov )
if (ply:Alive()) then
local view = {}
view.origin = Vector(camVectorX - 380, camVectorY, pos.z * zoomAmount)
view.angles = Angle(70, 0, 0)
view.fov = 65
playerZPos = pos.z;

return view
end

end

hook.Add( “CalcView”, “EngageCamera”, WL.EngageCamera )
[/lua]