]> Dogcows Code - chaz/yoink/blob - src/moof/cml/mathlib/picking.h
fixes for newer versions of g++
[chaz/yoink] / src / moof / cml / mathlib / picking.h
1 /* -*- C++ -*- ------------------------------------------------------------
2
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
4
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
7
8 *-----------------------------------------------------------------------*/
9 /** @file
10 * @brief
11 */
12
13 #ifndef picking_h
14 #define picking_h
15
16 #include <cml/mathlib/projection.h>
17
18 /* Functions for picking with rays, volumes, and drag-enclosed volumes. */
19
20 namespace cml {
21
22 /* Support function for extracting the near and far depth range values from
23 * a viewport matrix.
24 */
25
26 namespace detail {
27
28 // NOTE: Changed 'near' and 'far' to 'n' and 'f' to work around windows.h
29 // 'near' and 'far' macros.
30
31 template < class MatT, typename Real > void
32 depth_range_from_viewport_matrix(const MatT& viewport, Real& n, Real& f)
33 {
34 detail::CheckMatHomogeneous3D(viewport);
35
36 n = viewport.basis_element(3,2);
37 f = viewport.basis_element(2,2) + n;
38 }
39
40 } // namespace detail
41
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).
46 *
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.
50 *
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.
56 */
57
58 template < class MatT_1, class MatT_2, class MatT_3, typename E, class A >
59 void make_pick_ray(
60 E pick_x,
61 E pick_y,
62 const MatT_1& view,
63 const MatT_2& projection,
64 const MatT_3& viewport,
65 vector<E,A>& origin,
66 vector<E,A>& direction,
67 bool normalize = true)
68 {
69 typedef vector<E,A> vector_type;
70 typedef typename vector_type::value_type value_type;
71
72 // NOTE: Changed 'near' and 'far' to 'n' and 'f' to work around
73 // windows.h 'near' and 'far' macros.
74 value_type n, f;
75 detail::depth_range_from_viewport_matrix(viewport, n, f);
76
77 origin =
78 unproject_point(
79 view,projection,viewport,vector_type(pick_x,pick_y,n)
80 );
81 direction =
82 unproject_point(
83 view,projection,viewport,vector_type(pick_x,pick_y,f)
84 ) - origin;
85 if (normalize) {
86 direction.normalize();
87 }
88 }
89
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.
93 *
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.
96 *
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
99 * argument.
100 *
101 * The 'normalize' argument indicates whether the output planes should be
102 * normalized; its default value is 'true'.
103 *
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.
109 */
110
111 template < class MatT_1, class MatT_2, typename Real >
112 void make_pick_volume(
113 Real pick_x,
114 Real pick_y,
115 Real pick_width,
116 Real pick_height,
117 Real viewport_x,
118 Real viewport_y,
119 Real viewport_width,
120 Real viewport_height,
121 const MatT_1& view,
122 const MatT_2& projection,
123 Real planes[6][4],
124 ZClip z_clip,
125 bool normalize = true)
126 {
127 // FIXME: Should be promoted type...
128 typedef matrix<
129 Real, fixed<4,4>,
130 typename MatT_1::basis_orient, typename MatT_1::layout >
131 matrix_type;
132
133 matrix_type pick;
134 matrix_pick(
135 pick, pick_x, pick_y, pick_width, pick_height,
136 viewport_x, viewport_y, viewport_width, viewport_height
137 );
138 cml::extract_frustum_planes(
139 view,detail::matrix_concat_transforms_4x4(projection,pick),
140 planes,z_clip,normalize);
141 }
142
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
146 * coordinates.
147 *
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.
150 *
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
153 * argument.
154 *
155 * The 'normalize' argument indicates whether the output planes should be
156 * normalized; its default value is 'true'.
157 *
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.
163 */
164
165 template < class MatT_1, class MatT_2, typename Real >
166 void make_pick_drag_volume(
167 Real pick_x1,
168 Real pick_y1,
169 Real pick_x2,
170 Real pick_y2,
171 Real viewport_x,
172 Real viewport_y,
173 Real viewport_width,
174 Real viewport_height,
175 const MatT_1& view,
176 const MatT_2& projection,
177 Real planes[6][4],
178 ZClip z_clip,
179 bool normalize = true)
180 {
181 typedef Real value_type;
182
183 make_pick_volume(
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
190 );
191 }
192
193 } // namespace cml
194
195 #endif
This page took 0.039983 seconds and 4 git commands to generate.