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

sglIntersect.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: sglIntersect.hpp (was sglSegSet.hpp)
00021  *  Created: 18 April 1999
00022  *  Summary: stores the intersection traversal state
00023  *****************************************************************************/
00024 
00025 #ifndef __SGL_INTERSECT_HPP
00026 #define __SGL_INTERSECT_HPP
00027 
00028 #include <sgl.h>
00029 #include <sglSegment.hpp>
00030 #include <sglBound.hpp>
00031 #include <sglProbe.hpp>
00032 #include <sglGeoSetDataPtr.hpp>
00033 #include <sglBoxBound.hpp>
00034 #include <deque>
00035 
00036 class sglGeode;
00037 class sglDrawable;
00038 class sglNode;
00039 
00040 //----------------------------------------------------------------------------
00041 
00042 template <class T>
00043 class SGL_DLL_API sglIntersect : public sglProbeTemplate<T>
00044 {
00045 public: // Sub types
00046    class SGL_DLL_API IntersectResult : public sglProbeTemplate<T>::ProbeResult
00047    {
00048    public:
00049       sglBound::IntersectResultEnum m_result;
00050       sglSegment<T>                 m_segment;
00051       sglVec3f                      m_normal;
00052       deque<sglNode*>               m_path;      // path to picked geode
00053 
00054    public:
00055       IntersectResult() :
00056             sglProbeTemplate<T>::ProbeResult(),
00057                                  m_result(sglBound::eOUTSIDE),
00058                                  m_segment(sglVec3<T>(0,0,0),
00059                                            sglVec3<T>(0,0,0)),
00060                                  m_normal(0.f, 0.f, 0.f),
00061                                  m_path()
00062          {}
00063       virtual ~IntersectResult() { m_path.clear(); }
00064 
00065       virtual void reset()
00066          {
00067             m_result = sglBound::eOUTSIDE;
00068             m_segment.setPos(sglVec3<T>(0,0,0));
00069             m_segment.setDir(sglVec3<T>(0,0,0));
00070             m_segment.setLen(0);
00071             m_normal.set(0.f, 0.f, 0.f);
00072             m_path.clear();
00073             resetInternal();
00074          }
00075    };
00076 
00077 public:
00078    sglIntersect();
00079    ~sglIntersect();
00080 
00081    virtual void reset();
00082 
00083    void setSegment(const sglSegment<T> &segment)
00084       { m_result.m_segment = segment; }
00085    const sglSegment<T>& getSegment() const
00086       { return m_result.m_segment; }
00087 
00088    void setResultEnum(sglBound::IntersectResultEnum result)
00089       { m_result.m_result = result; }  // Cute huh?
00090    sglBound::IntersectResultEnum getResultEnum() const
00091       { return m_result.m_result; }
00092 
00098    deque<sglNode*>& getPath() { return m_result.m_path; }
00099 
00100 
00101    void setGeode(sglGeode *geode)   { m_result.m_geode = geode; }
00102    const sglGeode *getGeode() const { return m_result.m_geode; }
00103 
00104    void setGeometry(sglDrawable *geometry) { m_result.m_geometry = geometry; }
00105    const sglDrawable *getGeometry() const  { return m_result.m_geometry; }
00106 
00110    void setTransformMatrix(const sglMat4<T> &mat) { m_result.m_xform = mat; }
00111    const sglMat4<T> &getTransformMatrix() const   { return m_result.m_xform; }
00112 
00113 
00114 
00118    void setNormal(const sglVec3f &normal) { m_result.m_normal = normal; }
00119    const sglVec3f &getNormal() const      { return m_result.m_normal; }
00120 
00121 
00122    template <class S>
00123    void translate(S x, S y, S z)   { m_result.m_segment.translate(x, y, z); }
00124 
00125    template <class S>
00126    void scale(S scale)             { m_result.m_segment.scale(scale); }
00127 
00128    template <class S>
00129    void mul(const sglMat4<S> &mat) { m_result.m_segment.mul(mat); }
00130 
00131    void intersectTriangle(sglSegment<T>  &seg,
00132                           const sglVec3<T> &vertex0,
00133                           const sglVec3<T> &vertex1,
00134                           const sglVec3<T> &vertex2,
00135                           sglBound::IntersectResultEnum &result);
00136 
00137    const IntersectResult &getResult() const { return m_result; }
00138 
00139    // -------- push/pop transform functions (used internally) ---------
00141    template <class S>
00142    void pushScale(S scale,
00143                   S inv_scale,
00144                   sglSegment<T> &old_segment,
00145                   sglMat4<T>    &old_matrix,
00146                   sglFrustum<T> &old_view_frustum)
00147       {
00148          if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00149                        eLOD_VIEW|eBILLBOARD_VIEW))
00150          {
00151             // save the original view matrix
00152             old_matrix = m_modelview_matrix;
00153 
00154             // compute the new view matrix
00155             m_modelview_matrix.scale(old_matrix, scale, scale, scale);
00156 
00157             // compute a new view frustum
00158             if (m_mode & eUNPROJECT_VIEW) // |eUNSCALE_VIEW
00159             {
00160                old_view_frustum = m_current_view_frustum;
00161                m_current_view_frustum.scale(old_view_frustum, inv_scale);
00162             }
00163          }
00164 
00165          // store the original segment so that i don't have to inverse
00166          // transform it during the pop
00167          old_segment = m_result.m_segment;
00168 
00169          // scale the original segment
00170          m_result.m_segment.scale(inv_scale);
00171       }
00172 
00174    template <class S>
00175    void pushTranslate(S tx, S ty, S tz,
00176                       sglSegment<T> &old_segment,
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.translate(old_matrix, tx, ty, tz);
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.translate(old_view_frustum,
00194                                                 -tx, -ty, -tz);
00195             }
00196          }
00197 
00198          // store the original segment so that i don't have to inverse
00199          // translate it during pop;
00200          old_segment = m_result.m_segment;
00201 
00202          // translate the original segment
00203          m_result.m_segment.translate(-tx, -ty, -tz);
00204       }
00205 
00207    template <class S>
00208    void pushTransform(const sglMat4<S> &xform,
00209                       const sglMat4<S> &inv_xform,
00210                       sglSegment<T> &old_segment,
00211                       sglMat4<T>    &old_matrix,
00212                       sglFrustum<T> &old_view_frustum)
00213       {
00214          if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00215                        eLOD_VIEW|eBILLBOARD_VIEW))
00216          {
00217             // save the original view matrix
00218             old_matrix = m_modelview_matrix;
00219 
00220             // compute the new view matrix
00221             m_modelview_matrix.mul(xform, old_matrix);
00222 
00223             // compute a new view frustum
00224             if (m_mode & eUNPROJECT_VIEW)
00225             {
00226                old_view_frustum = m_current_view_frustum;
00227                m_current_view_frustum.mul(old_view_frustum, inv_xform);
00228             }
00229          }
00230 
00231          // store the original segment so that i don't have to inverse
00232          // transform it
00233          old_segment = m_result.m_segment;
00234 
00235          // transform the original segment
00236          m_result.m_segment.mul(inv_xform);
00237       }
00238 
00239    // pop the transform (restore the old values).
00240    void pop(sglSegment<T> &old_segment,
00241             sglMat4<T>    &old_matrix,
00242             sglFrustum<T> &old_view_frustum)
00243       {
00244          m_result.m_segment = old_segment;
00245 
00246          if (m_mode & (eTRANSFORM|eUNSCALE_VIEW|eUNPROJECT_VIEW|
00247                        eLOD_VIEW|eBILLBOARD_VIEW))
00248          {
00249             m_modelview_matrix = old_matrix;
00250 
00251             // restore the old view frustum
00252             if (m_mode & eUNPROJECT_VIEW) // |eUNSCALE_VIEW)
00253             {
00254                m_current_view_frustum = old_view_frustum;
00255             }
00256          }
00257       }
00258 
00259    typedef void (*IntersectTriangleFunc)(
00260       sglIntersect<T> &segset,
00261       sglSegment<T> &seg,
00262       const void *vtx0, const void *vtx1, const void *vtx2,
00263       sglBound::IntersectResultEnum &result);
00264 
00265    // Get the triangle intersection function for the given vertex data type.
00266    static IntersectTriangleFunc getIntersectTriangleFunc(int vertex_type)
00267       { return s_isect_tri_func_table[vertex_type]; }
00268 
00269    sglBound::IntersectResultEnum intersectIndexedTriangleSet(
00270       const sglBoxBound &bbox,
00271       const sglVertexPtr &vertices,
00272       const sglIndexPtr &index,
00273       unsigned int num_prims);
00274 
00275    sglBound::IntersectResultEnum intersectIndexedTriangleStripSet(
00276       const sglBoxBound &bbox,
00277       const sglVertexPtr &vertices,
00278       const sglIndexPtr &index,
00279       const sglIndexPtr &lengths,
00280       unsigned int num_prims);
00281 
00282    sglBound::IntersectResultEnum intersectIndexedTriangleFanSet(
00283       const sglBoxBound &bbox,
00284       const sglVertexPtr &vertices,
00285       const sglIndexPtr &index,
00286       const sglIndexPtr &lengths,
00287       unsigned int num_prims);
00288 
00289    sglBound::IntersectResultEnum intersectIndexedQuadSet(
00290       const sglBoxBound &bbox,
00291       const sglVertexPtr &vertices,
00292       const sglIndexPtr &index,
00293       unsigned int num_prims);
00294 
00295    sglBound::IntersectResultEnum intersectIndexedQuadStripSet(
00296       const sglBoxBound &bbox,
00297       const sglVertexPtr &vertices,
00298       const sglIndexPtr &index,
00299       const sglIndexPtr &lengths,
00300       unsigned int num_prims);
00301 
00302 private: // not implemented
00303    sglIntersect(const sglIntersect &);
00304    sglIntersect &operator=(const sglIntersect &);
00305 
00306 //    template <class S> void intersectTriangle2(
00307 //       sglSegment<T> &seg,
00308 //       const void *vtx0, const void *vtx1, const void *vtx2,
00309 //       sglBound::IntersectResultEnum &result);
00310 //    template <class S> void intersectTriangle3(
00311 //       sglSegment<T> &seg,
00312 //       const void *vtx0, const void *vtx1, const void *vtx2,
00313 //       sglBound::IntersectResultEnum &result);
00314 //    template <class S> void intersectTriangle4(
00315 //       sglSegment<T> &seg,
00316 //       const void *vtx0, const void *vtx1, const void *vtx2,
00317 //       sglBound::IntersectResultEnum &result);
00318 
00319    static void intersectTriangle2s(
00320       sglIntersect<T> &segset,
00321       sglSegment<T> &seg,
00322       const void *vtx0, const void *vtx1, const void *vtx2,
00323       sglBound::IntersectResultEnum &result);
00324    static void intersectTriangle2i(
00325       sglIntersect<T> &segset,
00326       sglSegment<T> &seg,
00327       const void *vtx0, const void *vtx1, const void *vtx2,
00328       sglBound::IntersectResultEnum &result);
00329    static void intersectTriangle2f(
00330       sglIntersect<T> &segset,
00331       sglSegment<T> &seg,
00332       const void *vtx0, const void *vtx1, const void *vtx2,
00333       sglBound::IntersectResultEnum &result);
00334    static void intersectTriangle2d(
00335       sglIntersect<T> &segset,
00336       sglSegment<T> &seg,
00337       const void *vtx0, const void *vtx1, const void *vtx2,
00338       sglBound::IntersectResultEnum &result);
00339    static void intersectTriangle3s(
00340       sglIntersect<T> &segset,
00341       sglSegment<T> &seg,
00342       const void *vtx0, const void *vtx1, const void *vtx2,
00343       sglBound::IntersectResultEnum &result);
00344    static void intersectTriangle3i(
00345       sglIntersect<T> &segset,
00346       sglSegment<T> &seg,
00347       const void *vtx0, const void *vtx1, const void *vtx2,
00348       sglBound::IntersectResultEnum &result);
00349    static void intersectTriangle3f(
00350       sglIntersect<T> &segset,
00351       sglSegment<T> &seg,
00352       const void *vtx0, const void *vtx1, const void *vtx2,
00353       sglBound::IntersectResultEnum &result);
00354    static void intersectTriangle3d(
00355       sglIntersect<T> &segset,
00356       sglSegment<T> &seg,
00357       const void *vtx0, const void *vtx1, const void *vtx2,
00358       sglBound::IntersectResultEnum &result);
00359    static void intersectTriangle4s(
00360       sglIntersect<T> &segset,
00361       sglSegment<T> &seg,
00362       const void *vtx0, const void *vtx1, const void *vtx2,
00363       sglBound::IntersectResultEnum &result);
00364    static void intersectTriangle4i(
00365       sglIntersect<T> &segset,
00366       sglSegment<T> &seg,
00367       const void *vtx0, const void *vtx1, const void *vtx2,
00368       sglBound::IntersectResultEnum &result);
00369    static void intersectTriangle4f(
00370       sglIntersect<T> &segset,
00371       sglSegment<T> &seg,
00372       const void *vtx0, const void *vtx1, const void *vtx2,
00373       sglBound::IntersectResultEnum &result);
00374    static void intersectTriangle4d(
00375       sglIntersect<T> &segset,
00376       sglSegment<T> &seg,
00377       const void *vtx0, const void *vtx1, const void *vtx2,
00378       sglBound::IntersectResultEnum &result);
00379 
00380 private:
00381    static IntersectTriangleFunc s_isect_tri_func_table[24];
00382 
00383    IntersectResult  m_result;
00384    deque<sglNode*>  m_path;      // current path
00385 };
00386 
00387 //----------------------------------------------------------------------------
00388 // convenience types:
00389 //    template class 'should' only be float or double
00390 
00391 typedef sglIntersect<float>  sglIntersectf;
00392 typedef sglIntersect<double> sglIntersectd;
00393 
00394 #endif

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