Page 1 of 2

TraceScreenRay - Restricted View Camera

Posted: 18 Aug 2009, 23:45
by SeanHeron
Original Thread title: "Get displayed screen area (on ground) coordinates ?"

Hey, I'm messing around with a widget that restricts camera freedom so as to make it impossible to view the edge of the map (which is something I find looks quite "work in progress" like ...).
I've been making some headway, but I recently came to wonder whether the trapezoid of the visible map is somehow accessible via the Lua interface - the question came to me when I realized that it's displayed in the minimap, so is definitely already calculated somewhere in the engine (so I could perhaps save myself doing the calculations over again...).

If anyone can help, thanks !

Sean

Re: Get displayed screen area (on ground) coordinates ?

Posted: 18 Aug 2009, 23:51
by lurker
Search for 'trace'

Unless that's what you mean by doing the calculation? It's too tiny to bother with.

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 00:00
by SeanHeron
No, I meant calculating the borders/corners of the viewfield on the ground via Cameraheight, viewing angle, and trigonometry :P.
I'll have a look for trace, thanks (though if it's just in the engine, it's probably won't be so much help, I was looking for a lazy Lua Read function :D)

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 00:05
by Kloot
Spring.GetCameraVectors() might help you with the derivation.

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 00:15
by Argh
Yeah, that's the only way to do it, IIRC. You need that and get the FOV value for the given camera type. Default FOV is 45 degrees.

However, there is no general "trace" that will get the location x,y of the world in relation to the POV, you'll have to work that out. And whatever solution you come up with in terms of intercept will have issues, due to relative height- your camera will dead-stop when the frustrum's edge or point touches the the edge of the heightmap, but that may result in borked behavior, in terms of what people can / can't see. For example, on a hilly map, a high hill may obscure the other side, but players would have to change their view angle to see it, because you couldn't simply keep scrolling. If you assume OTA POV, then it should be ok, though.

I really wish that there was a generic "trace" that functioned like Spring.TraceScreenRay but from an arbitrary point in space to another arbitrary point. It'd make building these sorts of things (and many others, like Lua-based weapon systems) much easier.

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 00:26
by SeanHeron
That seems interesting, yeah! I'd tried to interpret it before, but was befuddled by the numerous vector names given.
[strike] Plus the little documentation I can find speaks of three output values, while I get four... [/strike] (I also think it's in error on the values simply being coordinates - rather they seem mostly to be measures of rotation - but some further messing around is called for :P).

Thanks for the hint, in any case! Even if it doesn't save me doing calculations, it'll definitely make them easier (if I understand what is is properly...).

Edit: oops, my bad, the fourth value was actually just a different Echo I had forgotten to comment out...
Plus, I think I may be onto what the different vectors are :).

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 00:29
by zwzsg
Using Spring.TraceScreenRay(0,0,true) and Spring.TraceScreenRay(vsx,vsy,true) where vsx, vsy come from the widget:DrawScreenEffects(vsx,vsy) would already tell you which coordinate of the map you see at the corner of the screen.

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 00:32
by Argh
Using Spring.TraceScreenRay(0,0,true) and Spring.TraceScreenRay(vsx,vsy,true) where vsx, vsy come from the widget:DrawScreenEffects(vsx,vsy) would already tell you which coordinate of the map you see at the corner of the screen.
Wait a minute. Does setting "onlyCoordinates" mean that it'll just take arbitrary x,y? If so, that certainly makes building this easier (at least for OTA POV)!

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 00:33
by SeanHeron
Hey, coolio Zwzsg, that makes my day :D. Be testing that in a minute, thanks a bunch!

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 00:33
by zwzsg
Argh: No. "Only coordinate" means the output is the ground coordinate, even when over a unit or a feature (where by default, it would give the unit ID or the feature ID instead the packed ground coordinates.) The input are already always arbitrary x,y screen coordinates.


SeanHeron: Not tested, but hopefully it'll show you what I meant

Code: Select all

