]>
Dogcows Code - chaz/yoink/blob - src/cml/mathlib/picking.h
1 /* -*- C++ -*- ------------------------------------------------------------
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
8 *-----------------------------------------------------------------------*/
16 #include <cml/mathlib/projection.h>
18 /* Functions for picking with rays, volumes, and drag-enclosed volumes. */
22 /* Support function for extracting the near and far depth range values from
28 // NOTE: Changed 'near' and 'far' to 'n' and 'f' to work around windows.h
29 // 'near' and 'far' macros.
31 template < class MatT
, typename Real
> void
32 depth_range_from_viewport_matrix(const MatT
& viewport
, Real
& n
, Real
& f
)
34 detail::CheckMatHomogeneous3D(viewport
);
36 n
= viewport
.basis_element(3,2);
37 f
= viewport
.basis_element(2,2) + n
;
42 /* Make a pick ray given screen coordinates and view, projection, and viewport
43 * matrices. The origin of the ray lies in the near plane of the frustum; the
44 * direction vector extends to the far plane if 'normalize' is false, and is
45 * made unit-length if 'normalize' is true (its default value).
47 * Note that the origin of the ray lies in the near plane rather than
48 * coinciding with the position of the virtual camera, as the latter gives
49 * incorrect results when the projection is orthographic.
51 * Note also that the screen y coordinate increases from bottom to top rather
52 * than top to bottom. If mouse coordinates are returned in window space where
53 * the y coordinate increases from top to bottom (as is often the case), the
54 * y value should be recomputed as 'y = <window height> - y' before being
55 * submitted to this function.
58 template < class MatT_1
, class MatT_2
, class MatT_3
, typename E
, class A
>
63 const MatT_2
& projection
,
64 const MatT_3
& viewport
,
66 vector
<E
,A
>& direction
,
67 bool normalize
= true)
69 typedef vector
<E
,A
> vector_type
;
70 typedef typename
vector_type::value_type value_type
;
72 // NOTE: Changed 'near' and 'far' to 'n' and 'f' to work around
73 // windows.h 'near' and 'far' macros.
75 detail::depth_range_from_viewport_matrix(viewport
, n
, f
);
79 view
,projection
,viewport
,vector_type(pick_x
,pick_y
,n
)
83 view
,projection
,viewport
,vector_type(pick_x
,pick_y
,f
)
86 direction
.normalize();
90 /* Make a pick volume given the screen coordinates of the center of the
91 * picking rect, the width and height of the picking rect, and view and
92 * projection matrices.
94 * The volume is loaded into the 'planes' array. The planes are of the form
95 * ax+by+cz+d = 0, and are in the order left, right, bottom, top, near, far.
97 * The z_clip argument should be either z_clip_neg_one or z_clip_zero, and
98 * should correspond to the near z-clipping range of the projection matrix
101 * The 'normalize' argument indicates whether the output planes should be
102 * normalized; its default value is 'true'.
104 * Note that the screen y coordinate increases from bottom to top rather
105 * than top to bottom. If mouse coordinates are returned in window space where
106 * the y coordinate increases from top to bottom (as is often the case), the
107 * y value should be recomputed as 'y = <window height> - y' before being
108 * submitted to this function.
111 template < class MatT_1
, class MatT_2
, typename Real
>
112 void make_pick_volume(
120 Real viewport_height
,
122 const MatT_2
& projection
,
125 bool normalize
= true)
127 // FIXME: Should be promoted type...
130 typename
MatT_1::basis_orient
, typename
MatT_1::layout
>
135 pick
, pick_x
, pick_y
, pick_width
, pick_height
,
136 viewport_x
, viewport_y
, viewport_width
, viewport_height
138 cml::extract_frustum_planes(
139 view
,detail::matrix_concat_transforms_4x4(projection
,pick
),
140 planes
,z_clip
,normalize
);
143 /* Make a pick volume given two opposite corners of a rectangle in screen
144 * space, and view and projection matrices. The corners of the screen rect
145 * need not be in any particular 'order' with regard to the values of the
148 * The volume is loaded into the 'planes' array. The planes are of the form
149 * ax+by+cz+d = 0, and are in the order left, right, bottom, top, near, far.
151 * The z_clip argument should be either z_clip_neg_one or z_clip_zero, and
152 * should correspond to the near z-clipping range of the projection matrix
155 * The 'normalize' argument indicates whether the output planes should be
156 * normalized; its default value is 'true'.
158 * Note that the screen y coordinate increases from bottom to top rather
159 * than top to bottom. If mouse coordinates are returned in window space where
160 * the y coordinate increases from top to bottom (as is often the case), the
161 * y value should be recomputed as 'y = <window height> - y' before being
162 * submitted to this function.
165 template < class MatT_1
, class MatT_2
, typename Real
>
166 void make_pick_drag_volume(
174 Real viewport_height
,
176 const MatT_2
& projection
,
179 bool normalize
= true)
181 typedef Real value_type
;
184 (pick_x1
+pick_x2
)*value_type(.5),
185 (pick_y1
+pick_y2
)*value_type(.5),
186 std::fabs(pick_x2
-pick_x1
),
187 std::fabs(pick_y2
-pick_y1
),
188 viewport_x
, viewport_y
, viewport_width
, viewport_height
,
189 view
, projection
, planes
, z_clip
, normalize
This page took 0.046226 seconds and 5 git commands to generate.