gltube.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:9k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: gltube.hpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:50:26  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef GUI_OPENGL___GLTUBE__HPP
  10. #define GUI_OPENGL___GLTUBE__HPP
  11. /*  $Id: gltube.hpp,v 1000.1 2004/06/01 19:50:26 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software / database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software / database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Authors:  Mike DiCuccio
  37.  *
  38.  * File Description:
  39.  *
  40.  */
  41. #include <corelib/ncbistd.hpp>
  42. #include <gui/math/vect3.hpp>
  43. #include <gui/math/curve.hpp>
  44. #include <gui/math/quat.hpp>
  45. /** @addtogroup GUI_OPENGL
  46.  *
  47.  * @{
  48.  */
  49. BEGIN_NCBI_SCOPE
  50. ///
  51. /// class ICurve defines a basic interface for all curves.  This representation
  52. /// is independent of rendering
  53. ///
  54. template <class Curve>
  55. class CGlTube
  56. {
  57. public:
  58.     typedef ICurve::TPoint TPoint;
  59.     enum ERenderMode {
  60.         eRender_Points,
  61.         eRender_Lines,
  62.         eRender_Quads,
  63.         eRender_Default = eRender_Quads
  64.     };
  65.     CGlTube();
  66.     virtual ~CGlTube() { }
  67.     /// draw!
  68.     void Draw(ERenderMode mode = eRender_Default) const;
  69.     /// draw a curve with a given error limit, with a minimum number of segs
  70.     void Draw(float error, size_t min_segs,
  71.               ERenderMode mode = eRender_Default) const;
  72.     /// recalculate the curve (curve-specific)
  73.     void Recalc();
  74.     /// access control points of the curve
  75.     const TPoint& GetPoint(size_t i) const;
  76.     TPoint&       SetPoint(size_t i);
  77.     void          SetPoint(size_t i, const TPoint& );
  78.     //// evaluate the current curve at a given value [0, 1]
  79.     TPoint EvalPos  (float u) const;
  80.     TPoint EvalTan  (float u) const;
  81.     TPoint EvalCurve(float u) const;
  82.     /// access the level of detail
  83.     float GetError() const;
  84.     void  SetError(float f);
  85.     /// non-curve specifics
  86.     float GetStartRadius(void) const;
  87.     void SetStartRadius(float f);
  88.     float GetEndRadius(void) const;
  89.     void SetEndRadius(float f);
  90.     size_t GetNumSpokes(void) const;
  91.     void SetNumSpokes(size_t spokes);
  92. private:
  93.     // the curve we render
  94.     Curve m_Curve;
  95.     // our start/end radii
  96.     float m_Start;
  97.     float m_End;
  98.     // the numberof spokes in each ring
  99.     size_t m_Spokes;
  100.     struct SRingPos {
  101.         TPoint norm;
  102.         TPoint pos;
  103.     };
  104.     typedef vector<SRingPos> TRing;
  105.     void x_DrawRecursive(float u_lo, const TPoint& pos_lo, TRing& ring_lo,
  106.                          float u_hi, const TPoint& pos_hi,
  107.                          float error) const;
  108.     // evaluate a ring at a given u value
  109.     void x_GetRing(float u, const TPoint& normal,
  110.                    size_t spokes, float radius, TRing& ring) const;
  111. };
  112. template <class Curve>
  113. inline
  114. CGlTube<Curve>::CGlTube()
  115.     : m_Start(1.0f),
  116.       m_End(1.0f),
  117.       m_Spokes(10)
  118. {
  119. }
  120. template <class Curve>
  121. inline void
  122. CGlTube<Curve>::Draw(ERenderMode mode) const
  123. {
  124.     Draw(GetError(), 2, mode);
  125. }
  126. template <class Curve>
  127. inline void
  128. CGlTube<Curve>::Draw(float error, size_t min_segs, ERenderMode mode) const
  129. {
  130.     float u_step = 1.0f / min_segs;
  131.     float u;
  132.     TPoint pos0 = EvalPos(0.0f);
  133.     static const GLenum modes[] ={
  134.         GL_POINT,
  135.         GL_LINE,
  136.         GL_FILL
  137.     };
  138.     glPolygonMode(GL_FRONT_AND_BACK, modes[mode]);
  139.     // precompute our first ring
  140.     TPoint norm(0.0f, 1.0f, 0.0f);
  141.     TPoint axis = EvalPos(0.01f) - EvalPos(0.0f);
  142.     axis.Normalize();
  143.     if (norm.Dot(axis) < 0.0001f) {
  144.         norm = TPoint(0.0f, 0.0f, 1.0f);
  145.     }
  146.     TRing ring;
  147.     x_GetRing(0, norm, m_Spokes, m_Start, ring);
  148.     for (u = 0;  u < 1.0f;  u += u_step) {
  149.         TPoint pos1 = EvalPos(u + u_step);
  150.         x_DrawRecursive(u, pos0, ring, u+u_step, pos1, error);
  151.         pos0 = pos1;
  152.     }
  153.     glEnd();
  154. }
  155. ///
  156. /// internal (recursive) draw function
  157. /// this implements a subdivision with an error level
  158. ///
  159. template <class Curve>
  160. inline void
  161. CGlTube<Curve>::x_DrawRecursive(float u_lo, const TPoint& pos_lo, TRing& ring,
  162.                                 float u_hi, const TPoint& pos_hi,
  163.                                 float error) const
  164. {
  165. #if 0
  166.     /// find the midpoint of the current seg
  167.     float u_mid = (u_lo + u_hi) * 0.5f;
  168.     TPoint pos_mid = EvalPos(u_mid);
  169.     /// find the error associated with this point
  170.     float len0 = (pos_lo - pos_hi).Length();
  171.     float len1 = (pos_mid - pos_lo).Length() + (pos_hi - pos_mid).Length();
  172.     if ((len1 - len0) / len0 > error) {
  173.         /// subdivide!
  174.         x_DrawRecursive(u_lo,  pos_lo,  ring, u_mid, pos_mid, error);
  175.         x_DrawRecursive(u_mid, pos_mid, ring, u_hi,  pos_hi,  error);
  176.     } else {
  177.         // compute the normal for the high point
  178.         // retrieve a ring for our current position
  179.         TRing next;
  180.         x_GetRing(pos_hi, norm_hi, m_Spokes,
  181.                   m_Start + pos_hi * (m_End - m_Start),
  182.                   next);
  183.         glBegin(GL_QUAD_STRIP);
  184.         typename TRing::const_iterator this_iter = ring.begin();
  185.         typename TRing::const_iterator next_iter = next.begin();
  186.         for ( ;  this_iter != ring.end();  ++this_iter, ++next_iter) {
  187.             glNormal3fv(next_iter->norm.GetData());
  188.             glVertex3fv(next_iter->pos.GetData());
  189.             glNormal3fv(this_iter->norm.GetData());
  190.             glVertex3fv(this_iter->pos.GetData());
  191.         }
  192.         glEnd();
  193.         ring.swap(next);
  194.     }
  195. #endif
  196. }
  197. template <class Curve>
  198. inline void
  199. CGlTube<Curve>::x_GetRing(float u, const TPoint& norm,
  200.                           size_t spokes, float radius,
  201.                           TRing& ring) const
  202. {
  203.     float u1 = u + 0.01f;
  204.     if (u1 > 1.0f) {
  205.         u1 = u - 0.01f;
  206.     }
  207.     TPoint start = EvalPos(u);
  208.     TPoint end   = EvalPos(u1);
  209.     TPoint axis = start - end;
  210.     axis.Normalize();
  211.     CQuat<float> quat(axis, 360.0f / float(spokes));
  212.     TPoint nv(norm);
  213.     nv.Normalize();
  214.     nv *= radius;
  215.     ring.clear();
  216.     ring.reserve(spokes + 1);
  217.     for (size_t i =0;  i < spokes;  ++i) {
  218.         SRingPos rp;
  219.         rp.pos = start + nv;
  220.         rp.norm = nv;
  221.         rp.norm.Normalize();
  222.         ring.push_back(rp);
  223.         quat.Rotate(nv);
  224.     }
  225.     ring.push_back(ring.front());
  226. }
  227. template <class Curve>
  228. inline void
  229. CGlTube<Curve>::Recalc()
  230. {
  231.     m_Curve.Recalc();
  232. }
  233. template <class Curve>
  234. inline float
  235. CGlTube<Curve>::GetError() const
  236. {
  237.     return m_Curve.GetError();
  238. }
  239. template <class Curve>
  240. inline void
  241. CGlTube<Curve>::SetError(float f)
  242. {
  243.     m_Curve.SetError(f);
  244. }
  245. template <class Curve>
  246. inline const typename CGlTube<Curve>::TPoint&
  247. CGlTube<Curve>::GetPoint(size_t i) const
  248. {
  249.     return m_Curve.GetPoint(i);
  250. }
  251. template <class Curve>
  252. inline typename CGlTube<Curve>::TPoint&
  253. CGlTube<Curve>::SetPoint(size_t i)
  254. {
  255.     return m_Curve.SetPoint(i);
  256. }
  257. template <class Curve>
  258. inline void
  259. CGlTube<Curve>::SetPoint(size_t i, const TPoint& point)
  260. {
  261.     m_Curve.SetPoint(i, point);
  262. }
  263. template <class Curve>
  264. inline typename CGlTube<Curve>::TPoint
  265. CGlTube<Curve>::EvalPos(float u) const
  266. {
  267.     return m_Curve.EvalPos(u);
  268. }
  269. template <class Curve>
  270. inline typename CGlTube<Curve>::TPoint
  271. CGlTube<Curve>::EvalTan(float u) const
  272. {
  273.     return m_Curve.EvalTan(u);
  274. }
  275. template <class Curve>
  276. inline typename CGlTube<Curve>::TPoint
  277. CGlTube<Curve>::EvalCurve(float u) const
  278. {
  279.     return m_Curve.EvalCurve(u);
  280. }
  281. END_NCBI_SCOPE
  282. /* @} */
  283. /*
  284.  * ===========================================================================
  285.  * $Log: gltube.hpp,v $
  286.  * Revision 1000.1  2004/06/01 19:50:26  gouriano
  287.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  288.  *
  289.  * Revision 1.5  2004/05/11 18:54:22  dicuccio
  290.  * Added doxygne modules info
  291.  *
  292.  * Revision 1.4  2004/05/06 11:55:24  dicuccio
  293.  * Conditionally exclude contents of x_DrawRecursive() pending actual use and
  294.  * debugging
  295.  *
  296.  * Revision 1.3  2004/04/01 22:04:29  ucko
  297.  * Include <gui/math/quat.hpp> (due to use of CQuat in x_GetRing) rather
  298.  * than requiring includers to have previously included it...
  299.  *
  300.  * Revision 1.2  2004/03/11 20:08:05  dicuccio
  301.  * Corrected include paths
  302.  *
  303.  * Revision 1.1  2004/03/10 14:03:52  dicuccio
  304.  * Initial revision
  305.  *
  306.  * ===========================================================================
  307.  */
  308. #endif  // GUI_OPENGL___GLTUBE__HPP