function widget:DrawScreenEffects(vsx,vsy)
	local _,pos1 = Spring.TraceScreenRay(0,0,true,false)
	local _,pos2 = Spring.TraceScreenRay(0,vsy,true,false)
	local _,pos3 = Spring.TraceScreenRay(vsx,0,true,false)
	local _,pos4 = Spring.TraceScreenRay(vsx,vsy,true,false)
	-- when the poses are nil, it means you are outta map
	-- Otherwise, you get the world coordinates of the ground seen at each corner of your screen with:
	local x1,y1,z1=unpack(pos1)
	local x2,y2,z2=unpack(pos2)
	local x3,y3,z3=unpack(pos3)
	local x4,y4,z4=unpack(pos4)
end
Anyway, as lurker said, check http://springrts.com/wiki/Lua_UnsyncedRead#Screen_Trace

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 01:09
by SeanHeron
I can hardly express any further gratitude :P. Needless to say, I definitely wouldn't have guessed at a number of things there for quite a bit!
Just one small change and the whole thing works fine:

Code: Select all

function widget:DrawScreenEffects(vsx,vsy)
	local _,pos1 = Spring.TraceScreenRay(0,0,true,false)
	local _,pos2 = Spring.TraceScreenRay(0,vsy - 1,true,false)
	local _,pos3 = Spring.TraceScreenRay(vsx - 1,0,true,false)
	local _,pos4 = Spring.TraceScreenRay(vsx - 1,vsy - 1,true,false)
	-- when the poses are nil, it means you are outta map
	-- Otherwise, you get the world coordinates of the ground seen at each corner of your screen with:
	local x1,y1,z1=unpack(pos1)
	local x2,y2,z2=unpack(pos2)
	local x3,y3,z3=unpack(pos3)
	local x4,y4,z4=unpack(pos4)
end
And of course I'll need to add something to make it fail less when it tries to unpack "nil" - or just make sure it really does never go off the mapedge :D.

Edit: if you were wondering, the - 1s were an intuitive guess rather than any kind of knowledge... don't ask me why it should be so :P !

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 01:26
by zwzsg
if you were wondering, the - 1s were an intuitive guess rather than any kind of knowledge... don't ask me why it should be so :P !
If vsx is the screen width in pixel, 0 the first pixel, then vsx-1 is the last pixel, I guess.

And of course I'll need to add something to make it fail less when it tries to unpack "nil"
What about:

Code: Select all

function widget:DrawScreenEffects(vsx,vsy)
	local _,pos1 = Spring.TraceScreenRay(0,0,true,false)
	local _,pos2 = Spring.TraceScreenRay(0,vsy - 1,true,false)
	local _,pos3 = Spring.TraceScreenRay(vsx - 1,0,true,false)
	local _,pos4 = Spring.TraceScreenRay(vsx - 1,vsy - 1,true,false)
	local x1,_,z1=unpack(pos1 or {})
	local x2,_,z2=unpack(pos2 or {})
	local x3,_,z3=unpack(pos3 or {})
	local x4,_,z4=unpack(pos4 or {})
end
Then now you have to handle nil xn and zn :wink:

Re: Get displayed screen area (on ground) coordinates ?

Posted: 19 Aug 2009, 13:43
by SeanHeron
Since nil is the only value I'm really interested in, that's pretty good going, thanks for that! I went to sleep quite content knowing what I wanted to do worked in principle :D

