]> Dogcows Code - chaz/yoink/blob - src/Moof/cml/mathlib/projection.h
socket and packet copying
[chaz/yoink] / src / Moof / cml / mathlib / projection.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 projection_h
14 #define projection_h
15
16 #include <cml/mathlib/matrix_concat.h>
17 #include <cml/mathlib/vector_transform.h>
18
19 /* Functions for projection and 'unprojection' of points in 3D. */
20
21 namespace cml {
22
23 namespace detail {
24
25 template < typename E > void
26 divide_by_w(vector< E,fixed<4> >& v) {
27 v *= E(1) / v[3];
28 }
29
30 } // namespace detail
31
32 /* Project a point to screen space using the given model, view, projection,
33 * and viewport matrices. The z value of the returned point is a depth value
34 * in the range specified by the viewport matrix.
35 */
36
37 template <class MatT_1, class MatT_2, class MatT_3, class MatT_4, class VecT>
38 vector< typename VecT::value_type, fixed<3> > project_point(
39 const MatT_1& model,
40 const MatT_2& view,
41 const MatT_3& projection,
42 const MatT_4& viewport,
43 const VecT& p)
44 {
45 return project_point(
46 detail::matrix_concat_transforms_4x4(model,view),
47 projection,
48 viewport,
49 p
50 );
51 }
52
53 /* Project a point to screen space using the given modelview, projection, and
54 * viewport matrices. The z value of the returned point is a depth value in
55 * the range specified by the viewport matrix.
56 */
57
58 template < class MatT_1, class MatT_2, class MatT_3, class VecT >
59 vector< typename VecT::value_type, fixed<3> > project_point(
60 const MatT_1& modelview,
61 const MatT_2& projection,
62 const MatT_3& viewport,
63 const VecT& p)
64 {
65 typedef vector< typename VecT::value_type, fixed<3> > vector3_type;
66 typedef vector< typename VecT::value_type, fixed<4> > vector4_type;
67 typedef typename vector3_type::value_type value_type;
68
69 detail::CheckVec3(p);
70
71 vector4_type result = transform_vector_4D(
72 detail::matrix_concat_transforms_4x4(
73 modelview,
74 detail::matrix_concat_transforms_4x4(
75 projection,
76 viewport
77 )
78 ),
79 vector4_type(p[0],p[1],p[2],value_type(1))
80 );
81 detail::divide_by_w(result);
82 return vector3_type(result[0],result[1],result[2]);
83 }
84
85 /* 'Unproject' a point from screen space using the given model, view,
86 * projection, and viewport matrices. The z value of the input point is a
87 * depth value in the range specified by the viewport matrix.
88 */
89
90 template <class MatT_1, class MatT_2, class MatT_3, class MatT_4, class VecT>
91 vector< typename VecT::value_type, fixed<3> > unproject_point(
92 const MatT_1& model,
93 const MatT_2& view,
94 const MatT_3& projection,
95 const MatT_4& viewport,
96 const VecT& p)
97 {
98 return unproject_point(
99 detail::matrix_concat_transforms_4x4(model,view),
100 projection,
101 viewport,
102 p
103 );
104 }
105
106 /* 'Unproject' a point from screen space using the given modelview,
107 * projection, and viewport matrices. The z value of the input point is a
108 * depth value in the range specified by the viewport matrix.
109 */
110
111 template < class MatT_1, class MatT_2, class MatT_3, class VecT >
112 vector< typename VecT::value_type, fixed<3> > unproject_point(
113 const MatT_1& modelview,
114 const MatT_2& projection,
115 const MatT_3& viewport,
116 const VecT& p)
117 {
118 typedef vector< typename VecT::value_type, fixed<3> > vector3_type;
119 typedef vector< typename VecT::value_type, fixed<4> > vector4_type;
120 typedef typename vector3_type::value_type value_type;
121
122 detail::CheckVec3(p);
123
124 vector4_type result = transform_vector_4D(
125 inverse(
126 detail::matrix_concat_transforms_4x4(
127 modelview,
128 detail::matrix_concat_transforms_4x4(
129 projection,
130 viewport
131 )
132 )
133 ),
134 vector4_type(p[0],p[1],p[2],value_type(1))
135 );
136 detail::divide_by_w(result);
137 return vector3_type(result[0],result[1],result[2]);
138 }
139
140 } // namespace cml
141
142 #endif
This page took 0.042394 seconds and 4 git commands to generate.