00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef projection_h
00014 #define projection_h
00015
00016 #include <cml/mathlib/matrix_concat.h>
00017 #include <cml/mathlib/vector_transform.h>
00018
00019
00020
00021 namespace cml {
00022
00023 namespace detail {
00024
00025 template < typename E > void
00026 divide_by_w(vector< E,fixed<4> >& v) {
00027 v *= E(1) / v[3];
00028 }
00029
00030 }
00031
00032
00033
00034
00035
00036
00037 template <class MatT_1, class MatT_2, class MatT_3, class MatT_4, class VecT>
00038 vector< typename VecT::value_type, fixed<3> > project_point(
00039 const MatT_1& model,
00040 const MatT_2& view,
00041 const MatT_3& projection,
00042 const MatT_4& viewport,
00043 const VecT& p)
00044 {
00045 return project_point(
00046 detail::matrix_concat_transforms_4x4(model,view),
00047 projection,
00048 viewport,
00049 p
00050 );
00051 }
00052
00053
00054
00055
00056
00057
00058 template < class MatT_1, class MatT_2, class MatT_3, class VecT >
00059 vector< typename VecT::value_type, fixed<3> > project_point(
00060 const MatT_1& modelview,
00061 const MatT_2& projection,
00062 const MatT_3& viewport,
00063 const VecT& p)
00064 {
00065 typedef vector< typename VecT::value_type, fixed<3> > vector3_type;
00066 typedef vector< typename VecT::value_type, fixed<4> > vector4_type;
00067 typedef typename vector3_type::value_type value_type;
00068
00069 detail::CheckVec3(p);
00070
00071 vector4_type result = transform_vector_4D(
00072 detail::matrix_concat_transforms_4x4(
00073 modelview,
00074 detail::matrix_concat_transforms_4x4(
00075 projection,
00076 viewport
00077 )
00078 ),
00079 vector4_type(p[0],p[1],p[2],value_type(1))
00080 );
00081 detail::divide_by_w(result);
00082 return vector3_type(result[0],result[1],result[2]);
00083 }
00084
00085
00086
00087
00088
00089
00090 template <class MatT_1, class MatT_2, class MatT_3, class MatT_4, class VecT>
00091 vector< typename VecT::value_type, fixed<3> > unproject_point(
00092 const MatT_1& model,
00093 const MatT_2& view,
00094 const MatT_3& projection,
00095 const MatT_4& viewport,
00096 const VecT& p)
00097 {
00098 return unproject_point(
00099 detail::matrix_concat_transforms_4x4(model,view),
00100 projection,
00101 viewport,
00102 p
00103 );
00104 }
00105
00106
00107
00108
00109
00110
00111 template < class MatT_1, class MatT_2, class MatT_3, class VecT >
00112 vector< typename VecT::value_type, fixed<3> > unproject_point(
00113 const MatT_1& modelview,
00114 const MatT_2& projection,
00115 const MatT_3& viewport,
00116 const VecT& p)
00117 {
00118 typedef vector< typename VecT::value_type, fixed<3> > vector3_type;
00119 typedef vector< typename VecT::value_type, fixed<4> > vector4_type;
00120 typedef typename vector3_type::value_type value_type;
00121
00122 detail::CheckVec3(p);
00123
00124 vector4_type result = transform_vector_4D(
00125 inverse(
00126 detail::matrix_concat_transforms_4x4(
00127 modelview,
00128 detail::matrix_concat_transforms_4x4(
00129 projection,
00130 viewport
00131 )
00132 )
00133 ),
00134 vector4_type(p[0],p[1],p[2],value_type(1))
00135 );
00136 detail::divide_by_w(result);
00137 return vector3_type(result[0],result[1],result[2]);
00138 }
00139
00140 }
00141
00142 #endif