Viewport, Window Rect and View Rect Interpretation
From Virtools Wiki
Contents |
Terminology
The position of the rects returned from the CKRenderContext depends on the "ScreenSize" setting in General Preferences -> 3D Layout - Rendering. This is very important for checking mouse positions and picking.
- "Window Rect" is the rect returned from CKRenderContext::GetWindowRect
- "View Rect" is the rect turned from CKRenderContext::GetViewRect
- "Context Window" is the area within the 3D Layout portion of the Dev interface where 2D/3D images might be drawn. However, if your "Context Window" is not the same ratio as your camera, you will have some dead space around your viewport. How this extra space is treated depends on your "ScreenSize" setting.
- "viewport" is the area with the 3D Layout where 2D/3D images are actually drawn.
- "relative to" means that if A is relative to B, then if the top/left of A is at the same position as the top/left of B, the top/left of A will be (0,0)
- you can get the "Screen Relative" Window Rect by setting ScreenRelative to true when calling CKContext::GetWindowRect
If Screen size is set to Window Extents:
1. Window Rect (NOT screen relative) is the size of the Context Window, and the position is relative to the Context Window (top/left always 0,0).
2. Window Rect (ScreenRelative) is the size of the Context Window, position relative to top left of the screen.
3. View Rect is the Viewport size and position is relative to the Context Window.
If Screen size is set to a fixed resolution or Custom (which is actually also fixed):
1. Window Rect (NOT screen relative) is the size AND position of the Viewport relative to the Context Window.
2. Window Rect (ScreenRelative) is the size AND position of the Viewport relative to the screen.
3. View Rect is the viewport size only as it is relative to the Window Rect (top/left always 0,0).
This may be further complicated if you have odd camera ratios and use Ignore Camera Ratio, I haven't tried it.
Note: It is possible to use an incorrect calculation and still get valid results because, for example, if your viewport is at the same position as your Context Window (i.e. top left of viewport is 0,0 relative to Context Window), calculations which don't take into account the difference in positions won't have a problem and will appear to work correctly.
Mouse Position and Picking
So unless you're in the thick of 2D GUIland, maybe you're wondering how this stuff might actually be useful. If you aren't sure about what certain terms might refer to, see my previous post for definitions.
Mouse Position
When you get the mouse position, you have two options, absolute and not absolute. If you get the "absolute" mouse position, the coordinates will be relative to the upper left corner of the screen. This is the same as having the "Windowed Mode" set to false in the Get Mouse Position BB. If you get the "not-absolute" mouse position, the coordinates will be relative to the upper left corner of the Viewport. This is the same as having the "Windowed Mode" set to true in the Get Mouse Position BB.
Luckily, these values are fairly straightfoward. Most of the time you will simply want to get the non-absolute coordinates as this will be the same as the coordinates used by non-homogenous 2D entities for position and size.
So for example, if you want to tell if the mouse is inside a 2D Entity, simply:
Code: // pIns: // Entity2D ent; InputManager im = InputManager.Cast(bc.GetManagerByGuid(GetInputManagerGuid())); Vector2D vecMouse; im.GetMousePosition( vecMouse, false ); Rect rctEnt; ent.GetRect( rctEnt ); if( rctEnd.IsInside( vecMouse ) ) bc.OutputToConsole( "Inside", false ); else bc.OutputToConsole( "Outside", false);
Picking
There are two methods you can use to pick with: Pick(...) and Pick2D(...). Both require a set of 2D Coordinates to pick an object. They only require 2D Coordinates, and not a more complex origin/direction set, because the camera's direction is used for this information, and in the case of picking 2D Entities, isn't even needed. If you need to pick something not from the current camera's perspective, look into Ray Intersection. Pick(...) is actually just a simplified version of Ray Intersection, however the coordinates needed to correctly Pick(...) objects are the same as with Pick2D(...) so read on.
Unfortunately, picking with Pick(...) and Pick2D(...) isn't as simple as just testing against rects. Pick(...) and Pick2D(...) want coordinates relative to the "Context Window". So for example, this means that neither absolute nor non-absolute mouse coordinates will correctly pick entities.
As mentioned above, "It is possible to use an incorrect calculation and still get valid results". This is one of those situations. If you have "ScreenSize" set to "Window Extents", Pick2D(...) will work correctly if you use non-absolute mouse coordinates, but if you change your ScreenSize to a fixed resolution, suddenly it won't and there will be much crying and gnashing of teeth.
So, to solve this dilemma you have two options. You can figure out the 2D Vector math from my previous post to calculate the offset from one of the 2 mouse position coordinate systems to the system that the pick functions want, which isn't difficult, but will take a few more lines of code, or:
Code: Vector2D vecMouse; im.GetMousePosition(vecMouse, true); // get the Absolute! Yah no kidding. RenderContext rc = bc.GetPlayerRenderContext(); // works in Dev too! Don't let the word "player" throw you. rc.ScreenToClient(vecMouse); // does the coord system conversion for us Entity2D ent = rc.Pick2D(vecMouse); // pick something if( ent ) bc.OutputToConsole( ent.GetName() ); // print name of entity picked, or you can do whatever you want
Hopefully this is all anyone will ever need as far as figuring out what set of coordinates they need for any non-homogenous 2D situation.
