From cffe4156eb1519046eb883798f153cce2eb2716c Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 16 Feb 2007 01:49:45 +0000 Subject: [PATCH] explicit stereo lens control --- panda/src/gobj/matrixLens.I | 137 +++++++++++++++++++++++++++++++++- panda/src/gobj/matrixLens.cxx | 13 ++++ panda/src/gobj/matrixLens.h | 18 +++++ 3 files changed, 165 insertions(+), 3 deletions(-) diff --git a/panda/src/gobj/matrixLens.I b/panda/src/gobj/matrixLens.I index c23dc46d41..f7d10311ee 100644 --- a/panda/src/gobj/matrixLens.I +++ b/panda/src/gobj/matrixLens.I @@ -23,7 +23,8 @@ //////////////////////////////////////////////////////////////////// INLINE MatrixLens:: MatrixLens() : - _user_mat(LMatrix4f::ident_mat()) + _user_mat(LMatrix4f::ident_mat()), + _ml_flags(0) { // The default film size for a MatrixLens is 2, which makes the // default range for both X and Y be [-1, 1]. This also, @@ -39,7 +40,10 @@ MatrixLens() : INLINE MatrixLens:: MatrixLens(const MatrixLens ©) : Lens(copy), - _user_mat(copy._user_mat) + _user_mat(copy._user_mat), + _left_eye_mat(copy._left_eye_mat), + _right_eye_mat(copy._right_eye_mat), + _ml_flags(copy._ml_flags) { } @@ -51,7 +55,10 @@ MatrixLens(const MatrixLens ©) : INLINE void MatrixLens:: operator = (const MatrixLens ©) { Lens::operator = (copy); - _user_mat = copy.get_user_mat(); + _user_mat = copy._user_mat; + _left_eye_mat = copy._left_eye_mat; + _right_eye_mat = copy._right_eye_mat; + _ml_flags = copy._ml_flags; } //////////////////////////////////////////////////////////////////// @@ -88,3 +95,127 @@ INLINE const LMatrix4f &MatrixLens:: get_user_mat() const { return _user_mat; } + +//////////////////////////////////////////////////////////////////// +// Function: MatrixLens::set_left_eye_mat +// Access: Published +// Description: Sets a custom projection matrix for the left eye. +// This is only used if the lens is attached to a stereo +// camera, in which case the left eye matrix will be +// used to draw the scene in the left eye (but the +// center matrix--the user_mat--will still be used to +// cull the scene). +// +// This matrix should not be too different from the +// center matrix (set by set_user_mat()) or culling +// errors may become obvious. +//////////////////////////////////////////////////////////////////// +INLINE void MatrixLens:: +set_left_eye_mat(const LMatrix4f &left_eye_mat) { + _left_eye_mat = left_eye_mat; + _ml_flags |= MF_has_left_eye; + adjust_comp_flags(CF_mat, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: MatrixLens::clear_left_eye_mat +// Access: Published +// Description: Removes the custom projection matrix set for the left +// eye, and uses the center matrix (set by set_user_mat) +// instead. +//////////////////////////////////////////////////////////////////// +INLINE void MatrixLens:: +clear_left_eye_mat() { + _ml_flags &= ~MF_has_left_eye; + adjust_comp_flags(CF_mat, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: MatrixLens::has_left_eye_mat +// Access: Published +// Description: Returns true if the camera has a custom projection +// matrix set for the left eye, or false if the center +// matrix (set by set_user_mat) will be used for the +// left eye. +//////////////////////////////////////////////////////////////////// +INLINE bool MatrixLens:: +has_left_eye_mat() const { + return (_ml_flags & MF_has_left_eye) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: MatrixLens::get_left_eye_mat +// Access: Published +// Description: Returns the custom projection matrix for the left +// eye, if any, or the center matrix if there is no +// custom matrix set for the left eye. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4f &MatrixLens:: +get_left_eye_mat() const { + if ((_ml_flags & MF_has_left_eye) != 0) { + return _left_eye_mat; + } + return _user_mat; +} + +//////////////////////////////////////////////////////////////////// +// Function: MatrixLens::set_right_eye_mat +// Access: Published +// Description: Sets a custom projection matrix for the right eye. +// This is only used if the lens is attached to a stereo +// camera, in which case the right eye matrix will be +// used to draw the scene in the right eye (but the +// center matrix--the user_mat--will still be used to +// cull the scene). +// +// This matrix should not be too different from the +// center matrix (set by set_user_mat()) or culling +// errors may become obvious. +//////////////////////////////////////////////////////////////////// +INLINE void MatrixLens:: +set_right_eye_mat(const LMatrix4f &right_eye_mat) { + _right_eye_mat = right_eye_mat; + _ml_flags |= MF_has_right_eye; + adjust_comp_flags(CF_mat, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: MatrixLens::clear_right_eye_mat +// Access: Published +// Description: Removes the custom projection matrix set for the right +// eye, and uses the center matrix (set by set_user_mat) +// instead. +//////////////////////////////////////////////////////////////////// +INLINE void MatrixLens:: +clear_right_eye_mat() { + _ml_flags &= ~MF_has_right_eye; + adjust_comp_flags(CF_mat, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: MatrixLens::has_right_eye_mat +// Access: Published +// Description: Returns true if the camera has a custom projection +// matrix set for the right eye, or false if the center +// matrix (set by set_user_mat) will be used for the +// right eye. +//////////////////////////////////////////////////////////////////// +INLINE bool MatrixLens:: +has_right_eye_mat() const { + return (_ml_flags & MF_has_right_eye) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: MatrixLens::get_right_eye_mat +// Access: Published +// Description: Returns the custom projection matrix for the right +// eye, if any, or the center matrix if there is no +// custom matrix set for the right eye. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4f &MatrixLens:: +get_right_eye_mat() const { + if ((_ml_flags & MF_has_right_eye) != 0) { + return _right_eye_mat; + } + return _user_mat; +} diff --git a/panda/src/gobj/matrixLens.cxx b/panda/src/gobj/matrixLens.cxx index 5a5a4a1b4b..031210267f 100644 --- a/panda/src/gobj/matrixLens.cxx +++ b/panda/src/gobj/matrixLens.cxx @@ -66,6 +66,19 @@ write(ostream &out, int indent_level) const { void MatrixLens:: compute_projection_mat() { _projection_mat = get_lens_mat_inv() * _user_mat * get_film_mat(); + + if (_ml_flags & MF_has_left_eye) { + _projection_mat_left = get_lens_mat_inv() * _left_eye_mat * get_film_mat(); + } else { + _projection_mat_left = _projection_mat; + } + + if (_ml_flags & MF_has_right_eye) { + _projection_mat_right = get_lens_mat_inv() * _right_eye_mat * get_film_mat(); + } else { + _projection_mat_right = _projection_mat; + } + adjust_comp_flags(CF_projection_mat_inv, CF_projection_mat); } diff --git a/panda/src/gobj/matrixLens.h b/panda/src/gobj/matrixLens.h index f417fdfcc1..d192d1c4e6 100644 --- a/panda/src/gobj/matrixLens.h +++ b/panda/src/gobj/matrixLens.h @@ -44,6 +44,16 @@ PUBLISHED: INLINE void set_user_mat(const LMatrix4f &user_mat); INLINE const LMatrix4f &get_user_mat() const; + INLINE void set_left_eye_mat(const LMatrix4f &user_mat); + INLINE void clear_left_eye_mat(); + INLINE bool has_left_eye_mat() const; + INLINE const LMatrix4f &get_left_eye_mat() const; + + INLINE void set_right_eye_mat(const LMatrix4f &user_mat); + INLINE void clear_right_eye_mat(); + INLINE bool has_right_eye_mat() const; + INLINE const LMatrix4f &get_right_eye_mat() const; + public: virtual PT(Lens) make_copy() const; virtual bool is_linear() const; @@ -55,6 +65,14 @@ protected: private: LMatrix4f _user_mat; + LMatrix4f _left_eye_mat; + LMatrix4f _right_eye_mat; + + enum MLFlags { + MF_has_left_eye = 0x001, + MF_has_right_eye = 0x002, + }; + int _ml_flags; public: static void register_with_read_factory();