However, today I've run into some difficulties - that I don't think are solvable (but no worries, I'll just go back to good old trigonometry :P).
It seems that the Spring.TraceScreenRay in combination with widget:DrawScreenEffect is not matched with Spring.GetCameraState regarding positions - when the cam tells me it's alread standing, the trace value is still changing (ie it either lags or is "more precise" as the screen keeps moving after the camera position has stopped, I guess due to cam-movement smoothing - the later is probably more likely :P).

Under those circumstances it's not really of much help to me, but it was definitely interesting to learn some more! (Plus I'd have been frustrated to continue with geometric calculations thinking I could do it easier otherwise - now I'm quite happy to return to trigonometry :D).

Thanks again to all, will post the widget when I think it's worth trying.

Re: Get displayed screen area (on ground) coordinates ?

Posted: 20 Aug 2009, 02:42
by SeanHeron
Hmm, I have question that is both related and unrelated to the last: I'm looking to intercept camera-movement via the minimap (which is not a problem per se), but to do so precisely, I need to know the position the camera is going to move to (ie the one being hovered over), so that I can make a calculation for the projected position, and move the camera in from the edge as necessary.

I could/can grab this very lazily of the Tooltip - except that the coordinates are gone and replaced by other info when units/features are selected/hovered over... :/ .

So what I'm looking for is whether there is a way to get the position of the little blue diamond that hovers around when you have your cursor above the minimap - my expectation is that this is not available though, and I'll have to calculate it in a few steps after all (admittedly the effort would not be too great).

(P.S. I've tried to look into WorldToolTip, but I can't really fathom it..)

Edit: was speaking about "Spring.GetCurrentTooltip()" regarding the coordinates not always being available. I kindof reckon GetTooltip(x, y) might be helpful, but I'm afraid I can't figure out how to extract more info than the x and y out of that... :( . (and my other hunch is that it's just a function to get the tooltip at any given point - ie of no help to me either...)

Re: Get displayed screen area (on ground) coordinates ?

Posted: 20 Aug 2009, 02:47
by zwzsg
More precisely, pay close attention to TraceScreenRay's last argument.

Re: Get displayed screen area (on ground) coordinates ?

Posted: 20 Aug 2009, 02:49
by SeanHeron
Sweeto, if I'd thought of that earlier, I could have saved myself plenty of trouble! You're faster than greased lightning!

Re: Get displayed screen area (on ground) coordinates ?

Posted: 20 Aug 2009, 02:51
by zwzsg
Oh and you know about mx,my=GetMouseState(), right?

Re: Get displayed screen area (on ground) coordinates ?

Posted: 20 Aug 2009, 03:00
by SeanHeron
I'd currently plonked it into IsAbove, so that's definitely some useful info as well, thanks!
The TraceScreenRay works so easy, it hurts to think I didn't come up with it! Off to bed now, but I'm sure the first rough release will be out tomorrow :D.

Edit: First, very rough but basiclly functional version attached. ... I wouldn't advise looking at the code though, as it's still an ungodly mess (I can already here the voices: "and this poor excuse for coding took you that long... ?" :P ).
I mean, of course feel free to check for malicious code, but if you'd want to expand or change anything, my suggestion would be to wait a few days when I'll be releasing a "spring-cleaned" version.

List of deficiencies:
  • -only works with Rotatable overhead camera view at the moment,
    - view is restricted to straight down, north
    - tracking a unit not supported (ie you will track out the edge)

    - resizing is still a bit patchy (eg it won't lower your zoom level if your view area grows so that you can see the edge on either side).
    - water maps will show you an edge, as all calculations at the moment are from 0 (as ground) rather than lowest point of the map
    - if you make an effort, you can switch into crosshair mode, giving you ugly jumps, and possibly showing you !gasp! the map edge

    - maps with different heights at the mapedge will have unviewable slivers at the higher parts of the edges. This is pretty much inherent in this kind of thing though, so no solution to that intended really. It helps to reduce the Camera's Field of View,though this seems to reduce how far you can zoom out.
camera_map_edge.lua
Just for seeing how it runs, don't bother looking at the code !
(23.58 KiB) Downloaded 126 times
Some heavy refactoring and cleaning up is called for, and is what I intend to do as the next steps!
Sean

Re: Get displayed screen area (on ground) coordinates ?

Posted: 07 Sep 2009, 20:11
by SeanHeron
Well, a few days turned into a few more days - but I now have gotten round to somewhat cleaning the thing up. (You might find it still suffers somewhat from comment overload - but I need these hints to myself).

Link to most current version in SVN here.

It still has all the deficiencies listed in the post above - plus I've noticed that the minimap movement is somewhat glitched, Middlemousebutton held and released is not quite working as advertised. But since that might be handled differently for the Overviewcam (which is what I really want to get this working with), I can't really be bothered to fix that.

Oh, the other thing I'm not bothered about - the widget is broken if switched on during game (as one of the values is set from GamePreload) - as I plan to include this widget in a game and not have the widgets messable with, that isn't of a worry for me...

Edit: Not to forget! Many thanks to all those that helped me out with my noob questions here, especially Zwzsg !

P.S. The next thing I plan on attacking is getting it to work at angles, rather than straight down - ie supporting the Overview cam!

Re: Get displayed screen area (on ground) coordinates ?

Posted: 07 Sep 2009, 21:36
by Beherith
I could see use for this, by restricting a maps typemap to a tiny bit smaller, say 16-32 heightmap pixels