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

sglSegment.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: sglSegment.hpp
00021  *  Created: 17 November 1998
00022  *  Summary: 
00023  *****************************************************************************/
00024 
00025 #ifndef __SGL_SEGMENT_HPP
00026 #define __SGL_SEGMENT_HPP
00027 
00028 #include <sgl.h>
00029 #include <GL/gl.h>
00030 #include <sglVec3.hpp>
00031 #include <sglVec4.hpp>
00032 #include <sglMat4.hpp>
00033 
00034 //----------------------------------------------------------------------------
00035 // convenience types:
00036 //    template class 'should' only be float or double
00037 
00038 template <class T> class sglSegment;
00039 
00040 typedef sglSegment<float>  sglSegmentf;
00041 typedef sglSegment<double> sglSegmentd;
00042 
00043 //---------------------------------------------------------------------------
00044 
00045 template <class T>
00046 class sglSegment
00047 {
00048 public:
00049    sglSegment() {}; // no initialization
00050 
00051    // this constructor assumes dir is already normalized
00052    sglSegment(const sglVec3<T> &pos, const sglVec3<T> &dir, T len)
00053          : m_pos(pos), m_dir(dir), m_len(len) {};
00054 
00055    // build a segment that starts at p1 and ends at p2
00056    sglSegment(const sglVec3<T> &p1,  const sglVec3<T> &p2)
00057          : m_pos(p1)
00058       {
00059          m_dir = p2;
00060          m_dir -= p1;
00061          m_len = m_dir.normalize();
00062       }
00063 
00064    // copy a segment
00065    sglSegment(const sglSegment<T> &seg)
00066          : m_pos(seg.getPos()),
00067            m_dir(seg.getDir()),
00068            m_len(seg.getLen())
00069            
00070       {
00071       }
00072 
00073    ~sglSegment() {};
00074 
00075    inline sglSegment &operator=(const sglSegment<T> seg)
00076       {
00077          if (this != &seg)
00078          {
00079             m_pos = seg.getPos();
00080             m_dir = seg.getDir();
00081             m_len = seg.getLen();
00082          }
00083          return *this;
00084       }
00085 
00086 
00087    void setPos(const sglVec3<T> &pos) { m_pos = pos; }
00088    void setDir(const sglVec3<T> &dir) { m_dir = dir; }  // dir must be normed
00089    void setLen(T len) { m_len = len; }
00090 
00091    const sglVec3<T>& getPos() const { return m_pos; }
00092    const sglVec3<T>& getDir() const { return m_dir; }
00093    T getLen() const { return m_len; }
00094 
00095    sglVec3<T> getEndPoint() const
00096       {
00097          return (sglVec3<T>(m_pos[0] + m_len*m_dir[0],
00098                             m_pos[1] + m_len*m_dir[1],
00099                             m_pos[2] + m_len*m_dir[2]));
00100       }
00101 
00102    void clip(const sglSegment<T>& seg, T d1, T d2)
00103       {
00104          if (d2 < d1)
00105          {
00106             m_dir = seg.getDir();
00107             m_dir *= -1;
00108 
00109             m_pos = m_dir;
00110             m_pos *= d1;
00111             m_pos = seg.getPos();
00112 
00113             m_len = d1 - d2;
00114          }
00115          else
00116          {
00117             m_dir = seg.getDir();
00118 
00119             m_pos = m_dir;
00120             m_pos *= d1;
00121             m_pos += seg.getPos();
00122 
00123             m_len = d2 - d1;
00124          }
00125       }
00126 
00127    void makePts(const sglVec3<T> &p1,  const sglVec3<T> &p2)
00128       {
00129          m_pos = p1;
00130          m_dir = p2;
00131          m_dir -= p1;
00132          m_len = m_dir.normalize();
00133       }
00134 
00135    // angles and radians
00136    void makePolar(const sglVec3<T> &pos, double heading, double pitch, T len)
00137       {
00138          m_pos = pos;
00139          m_len = len;
00140          m_dir.set(-sin(heading)*cos(pitch),
00141                    cos(heading)*cos(pitch),
00142                    sin(pitch));
00143       }
00144 
00145    // ---------------------------------------------------------
00146    // Transformations
00147    template <class S>
00148    void mul(const sglMat4<S> &mat)
00149       {
00150          sglVec4<T> pos, dir;
00151          ::mul(m_pos, (T)1.0, mat, pos);
00152          ::mul(m_dir, (T)0.0, mat, dir);
00153          m_pos.set(pos[0], pos[1], pos[2]);
00154          m_dir.set(dir[0], dir[1], dir[2]);
00155       }
00156 
00157    template <class S>
00158    void translate(S x, S y, S z)
00159       {
00160          m_pos[0] += x;
00161          m_pos[1] += y;
00162          m_pos[2] += z;
00163       }
00164 
00165    template <class S>
00166    void scale(S scale)
00167       {
00168          m_pos[0] *= scale;
00169          m_pos[1] *= scale;
00170          m_pos[2] *= scale;
00171          m_len *= scale;
00172       }
00173 
00174    // ---------------------------------------------------------
00175    // Informational output
00176    void drawImmediate() const;
00177 
00178 #if defined(TEMPLATE_OSTREAM_HACK)
00179    template <class S> 
00180    friend ostream &operator<<(ostream &ostrm, const sglSegment<S> &segment);
00181 #else
00182    friend ostream &operator<<(ostream &ostrm, const sglSegment<T> &segment)
00183       {
00184          return (ostrm << "segment [ origin = " << segment.m_pos
00185                  << ", dir = " << segment.m_dir
00186                  << ", length = " << segment.m_len << "]");
00187       }
00188 #endif
00189 
00190 protected:
00191    sglVec3<T>  m_pos;
00192    sglVec3<T>  m_dir;  // normalized
00193    T m_len;
00194 };
00195 
00196 //----------------------------------------------------------------------------
00197 #if defined(TEMPLATE_OSTREAM_HACK)
00198 template <class T>
00199 inline ostream &operator<<(ostream &ostrm, const sglSegment<T> &segment)
00200 {
00201     return (ostrm << "segment [ origin = " << segment.m_pos
00202             << ", dir = " << segment.m_dir
00203             << ", length = " << segment.m_len << "]");
00204 }
00205 #endif
00206 
00207 //----------------------------------------------------------------------------
00208 template <class T>
00209 inline void sglSegment<T>::drawImmediate() const
00210 {
00211    glBegin(GL_LINES);
00212    glVertex3f(m_pos[0], m_pos[1], m_pos[2]);
00213    glVertex3f(m_pos[0] + m_len*m_dir[0],
00214               m_pos[1] + m_len*m_dir[1],
00215               m_pos[2] + m_len*m_dir[2]);
00216    glEnd();
00217 }
00218 
00219 #endif

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