00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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
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
00757
00758
00759
00760
00761
00762
00763
00764
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
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
00843
00844
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
01236
01237
01238
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