Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   Related Pages  

sglPick.hpp

00001 /*****************************************************************************
00002  * SGL: A Scene Graph Library
00003  *
00004  * Copyright (C) 1997-2001  Scott McMillan   All Rights Reserved.
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public
00017  * License along with this library; if not, write to the Free
00018  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  *****************************************************************************
00020  *     File: sglPick.hpp
00021  *  Created: 18 April 2001
00022  *  Summary: stores the probe traversal state (very similar to cull traversal)
00023  *****************************************************************************/
00024 
00025 #ifndef __SGL_PICK_HPP
00026 #define __SGL_PICK_HPP
00027 
00028 #include <sgl.h>
00029 #include <sglProbe.hpp>
00030 
00031 #include <vector>
00032 
00033 class sglNode;
00034 
00035 //----------------------------------------------------------------------------
00036 
00040 template <class T>
00041 class SGL_DLL_API sglPick : public sglProbeTemplate<T>
00042 {
00043 public: // Sub types
00044    class SGL_DLL_API PickResult : public sglProbeTemplate<T>::ProbeResult
00045    {
00046    public:
00047       vector<sglNode*>     m_path;  // path to picked geoset
00048 
00049    public:
00050       PickResult() : sglProbeTemplate<T>::ProbeResult() {}
00051       virtual ~PickResult() { reset(); }  // necessary?
00052 
00053       virtual void reset()
00054          {
00055             m_path.clear();
00056             resetInternal();
00057          }
00058    };
00059 
00060 public:
00062    sglPick(vector<PickResult*> *result_pool = NULL);
00063 
00065    virtual ~sglPick();
00066 
00073    void setPickFrustum(const sglMat4<T>    &pick_matrix,
00074                        const sglFrustum<T> &pick_frustum);
00075 
00079    virtual void reset();
00080 
00082    vector<sglNode*> &getPath() { return m_path; }
00083 
00087    sglFrustum<T> &getOrigPickFrustum() { return m_orig_pick_frustum; }
00089    sglFrustum<T> &getPickFrustum()     { return m_current_pick_frustum; }
00090 
00098    void addHit(const sglGeode *geode, const sglDrawable *geometry);
00099 
00102    const vector<PickResult*> &getResults() const { return m_results; }
00103 
00104    // -------- push/pop transform functions (used internally) ---------
00106    template <class S>
00107    void pushScale(S scale,
00108                   S inv_scale,
00109                   sglFrustum<T> &old_pick_frustum,
00110                   sglMat4<T>    &old_matrix,
00111                   sglFrustum<T> &old_view_frustum)
00112       {
00113          if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00114                        eLOD_VIEW|eBILLBOARD_VIEW))
00115          {
00116             // save the original view matrix
00117             old_matrix = m_modelview_matrix;
00118 
00119             // compute the new view matrix
00120             m_modelview_matrix.scale(old_matrix, scale, scale, scale);
00121 
00122             // compute a new view frustum
00123             if (m_mode & eUNPROJECT_VIEW) // |eUNSCALE_VIEW
00124             {
00125                old_view_frustum = m_current_view_frustum;
00126                m_current_view_frustum.scale(old_view_frustum, inv_scale);
00127             }
00128          }
00129 
00130          // store the original pick frustum so that i don't have to inverse
00131          // transform it during the pop
00132          old_pick_frustum = m_current_pick_frustum;
00133 
00134          // scale the original pick frustum
00135          m_current_pick_frustum.scale(old_pick_frustum, inv_scale);
00136       }
00137 
00139    template <class S>
00140    void pushTranslate(S tx, S ty, S tz,
00141                       sglFrustum<T> &old_pick_frustum,
00142                       sglMat4<T>    &old_matrix,
00143                       sglFrustum<T> &old_view_frustum)
00144       {
00145          if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00146                        eLOD_VIEW|eBILLBOARD_VIEW))
00147          {
00148             // save the original view matrix
00149             old_matrix = m_modelview_matrix;
00150 
00151             // compute the new view matrix
00152             m_modelview_matrix.translate(old_matrix, tx, ty, tz);
00153 
00154             // compute a new view frustum
00155             if (m_mode & eUNPROJECT_VIEW)
00156             {
00157                old_view_frustum = m_current_view_frustum;
00158                m_current_view_frustum.translate(old_view_frustum,
00159                                                 -tx, -ty, -tz);
00160             }
00161          }
00162 
00163          // store the original pick frustum so that i don't have to inverse
00164          // transform it during the pop
00165          old_pick_frustum = m_current_pick_frustum;
00166 
00167          // translate the original pick frustum
00168          m_current_pick_frustum.translate(old_pick_frustum, -tx, -ty, -tz);
00169       }
00170 
00171    // transform - HACK Windoze could not deal with the following function
00172    // being called push() when compiling sglTransform
00173    template <class S>
00174    void pushTransform(const sglMat4<S> &xform,
00175                       const sglMat4<S> &inv_xform,
00176                       sglFrustum<T> &old_pick_frustum,
00177                       sglMat4<T>    &old_matrix,
00178                       sglFrustum<T> &old_view_frustum)
00179       {
00180          if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00181                        eLOD_VIEW|eBILLBOARD_VIEW))
00182          {
00183             // save the original view matrix
00184             old_matrix = m_modelview_matrix;
00185 
00186             // compute the new view matrix
00187             m_modelview_matrix.mul(xform, old_matrix);
00188 
00189             // compute a new view frustum
00190             if (m_mode & eUNPROJECT_VIEW)
00191             {
00192                old_view_frustum = m_current_view_frustum;
00193                m_current_view_frustum.mul(old_view_frustum, inv_xform);
00194             }
00195          }
00196 
00197          // store the original pick frustum so that i don't have to inverse
00198          // transform it during the pop
00199          old_pick_frustum = m_current_pick_frustum;
00200 
00201          // transform the original pick frustum
00202          m_current_pick_frustum.mul(old_pick_frustum, inv_xform);
00203       }
00204 
00205    // pop the transform (restore the old values).
00206    void pop(sglFrustum<T> &old_pick_frustum,
00207             sglMat4<T>    &old_matrix,
00208             sglFrustum<T> &old_view_frustum)
00209       {
00210          m_current_pick_frustum = old_pick_frustum;
00211 
00212          if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00213                        eLOD_VIEW|eBILLBOARD_VIEW))
00214          {
00215             m_modelview_matrix = old_matrix;
00216 
00217             // restore the old view frustum
00218             if (m_mode & eUNPROJECT_VIEW) // |eUNSCALE_VIEW)
00219             {
00220                m_current_view_frustum = old_view_frustum;
00221             }
00222          }
00223       }
00224 
00225 private: // not implemented
00226    sglPick(const sglPick &);
00227    sglPick& operator=(const sglPick &);
00228 
00229 protected:
00230    sglFrustum<T>        m_orig_pick_frustum;
00231    sglFrustum<T>        m_current_pick_frustum;
00232 
00233    vector<PickResult*>  m_results;
00234    vector<PickResult*> *m_result_pool;
00235 
00236    vector<sglNode*>     m_path;              // current pick path
00237 };
00238 
00239 //----------------------------------------------------------------------------
00240 // convenience types:
00241 //    template class 'should' only be float or double
00242 
00243 typedef sglPick<float>  sglPickf;
00244 typedef sglPick<double> sglPickd;
00245 
00246 #endif

Generated at Mon Jul 1 18:00:05 2002 for SGL by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001