render.h

Go to the documentation of this file.
00001 
00006 /*
00007  Copyright (C) 2001-2006, William Joseph.
00008  All Rights Reserved.
00009 
00010  This file is part of GtkRadiant.
00011 
00012  GtkRadiant is free software; you can redistribute it and/or modify
00013  it under the terms of the GNU General Public License as published by
00014  the Free Software Foundation; either version 2 of the License, or
00015  (at your option) any later version.
00016 
00017  GtkRadiant is distributed in the hope that it will be useful,
00018  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  GNU General Public License for more details.
00021 
00022  You should have received a copy of the GNU General Public License
00023  along with GtkRadiant; if not, write to the Free Software
00024  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00025  */
00026 
00027 #if !defined(INCLUDED_RENDER_H)
00028 #define INCLUDED_RENDER_H
00029 
00030 #include "irender.h"
00031 #include "igl.h"
00032 
00033 #include "container/array.h"
00034 #include "math/FloatTools.h"
00035 #include "math/Vector2.h"
00036 #include "math/pi.h"
00037 
00038 #include <vector>
00039 
00040 typedef unsigned int RenderIndex;
00041 const GLenum RenderIndexTypeID = GL_UNSIGNED_INT;
00042 
00044 class IndexBuffer
00045 {
00046         typedef std::vector<RenderIndex> Indices;
00047         Indices m_data;
00048     public:
00049         typedef Indices::iterator iterator;
00050         typedef Indices::const_iterator const_iterator;
00051 
00052         iterator begin ()
00053         {
00054             return m_data.begin();
00055         }
00056         const_iterator begin () const
00057         {
00058             return m_data.begin();
00059         }
00060         iterator end ()
00061         {
00062             return m_data.end();
00063         }
00064         const_iterator end () const
00065         {
00066             return m_data.end();
00067         }
00068 
00069         bool empty () const
00070         {
00071             return m_data.empty();
00072         }
00073         std::size_t size () const
00074         {
00075             return m_data.size();
00076         }
00077         const RenderIndex* data () const
00078         {
00079             return &(*m_data.begin());
00080         }
00081         RenderIndex& operator[] (std::size_t index)
00082         {
00083             return m_data[index];
00084         }
00085         const RenderIndex& operator[] (std::size_t index) const
00086         {
00087             return m_data[index];
00088         }
00089         void clear ()
00090         {
00091             m_data.clear();
00092         }
00093         void reserve (std::size_t max_indices)
00094         {
00095             m_data.reserve(max_indices);
00096         }
00097         void insert (RenderIndex index)
00098         {
00099             m_data.push_back(index);
00100         }
00101         void swap (IndexBuffer& other)
00102         {
00103             std::swap(m_data, m_data);
00104         }
00105 };
00106 
00107 namespace std
00108 {
00111     inline void swap (IndexBuffer& self, IndexBuffer& other)
00112     {
00113         self.swap(other);
00114     }
00115 }
00116 
00119 template<typename Vertex>
00120 class VertexBuffer
00121 {
00122         typedef typename std::vector<Vertex> Vertices;
00123         Vertices m_data;
00124     public:
00125         typedef typename Vertices::iterator iterator;
00126         typedef typename Vertices::const_iterator const_iterator;
00127 
00128         iterator begin ()
00129         {
00130             return m_data.begin();
00131         }
00132         iterator end ()
00133         {
00134             return m_data.end();
00135         }
00136         const_iterator begin () const
00137         {
00138             return m_data.begin();
00139         }
00140         const_iterator end () const
00141         {
00142             return m_data.end();
00143         }
00144 
00145         bool empty () const
00146         {
00147             return m_data.empty();
00148         }
00149         RenderIndex size () const
00150         {
00151             return RenderIndex(m_data.size());
00152         }
00153         const Vertex* data () const
00154         {
00155             return &(*m_data.begin());
00156         }
00157         Vertex& operator[] (std::size_t index)
00158         {
00159             return m_data[index];
00160         }
00161         const Vertex& operator[] (std::size_t index) const
00162         {
00163             return m_data[index];
00164         }
00165 
00166         void clear ()
00167         {
00168             m_data.clear();
00169         }
00170         void reserve (std::size_t max_vertices)
00171         {
00172             m_data.reserve(max_vertices);
00173         }
00174         void push_back (const Vertex& vertex)
00175         {
00176             m_data.push_back(vertex);
00177         }
00178 };
00179 
00183 template<typename Vertex>
00184 class UniqueVertexBuffer
00185 {
00186         typedef VertexBuffer<Vertex> Vertices;
00187         Vertices& m_data;
00188 
00189         struct bnode
00190         {
00191                 bnode () :
00192                     m_left(0), m_right(0)
00193                 {
00194                 }
00195                 RenderIndex m_left;
00196                 RenderIndex m_right;
00197         };
00198 
00199         std::vector<bnode> m_btree;
00200         RenderIndex m_prev0;
00201         RenderIndex m_prev1;
00202         RenderIndex m_prev2;
00203 
00204         const RenderIndex find_or_insert (const Vertex& vertex)
00205         {
00206             RenderIndex index = 0;
00207 
00208             while (1) {
00209                 if (vertex < m_data[index]) {
00210                     bnode& node = m_btree[index];
00211                     if (node.m_left != 0) {
00212                         index = node.m_left;
00213                         continue;
00214                     } else {
00215                         node.m_left = RenderIndex(m_btree.size());
00216                         m_btree.push_back(bnode());
00217                         m_data.push_back(vertex);
00218                         return RenderIndex(m_btree.size() - 1);
00219                     }
00220                 }
00221                 if (m_data[index] < vertex) {
00222                     bnode& node = m_btree[index];
00223                     if (node.m_right != 0) {
00224                         index = node.m_right;
00225                         continue;
00226                     } else {
00227                         node.m_right = RenderIndex(m_btree.size());
00228                         m_btree.push_back(bnode());
00229                         m_data.push_back(vertex);
00230                         return RenderIndex(m_btree.size() - 1);
00231                     }
00232                 }
00233 
00234                 return index;
00235             }
00236         }
00237     public:
00238         UniqueVertexBuffer (Vertices& data) :
00239             m_data(data), m_prev0(0), m_prev1(0), m_prev2(0)
00240         {
00241         }
00242 
00243         typedef typename Vertices::const_iterator iterator;
00244 
00245         iterator begin () const
00246         {
00247             return m_data.begin();
00248         }
00249         iterator end () const
00250         {
00251             return m_data.end();
00252         }
00253 
00254         std::size_t size () const
00255         {
00256             return m_data.size();
00257         }
00258         const Vertex* data () const
00259         {
00260             return &(*m_data.begin());
00261         }
00262         Vertex& operator[] (std::size_t index)
00263         {
00264             return m_data[index];
00265         }
00266         const Vertex& operator[] (std::size_t index) const
00267         {
00268             return m_data[index];
00269         }
00270 
00271         void clear ()
00272         {
00273             m_prev0 = 0;
00274             m_prev1 = 0;
00275             m_prev2 = 0;
00276             m_data.clear();
00277             m_btree.clear();
00278         }
00279         void reserve (std::size_t max_vertices)
00280         {
00281             m_data.reserve(max_vertices);
00282             m_btree.reserve(max_vertices);
00283         }
00285         RenderIndex insert (const Vertex& vertex)
00286         {
00287             if (m_data.empty()) {
00288                 m_data.push_back(vertex);
00289                 m_btree.push_back(bnode());
00290                 return 0;
00291             }
00292 
00293             if (m_data[m_prev0] == vertex)
00294                 return m_prev0;
00295             if (m_prev1 != m_prev0 && m_data[m_prev1] == vertex)
00296                 return m_prev1;
00297             if (m_prev2 != m_prev0 && m_prev2 != m_prev1 && m_data[m_prev2] == vertex)
00298                 return m_prev2;
00299 
00300             m_prev2 = m_prev1;
00301             m_prev1 = m_prev0;
00302             m_prev0 = find_or_insert(vertex);
00303 
00304             return m_prev0;
00305         }
00306 };
00307 
00309 struct Colour4b
00310 {
00311         unsigned char r, g, b, a;
00312 
00313         Colour4b ()
00314         {
00315         }
00316 
00317         Colour4b (unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) :
00318             r(_r), g(_g), b(_b), a(_a)
00319         {
00320         }
00321 };
00322 
00323 const Colour4b colour_vertex(0, 255, 0, 255);
00324 const Colour4b colour_selected(0, 0, 255, 255);
00325 
00326 inline bool operator< (const Colour4b& self, const Colour4b& other)
00327 {
00328     if (self.r != other.r) {
00329         return self.r < other.r;
00330     }
00331     if (self.g != other.g) {
00332         return self.g < other.g;
00333     }
00334     if (self.b != other.b) {
00335         return self.b < other.b;
00336     }
00337     if (self.a != other.a) {
00338         return self.a < other.a;
00339     }
00340     return false;
00341 }
00342 
00343 inline bool operator== (const Colour4b& self, const Colour4b& other)
00344 {
00345     return self.r == other.r && self.g == other.g && self.b == other.b && self.a == other.a;
00346 }
00347 
00348 inline bool operator!= (const Colour4b& self, const Colour4b& other)
00349 {
00350     return !operator==(self, other);
00351 }
00352 
00354 struct Vertex3f: public Vector3
00355 {
00356 
00359         Vertex3f ()
00360         {
00361         }
00362 
00365         Vertex3f (float _x, float _y, float _z) :
00366             Vector3(_x, _y, _z)
00367         {
00368         }
00369 
00372         Vertex3f (const float* array) :
00373             Vector3(array)
00374         {
00375         }
00376 
00377 };
00378 
00379 inline bool operator< (const Vertex3f& self, const Vertex3f& other)
00380 {
00381     if (self.x() != other.x()) {
00382         return self.x() < other.x();
00383     }
00384     if (self.y() != other.y()) {
00385         return self.y() < other.y();
00386     }
00387     if (self.z() != other.z()) {
00388         return self.z() < other.z();
00389     }
00390     return false;
00391 }
00392 
00393 inline bool operator== (const Vertex3f& self, const Vertex3f& other)
00394 {
00395     return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
00396 }
00397 
00398 inline bool operator!= (const Vertex3f& self, const Vertex3f& other)
00399 {
00400     return !operator==(self, other);
00401 }
00402 
00403 inline Vertex3f vertex3f_from_array (const float* array)
00404 {
00405     return Vertex3f(array[0], array[1], array[2]);
00406 }
00407 
00408 inline float* vertex3f_to_array (Vertex3f& vertex)
00409 {
00410     return reinterpret_cast<float*> (&vertex);
00411 }
00412 
00413 inline const float* vertex3f_to_array (const Vertex3f& vertex)
00414 {
00415     return reinterpret_cast<const float*> (&vertex);
00416 }
00417 
00418 const Vertex3f vertex3f_identity(0, 0, 0);
00419 
00420 inline Vertex3f vertex3f_for_vector3 (const Vector3& vector3)
00421 {
00422     return Vertex3f(vector3.x(), vector3.y(), vector3.z());
00423 }
00424 
00425 inline const Vector3& vertex3f_to_vector3 (const Vertex3f& vertex)
00426 {
00427     return vertex;
00428 }
00429 
00430 inline Vector3& vertex3f_to_vector3 (Vertex3f& vertex)
00431 {
00432     return vertex;
00433 }
00434 
00436 struct Normal3f: public Vector3
00437 {
00438         Normal3f ()
00439         {
00440         }
00441 
00446         Normal3f (float _x, float _y, float _z) :
00447             Vector3(_x, _y, _z)
00448         {
00449         }
00450 
00451         // Static conversion from Vector3
00452         Normal3f (const Vector3& vec) :
00453             Vector3(vec)
00454         {
00455         }
00456 
00459         Normal3f (const float* array) :
00460             Vector3(array)
00461         {
00462         }
00463 
00464 };
00465 
00466 inline bool operator< (const Normal3f& self, const Normal3f& other)
00467 {
00468     if (self.x() != other.x()) {
00469         return self.x() < other.x();
00470     }
00471     if (self.y() != other.y()) {
00472         return self.y() < other.y();
00473     }
00474     if (self.z() != other.z()) {
00475         return self.z() < other.z();
00476     }
00477     return false;
00478 }
00479 
00480 inline bool operator== (const Normal3f& self, const Normal3f& other)
00481 {
00482     return self.x() == other.x() && self.y() == other.y() && self.z() == other.z();
00483 }
00484 
00485 inline bool operator!= (const Normal3f& self, const Normal3f& other)
00486 {
00487     return !operator==(self, other);
00488 }
00489 
00490 inline Normal3f normal3f_from_array (const float* array)
00491 {
00492     return Normal3f(array[0], array[1], array[2]);
00493 }
00494 
00495 inline float* normal3f_to_array (Normal3f& normal)
00496 {
00497     return reinterpret_cast<float*> (&normal);
00498 }
00499 
00500 inline const float* normal3f_to_array (const Normal3f& normal)
00501 {
00502     return reinterpret_cast<const float*> (&normal);
00503 }
00504 
00505 inline Normal3f normal3f_for_vector3 (const Vector3& vector3)
00506 {
00507     return Normal3f(vector3.x(), vector3.y(), vector3.z());
00508 }
00509 
00510 inline const Vector3& normal3f_to_vector3 (const Normal3f& normal)
00511 {
00512     return normal;
00513 }
00514 
00515 inline Vector3& normal3f_to_vector3 (Normal3f& normal)
00516 {
00517     return normal;
00518 }
00519 
00521 struct TexCoord2f: public Vector2
00522 {
00523         TexCoord2f ()
00524         {
00525         }
00526 
00530         TexCoord2f (float _s, float _t) :
00531             Vector2(_s, _t)
00532         {
00533         }
00534 
00538         TexCoord2f (const float* array) :
00539             Vector2(array[0], array[1])
00540         {
00541         }
00542 
00543         float& s ()
00544         {
00545             return x();
00546         }
00547         const float& s () const
00548         {
00549             return x();
00550         }
00551         float& t ()
00552         {
00553             return y();
00554         }
00555         const float& t () const
00556         {
00557             return y();
00558         }
00559 };
00560 
00561 inline bool operator< (const TexCoord2f& self, const TexCoord2f& other)
00562 {
00563     if (self.s() != other.s()) {
00564         return self.s() < other.s();
00565     }
00566     if (self.t() != other.t()) {
00567         return self.t() < other.t();
00568     }
00569     return false;
00570 }
00571 
00572 inline bool operator== (const TexCoord2f& self, const TexCoord2f& other)
00573 {
00574     return self.s() == other.s() && self.t() == other.t();
00575 }
00576 
00577 inline bool operator!= (const TexCoord2f& self, const TexCoord2f& other)
00578 {
00579     return !operator==(self, other);
00580 }
00581 
00582 inline float* texcoord2f_to_array (TexCoord2f& texcoord)
00583 {
00584     return reinterpret_cast<float*> (&texcoord);
00585 }
00586 
00587 inline const float* texcoord2f_to_array (const TexCoord2f& texcoord)
00588 {
00589     return reinterpret_cast<const float*> (&texcoord);
00590 }
00591 
00592 inline const TexCoord2f& texcoord2f_from_array (const float* array)
00593 {
00594     return *reinterpret_cast<const TexCoord2f*> (array);
00595 }
00596 
00597 inline TexCoord2f texcoord2f_for_vector2 (const Vector2& vector2)
00598 {
00599     return TexCoord2f(vector2.x(), vector2.y());
00600 }
00601 
00602 inline const Vector2& texcoord2f_to_vector2 (const TexCoord2f& vertex)
00603 {
00604     return vertex;
00605 }
00606 
00607 inline Vector2& texcoord2f_to_vector2 (TexCoord2f& vertex)
00608 {
00609     return vertex;
00610 }
00611 
00613 inline Normal3f normal3f_normalised (const Normal3f& normal)
00614 {
00615     return normal3f_for_vector3(normal3f_to_vector3(normal).getNormalised());
00616 }
00617 
00618 enum UnitSphereOctant
00619 {
00620     UNITSPHEREOCTANT_000 = 0 << 0 | 0 << 1 | 0 << 2,
00621     UNITSPHEREOCTANT_001 = 0 << 0 | 0 << 1 | 1 << 2,
00622     UNITSPHEREOCTANT_010 = 0 << 0 | 1 << 1 | 0 << 2,
00623     UNITSPHEREOCTANT_011 = 0 << 0 | 1 << 1 | 1 << 2,
00624     UNITSPHEREOCTANT_100 = 1 << 0 | 0 << 1 | 0 << 2,
00625     UNITSPHEREOCTANT_101 = 1 << 0 | 0 << 1 | 1 << 2,
00626     UNITSPHEREOCTANT_110 = 1 << 0 | 1 << 1 | 0 << 2,
00627     UNITSPHEREOCTANT_111 = 1 << 0 | 1 << 1 | 1 << 2,
00628 };
00629 
00631 inline UnitSphereOctant normal3f_classify_octant (const Normal3f& normal)
00632 {
00633     return static_cast<UnitSphereOctant> (((normal.x() > 0) << 0) | ((normal.y() > 0) << 1) | ((normal.z() > 0) << 2));
00634 }
00635 
00637 inline Normal3f normal3f_fold_octant (const Normal3f& normal, UnitSphereOctant octant)
00638 {
00639     switch (octant) {
00640     case UNITSPHEREOCTANT_000:
00641         return Normal3f(-normal.x(), -normal.y(), -normal.z());
00642     case UNITSPHEREOCTANT_001:
00643         return Normal3f(normal.x(), -normal.y(), -normal.z());
00644     case UNITSPHEREOCTANT_010:
00645         return Normal3f(-normal.x(), normal.y(), -normal.z());
00646     case UNITSPHEREOCTANT_011:
00647         return Normal3f(normal.x(), normal.y(), -normal.z());
00648     case UNITSPHEREOCTANT_100:
00649         return Normal3f(-normal.x(), -normal.y(), normal.z());
00650     case UNITSPHEREOCTANT_101:
00651         return Normal3f(normal.x(), -normal.y(), normal.z());
00652     case UNITSPHEREOCTANT_110:
00653         return Normal3f(-normal.x(), normal.y(), normal.z());
00654     case UNITSPHEREOCTANT_111:
00655         return Normal3f(normal.x(), normal.y(), normal.z());
00656     }
00657     return Normal3f();
00658 }
00659 
00663 inline Normal3f normal3f_unfold_octant (const Normal3f& normal, UnitSphereOctant octant)
00664 {
00665     return normal3f_fold_octant(normal, octant);
00666 }
00667 
00668 enum UnitSphereSextant
00669 {
00670     UNITSPHERESEXTANT_XYZ = 0,
00671     UNITSPHERESEXTANT_XZY = 1,
00672     UNITSPHERESEXTANT_YXZ = 2,
00673     UNITSPHERESEXTANT_YZX = 3,
00674     UNITSPHERESEXTANT_ZXY = 4,
00675     UNITSPHERESEXTANT_ZYX = 5,
00676 };
00677 
00681 inline UnitSphereSextant normal3f_classify_sextant (const Normal3f& normal)
00682 {
00683     return normal.x() >= normal.y() ? normal.x() >= normal.z() ? normal.y() >= normal.z() ? UNITSPHERESEXTANT_XYZ
00684             : UNITSPHERESEXTANT_XZY : UNITSPHERESEXTANT_ZXY
00685             : normal.y() >= normal.z() ? normal.x() >= normal.z() ? UNITSPHERESEXTANT_YXZ : UNITSPHERESEXTANT_YZX
00686                     : UNITSPHERESEXTANT_ZYX;
00687 }
00688 
00692 inline Normal3f normal3f_fold_sextant (const Normal3f& normal, UnitSphereSextant sextant)
00693 {
00694     switch (sextant) {
00695     case UNITSPHERESEXTANT_XYZ:
00696         return Normal3f(normal.x(), normal.y(), normal.z());
00697     case UNITSPHERESEXTANT_XZY:
00698         return Normal3f(normal.x(), normal.z(), normal.y());
00699     case UNITSPHERESEXTANT_YXZ:
00700         return Normal3f(normal.y(), normal.x(), normal.z());
00701     case UNITSPHERESEXTANT_YZX:
00702         return Normal3f(normal.y(), normal.z(), normal.x());
00703     case UNITSPHERESEXTANT_ZXY:
00704         return Normal3f(normal.z(), normal.x(), normal.y());
00705     case UNITSPHERESEXTANT_ZYX:
00706         return Normal3f(normal.z(), normal.y(), normal.x());
00707     }
00708     return Normal3f();
00709 }
00710 
00714 inline Normal3f normal3f_unfold_sextant (const Normal3f& normal, UnitSphereSextant sextant)
00715 {
00716     return normal3f_fold_sextant(normal, sextant);
00717 }
00718 
00719 const std::size_t c_quantise_normal = 1 << 6;
00720 
00722 inline Normal3f normal3f_folded_quantised (const Normal3f& folded)
00723 {
00724     // compress
00725     double scale = static_cast<float> (c_quantise_normal) / (folded.x() + folded.y() + folded.z());
00726     unsigned int zbits = static_cast<unsigned int> (folded.z() * scale);
00727     unsigned int ybits = static_cast<unsigned int> (folded.y() * scale);
00728 
00729     // decompress
00730     return normal3f_normalised(Normal3f(static_cast<float> (c_quantise_normal - zbits - ybits),
00731             static_cast<float> (ybits), static_cast<float> (zbits)));
00732 }
00733 
00735 inline Normal3f normal3f_quantised_custom (const Normal3f& normal)
00736 {
00737     UnitSphereOctant octant = normal3f_classify_octant(normal);
00738     Normal3f folded = normal3f_fold_octant(normal, octant);
00739     UnitSphereSextant sextant = normal3f_classify_sextant(folded);
00740     folded = normal3f_fold_sextant(folded, sextant);
00741     return normal3f_unfold_octant(normal3f_unfold_sextant(normal3f_folded_quantised(folded), sextant), octant);
00742 }
00743 
00744 struct spherical_t
00745 {
00746         double longditude, latitude;
00747 
00748         spherical_t (double _longditude, double _latitude) :
00749             longditude(_longditude), latitude(_latitude)
00750         {
00751         }
00752 };
00753 
00754 /*
00755  {
00756  theta = 2pi * U;
00757  phi = acos((2 * V) - 1);
00758 
00759  U = theta / 2pi;
00760  V = (cos(phi) + 1) / 2;
00761  }
00762 
00763  longitude = atan(y / x);
00764  latitude = acos(z);
00765  */
00766 struct uniformspherical_t
00767 {
00768         double U, V;
00769 
00770         uniformspherical_t (double U_, double V_) :
00771             U(U_), V(V_)
00772         {
00773         }
00774 };
00775 
00776 inline spherical_t spherical_from_normal3f (const Normal3f& normal)
00777 {
00778     return spherical_t(normal.x() == 0 ? c_pi / 2 : normal.x() > 0 ? atan(normal.y() / normal.x()) : atan(normal.y()
00779             / normal.x()) + c_pi, acos(normal.z()));
00780 }
00781 
00782 inline Normal3f normal3f_from_spherical (const spherical_t& spherical)
00783 {
00784     return Normal3f(static_cast<float> (cos(spherical.longditude) * sin(spherical.latitude)), static_cast<float> (sin(
00785             spherical.longditude) * sin(spherical.latitude)), static_cast<float> (cos(spherical.latitude)));
00786 }
00787 
00788 inline uniformspherical_t uniformspherical_from_spherical (const spherical_t& spherical)
00789 {
00790     return uniformspherical_t(spherical.longditude * c_inv_2pi, (cos(spherical.latitude) + 1) * 0.5);
00791 }
00792 
00793 inline spherical_t spherical_from_uniformspherical (const uniformspherical_t& uniformspherical)
00794 {
00795     return spherical_t(c_2pi * uniformspherical.U, acos((2 * uniformspherical.V) - 1));
00796 }
00797 
00798 inline uniformspherical_t uniformspherical_from_normal3f (const Normal3f& normal)
00799 {
00800     return uniformspherical_from_spherical(spherical_from_normal3f(normal));
00801     //return uniformspherical_t(atan2(normal.y / normal.x) * c_inv_2pi, (normal.z + 1) * 0.5);
00802 }
00803 
00804 inline Normal3f normal3f_from_uniformspherical (const uniformspherical_t& uniformspherical)
00805 {
00806     return normal3f_from_spherical(spherical_from_uniformspherical(uniformspherical));
00807 }
00808 
00810 inline float float_quantise (float component, float precision)
00811 {
00812     return float_snapped(component, precision);
00813 }
00814 
00816 inline double double_quantise (double component, double precision)
00817 {
00818     return float_snapped(component, precision);
00819 }
00820 
00821 inline spherical_t spherical_quantised (const spherical_t& spherical, float snap)
00822 {
00823     return spherical_t(double_quantise(spherical.longditude, snap), double_quantise(spherical.latitude, snap));
00824 }
00825 
00826 inline uniformspherical_t uniformspherical_quantised (const uniformspherical_t& uniformspherical, float snap)
00827 {
00828     return uniformspherical_t(double_quantise(uniformspherical.U, snap), double_quantise(uniformspherical.V, snap));
00829 }
00830 
00832 inline Vertex3f vertex3f_quantised (const Vertex3f& vertex, float precision)
00833 {
00834     return Vertex3f(float_quantise(vertex.x(), precision), float_quantise(vertex.y(), precision), float_quantise(
00835             vertex.z(), precision));
00836 }
00837 
00839 inline Normal3f normal3f_quantised (const Normal3f& normal)
00840 {
00841     return normal3f_quantised_custom(normal);
00842     //return normal3f_from_spherical(spherical_quantised(spherical_from_normal3f(normal), snap));
00843     //return normal3f_from_uniformspherical(uniformspherical_quantised(uniformspherical_from_normal3f(normal), snap));
00844     //  float_quantise(normal.x, snap), float_quantise(normal.y, snap), float_quantise(normal.y, snap));
00845 }
00846 
00848 inline TexCoord2f texcoord2f_quantised (const TexCoord2f& texcoord, float precision)
00849 {
00850     return TexCoord2f(float_quantise(texcoord.s(), precision), float_quantise(texcoord.t(), precision));
00851 }
00852 
00854 struct PointVertex
00855 {
00856         Colour4b colour;
00857         Vertex3f vertex;
00858 
00859         PointVertex ()
00860         {
00861         }
00862         PointVertex (Vertex3f _vertex) :
00863             colour(Colour4b(255, 255, 255, 255)), vertex(_vertex)
00864         {
00865         }
00866         PointVertex (Vertex3f _vertex, Colour4b _colour) :
00867             colour(_colour), vertex(_vertex)
00868         {
00869         }
00870 };
00871 
00872 inline bool operator< (const PointVertex& self, const PointVertex& other)
00873 {
00874     if (self.vertex != other.vertex) {
00875         return self.vertex < other.vertex;
00876     }
00877     if (self.colour != other.colour) {
00878         return self.colour < other.colour;
00879     }
00880     return false;
00881 }
00882 
00883 inline bool operator== (const PointVertex& self, const PointVertex& other)
00884 {
00885     return self.colour == other.colour && self.vertex == other.vertex;
00886 }
00887 
00888 inline bool operator!= (const PointVertex& self, const PointVertex& other)
00889 {
00890     return !operator==(self, other);
00891 }
00892 
00894 struct ArbitraryMeshVertex
00895 {
00896         TexCoord2f texcoord;
00897         Normal3f normal;
00898         Vertex3f vertex;
00899         Normal3f tangent;
00900         Normal3f bitangent;
00901 
00902         ArbitraryMeshVertex () :
00903             tangent(0, 0, 0), bitangent(0, 0, 0)
00904         {
00905         }
00906         ArbitraryMeshVertex (Vertex3f _vertex, Normal3f _normal, TexCoord2f _texcoord) :
00907             texcoord(_texcoord), normal(_normal), vertex(_vertex), tangent(0, 0, 0), bitangent(0, 0, 0)
00908         {
00909         }
00910 };
00911 
00912 inline bool operator< (const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other)
00913 {
00914     if (self.texcoord != other.texcoord) {
00915         return self.texcoord < other.texcoord;
00916     }
00917     if (self.normal != other.normal) {
00918         return self.normal < other.normal;
00919     }
00920     if (self.vertex != other.vertex) {
00921         return self.vertex < other.vertex;
00922     }
00923     return false;
00924 }
00925 
00926 inline bool operator== (const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other)
00927 {
00928     return self.texcoord == other.texcoord && self.normal == other.normal && self.vertex == other.vertex;
00929 }
00930 
00931 inline bool operator!= (const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other)
00932 {
00933     return !operator==(self, other);
00934 }
00935 
00936 const float c_quantise_vertex = 1.f / static_cast<float> (1 << 3);
00937 
00939 inline PointVertex pointvertex_quantised (const PointVertex& v)
00940 {
00941     return PointVertex(vertex3f_quantised(v.vertex, c_quantise_vertex), v.colour);
00942 }
00943 
00944 const float c_quantise_texcoord = 1.f / static_cast<float> (1 << 8);
00945 
00947 inline ArbitraryMeshVertex arbitrarymeshvertex_quantised (const ArbitraryMeshVertex& v)
00948 {
00949     return ArbitraryMeshVertex(vertex3f_quantised(v.vertex, c_quantise_vertex), normal3f_quantised(v.normal),
00950             texcoord2f_quantised(v.texcoord, c_quantise_texcoord));
00951 }
00952 
00954 inline void pointvertex_gl_array (const PointVertex* array)
00955 {
00956     glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &array->colour);
00957     glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &array->vertex);
00958 }
00959 
00960 class RenderablePointArray: public OpenGLRenderable
00961 {
00962         const Array<PointVertex>& m_array;
00963         const GLenum m_mode;
00964     public:
00965         RenderablePointArray (const Array<PointVertex>& array, GLenum mode) :
00966             m_array(array), m_mode(mode)
00967         {
00968         }
00969         void render (RenderStateFlags state) const
00970         {
00971 #define NV_DRIVER_BUG 1
00972 #if NV_DRIVER_BUG
00973             glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);
00974             glVertexPointer(3, GL_FLOAT, 0, 0);
00975             glDrawArrays(GL_TRIANGLE_FAN, 0, 0);
00976 #endif
00977             pointvertex_gl_array(m_array.data());
00978             glDrawArrays(m_mode, 0, GLsizei(m_array.size()));
00979         }
00980 };
00981 
00982 class RenderablePointVector: public OpenGLRenderable
00983 {
00984         std::vector<PointVertex> m_vector;
00985         const GLenum m_mode;
00986     public:
00987         RenderablePointVector (GLenum mode) :
00988             m_mode(mode)
00989         {
00990         }
00991 
00992         void render (RenderStateFlags state) const
00993         {
00994             pointvertex_gl_array(&m_vector.front());
00995             glDrawArrays(m_mode, 0, GLsizei(m_vector.size()));
00996         }
00997 
00998         std::size_t size () const
00999         {
01000             return m_vector.size();
01001         }
01002         bool empty () const
01003         {
01004             return m_vector.empty();
01005         }
01006         void clear ()
01007         {
01008             m_vector.clear();
01009         }
01010         void reserve (std::size_t size)
01011         {
01012             m_vector.reserve(size);
01013         }
01014         void push_back (const PointVertex& point)
01015         {
01016             m_vector.push_back(point);
01017         }
01018 };
01019 
01020 class RenderableVertexBuffer: public OpenGLRenderable
01021 {
01022         const GLenum m_mode;
01023         const VertexBuffer<PointVertex>& m_vertices;
01024     public:
01025         RenderableVertexBuffer (GLenum mode, const VertexBuffer<PointVertex>& vertices) :
01026             m_mode(mode), m_vertices(vertices)
01027         {
01028         }
01029 
01030         void render (RenderStateFlags state) const
01031         {
01032             pointvertex_gl_array(m_vertices.data());
01033             glDrawArrays(m_mode, 0, m_vertices.size());
01034         }
01035 };
01036 
01037 class RenderableIndexBuffer: public OpenGLRenderable
01038 {
01039         const GLenum m_mode;
01040         const IndexBuffer& m_indices;
01041         const VertexBuffer<PointVertex>& m_vertices;
01042     public:
01043         RenderableIndexBuffer (GLenum mode, const IndexBuffer& indices, const VertexBuffer<PointVertex>& vertices) :
01044             m_mode(mode), m_indices(indices), m_vertices(vertices)
01045         {
01046         }
01047 
01048         void render (RenderStateFlags state) const
01049         {
01050 #if 1
01051             pointvertex_gl_array(m_vertices.data());
01052             glDrawElements(m_mode, GLsizei(m_indices.size()), RenderIndexTypeID, m_indices.data());
01053 #else
01054             glBegin(m_mode);
01055             if(state & RENDER_COLOURARRAY != 0)
01056             {
01057                 for(std::size_t i = 0; i < m_indices.size(); ++i)
01058                 {
01059                     glColor4ubv(&m_vertices[m_indices[i]].colour.r);
01060                     glVertex3fv(&m_vertices[m_indices[i]].vertex.x);
01061                 }
01062             }
01063             else
01064             {
01065                 for(std::size_t i = 0; i < m_indices.size(); ++i)
01066                 {
01067                     glVertex3fv(&m_vertices[m_indices[i]].vertex.x);
01068                 }
01069             }
01070             glEnd();
01071 #endif
01072         }
01073 };
01074 
01075 class RemapXYZ
01076 {
01077     public:
01078         static void set (Vertex3f& vertex, float x, float y, float z)
01079         {
01080             vertex.x() = x;
01081             vertex.y() = y;
01082             vertex.z() = z;
01083         }
01084 };
01085 
01086 class RemapYZX
01087 {
01088     public:
01089         static void set (Vertex3f& vertex, float x, float y, float z)
01090         {
01091             vertex.x() = z;
01092             vertex.y() = x;
01093             vertex.z() = y;
01094         }
01095 };
01096 
01097 class RemapZXY
01098 {
01099     public:
01100         static void set (Vertex3f& vertex, float x, float y, float z)
01101         {
01102             vertex.x() = y;
01103             vertex.y() = z;
01104             vertex.z() = x;
01105         }
01106 };
01107 
01108 template<typename remap_policy>
01109 inline void draw_circle (const std::size_t segments, const float radius, PointVertex* vertices, remap_policy remap)
01110 {
01111     const double increment = c_pi / double(segments << 2);
01112 
01113     std::size_t count = 0;
01114     float x = radius;
01115     float y = 0;
01116     while (count < segments) {
01117         PointVertex* i = vertices + count;
01118         PointVertex* j = vertices + ((segments << 1) - (count + 1));
01119 
01120         PointVertex* k = i + (segments << 1);
01121         PointVertex* l = j + (segments << 1);
01122 
01123         PointVertex* m = i + (segments << 2);
01124         PointVertex* n = j + (segments << 2);
01125         PointVertex* o = k + (segments << 2);
01126         PointVertex* p = l + (segments << 2);
01127 
01128         remap_policy::set(i->vertex, x, -y, 0);
01129         remap_policy::set(k->vertex, -y, -x, 0);
01130         remap_policy::set(m->vertex, -x, y, 0);
01131         remap_policy::set(o->vertex, y, x, 0);
01132 
01133         ++count;
01134 
01135         {
01136             const double theta = increment * count;
01137             x = static_cast<float> (radius * cos(theta));
01138             y = static_cast<float> (radius * sin(theta));
01139         }
01140 
01141         remap_policy::set(j->vertex, y, -x, 0);
01142         remap_policy::set(l->vertex, -x, -y, 0);
01143         remap_policy::set(n->vertex, -y, x, 0);
01144         remap_policy::set(p->vertex, x, y, 0);
01145     }
01146 }
01147 
01148 #if 0
01149 class PointVertexArrayIterator
01150 {
01151     PointVertex* m_point;
01152     public:
01153     PointVertexArrayIterator(PointVertex* point)
01154     : m_point(point)
01155     {
01156     }
01157     PointVertexArrayIterator& operator++()
01158     {
01159         ++m_point;
01160         return *this;
01161     }
01162     PointVertexArrayIterator operator++(int)
01163     {
01164         PointVertexArrayIterator tmp(*this);
01165         ++m_point;
01166         return tmp;
01167     }
01168     Vertex3f& operator*()
01169     {
01170         return m_point.vertex;
01171     }
01172     Vertex3f* operator->()
01173     {
01174         return &(operator*());
01175     }
01176 }
01177 
01178 template<typename remap_policy, typename iterator_type
01179 inline void draw_circle(const std::size_t segments, const float radius, iterator_type start, remap_policy remap)
01180 {
01181     const float increment = c_pi / (double)(segments << 2);
01182 
01183     std::size_t count = 0;
01184     iterator_type pxpy(start);
01185     iterator_type pypx(pxpy + (segments << 1));
01186     iterator_type pynx(pxpy + (segments << 1));
01187     iterator_type nxpy(pypx + (segments << 1));
01188     iterator_type nxny(pypx + (segments << 1));
01189     iterator_type nynx(nxpy + (segments << 1));
01190     iterator_type nypx(nxpy + (segments << 1));
01191     iterator_type pxny(start);
01192     while(count < segments)
01193     {
01194         const float theta = increment * count;
01195         const float x = radius * cos(theta);
01196         const float y = radius * sin(theta);
01197 
01198         remap_policy::set((*pxpy), x, y, 0);
01199         remap_policy::set((*pxny), x,-y, 0);
01200         remap_policy::set((*nxpy),-x, y, 0);
01201         remap_policy::set((*nxny),-x,-y, 0);
01202 
01203         remap_policy::set((*pypx), y, x, 0);
01204         remap_policy::set((*pynx), y,-x, 0);
01205         remap_policy::set((*nypx),-y, x, 0);
01206         remap_policy::set((*nynx),-y,-x, 0);
01207     }
01208 }
01209 
01210 template<typename remap_policy, typename iterator_type
01211 inline void draw_semicircle(const std::size_t segments, const float radius, iterator_type start, remap_policy remap)
01212 {
01213     const float increment = c_pi / (double)(segments << 2);
01214 
01215     std::size_t count = 0;
01216     iterator_type pxpy(start);
01217     iterator_type pypx(pxpy + (segments << 1));
01218     iterator_type pynx(pxpy + (segments << 1));
01219     iterator_type nxpy(pypx + (segments << 1));
01220     iterator_type nxny(pypx + (segments << 1));
01221     iterator_type nynx(nxpy + (segments << 1));
01222     iterator_type nypx(nxpy + (segments << 1));
01223     iterator_type pxny(start);
01224     while(count < segments)
01225     {
01226         const float theta = increment * count;
01227         const float x = radius * cos(theta);
01228         const float y = radius * sin(theta);
01229 
01230         remap_policy::set((*pxpy), x, y, 0);
01231         remap_policy::set((*pxny), x,-y, 0);
01232         remap_policy::set((*nxpy),-x, y, 0);
01233         remap_policy::set((*nxny),-x,-y, 0);
01234 
01235         //remap_policy::set((*pypx), y, x, 0);
01236         //remap_policy::set((*pynx), y,-x, 0);
01237         //remap_policy::set((*nypx),-y, x, 0);
01238         //remap_policy::set((*nynx),-y,-x, 0);
01239     }
01240 }
01241 
01242 #endif
01243 
01244 inline void draw_quad (const float radius, PointVertex* quad)
01245 {
01246     (*quad++).vertex = Vertex3f(-radius, radius, 0);
01247     (*quad++).vertex = Vertex3f(radius, radius, 0);
01248     (*quad++).vertex = Vertex3f(radius, -radius, 0);
01249     (*quad++).vertex = Vertex3f(-radius, -radius, 0);
01250 }
01251 
01252 inline void draw_cube (const float radius, PointVertex* cube)
01253 {
01254     (*cube++).vertex = Vertex3f(-radius, -radius, -radius);
01255     (*cube++).vertex = Vertex3f(radius, -radius, -radius);
01256     (*cube++).vertex = Vertex3f(-radius, radius, -radius);
01257     (*cube++).vertex = Vertex3f(radius, radius, -radius);
01258     (*cube++).vertex = Vertex3f(-radius, -radius, radius);
01259     (*cube++).vertex = Vertex3f(radius, -radius, radius);
01260     (*cube++).vertex = Vertex3f(-radius, radius, radius);
01261     (*cube++).vertex = Vertex3f(radius, radius, radius);
01262 }
01263 
01265 inline void ArbitraryMeshTriangle_calcTangents (const ArbitraryMeshVertex& a, const ArbitraryMeshVertex& b,
01266         const ArbitraryMeshVertex& c, Vector3& s, Vector3& t)
01267 {
01268     s = Vector3(0, 0, 0);
01269     t = Vector3(0, 0, 0);
01270     Vector3 aVec, bVec, cVec;
01271     {
01272         aVec = Vector3(a.vertex.x(), a.texcoord.s(), a.texcoord.t());
01273         bVec = Vector3(b.vertex.x(), b.texcoord.s(), b.texcoord.t());
01274         cVec = Vector3(c.vertex.x(), c.texcoord.s(), c.texcoord.t());
01275         Vector3 cross((bVec - aVec).crossProduct(cVec - aVec));
01276 
01277         if (fabs(cross.x()) > 0.000001f) {
01278             s.x() = -cross.y() / cross.x();
01279         }
01280 
01281         if (fabs(cross.x()) > 0.000001f) {
01282             t.x() = -cross.z() / cross.x();
01283         }
01284     }
01285 
01286     {
01287         aVec = Vector3(a.vertex.y(), a.texcoord.s(), a.texcoord.t());
01288         bVec = Vector3(b.vertex.y(), b.texcoord.s(), b.texcoord.t());
01289         cVec = Vector3(c.vertex.y(), c.texcoord.s(), c.texcoord.t());
01290         Vector3 cross((bVec - aVec).crossProduct(cVec - aVec));
01291 
01292         if (fabs(cross.x()) > 0.000001f) {
01293             s.y() = -cross.y() / cross.x();
01294         }
01295 
01296         if (fabs(cross.x()) > 0.000001f) {
01297             t.y() = -cross.z() / cross.x();
01298         }
01299     }
01300 
01301     {
01302         aVec = Vector3(a.vertex.z(), a.texcoord.s(), a.texcoord.t());
01303         bVec = Vector3(b.vertex.z(), b.texcoord.s(), b.texcoord.t());
01304         cVec = Vector3(c.vertex.z(), c.texcoord.s(), c.texcoord.t());
01305         Vector3 cross((bVec - aVec).crossProduct(cVec - aVec));
01306 
01307         if (fabs(cross.x()) > 0.000001f) {
01308             s.z() = -cross.y() / cross.x();
01309         }
01310 
01311         if (fabs(cross.x()) > 0.000001f) {
01312             t.z() = -cross.z() / cross.x();
01313         }
01314     }
01315 }
01316 
01317 inline void ArbitraryMeshTriangle_sumTangents (ArbitraryMeshVertex& a, ArbitraryMeshVertex& b, ArbitraryMeshVertex& c)
01318 {
01319     Vector3 s, t;
01320 
01321     ArbitraryMeshTriangle_calcTangents(a, b, c, s, t);
01322 
01323     reinterpret_cast<Vector3&> (a.tangent) += s;
01324     reinterpret_cast<Vector3&> (b.tangent) += s;
01325     reinterpret_cast<Vector3&> (c.tangent) += s;
01326 
01327     reinterpret_cast<Vector3&> (a.bitangent) += t;
01328     reinterpret_cast<Vector3&> (b.bitangent) += t;
01329     reinterpret_cast<Vector3&> (c.bitangent) += t;
01330 }
01331 
01332 #endif

Generated by  doxygen 1.6.2