X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=libs%2Frender.h;h=b2e6c5e92da32472977e1a439845d3b4deea3350;hb=fa4a5ccafc7fa6ef1cce4d63112f78a9b95c4fc2;hp=fb243650a5e1d24b87e18abca04b919e4f794bda;hpb=231225d6f97d0b926b2e896e5783cccfbc7c5619;p=xonotic%2Fnetradiant.git diff --git a/libs/render.h b/libs/render.h index fb243650..b2e6c5e9 100644 --- a/libs/render.h +++ b/libs/render.h @@ -1,25 +1,25 @@ /* -Copyright (C) 2001-2006, William Joseph. -All Rights Reserved. + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ -#if !defined(INCLUDED_RENDER_H) +#if !defined( INCLUDED_RENDER_H ) #define INCLUDED_RENDER_H /// \file @@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "igl.h" #include "container/array.h" -#include "math/vector.h" +#include "math/vector.h" #include "math/pi.h" #include @@ -40,75 +40,61 @@ const GLenum RenderIndexTypeID = GL_UNSIGNED_INT; /// \brief A resizable buffer of indices. class IndexBuffer { - typedef std::vector Indices; - Indices m_data; +typedef std::vector Indices; +Indices m_data; public: - typedef Indices::iterator iterator; - typedef Indices::const_iterator const_iterator; - - iterator begin() - { - return m_data.begin(); - } - const_iterator begin() const - { - return m_data.begin(); - } - iterator end() - { - return m_data.end(); - } - const_iterator end() const - { - return m_data.end(); - } - - bool empty() const - { - return m_data.empty(); - } - std::size_t size() const - { - return m_data.size(); - } - const RenderIndex* data() const - { - return &(*m_data.begin()); - } - RenderIndex& operator[](std::size_t index) - { - return m_data[index]; - } - const RenderIndex& operator[](std::size_t index) const - { - return m_data[index]; - } - void clear() - { - m_data.clear(); - } - void reserve(std::size_t max_indices) - { - m_data.reserve(max_indices); - } - void insert(RenderIndex index) - { - m_data.push_back(index); - } - void swap(IndexBuffer& other) - { - std::swap(m_data, m_data); - } +typedef Indices::iterator iterator; +typedef Indices::const_iterator const_iterator; + +iterator begin(){ + return m_data.begin(); +} +const_iterator begin() const { + return m_data.begin(); +} +iterator end(){ + return m_data.end(); +} +const_iterator end() const { + return m_data.end(); +} + +bool empty() const { + return m_data.empty(); +} +std::size_t size() const { + return m_data.size(); +} +const RenderIndex* data() const { + return &( *m_data.begin() ); +} +RenderIndex& operator[]( std::size_t index ){ + return m_data[index]; +} +const RenderIndex& operator[]( std::size_t index ) const { + return m_data[index]; +} +void clear(){ + m_data.clear(); +} +void reserve( std::size_t max_indices ){ + m_data.reserve( max_indices ); +} +void insert( RenderIndex index ){ + m_data.push_back( index ); +} +void swap( IndexBuffer& other ){ + std::swap( m_data, other.m_data ); +} }; namespace std { - /// \brief Swaps the values of \p self and \p other. - /// Overloads std::swap. - inline void swap(IndexBuffer& self, IndexBuffer& other) - { - self.swap(other); - } +/// \brief Swaps the values of \p self and \p other. +/// Overloads std::swap. +inline void swap( IndexBuffer& self, IndexBuffer& other ){ + self.swap( other ); +} } /// \brief A resizable buffer of vertices. @@ -116,62 +102,50 @@ namespace std template class VertexBuffer { - typedef typename std::vector Vertices; - Vertices m_data; +typedef typename std::vector Vertices; +Vertices m_data; public: - typedef typename Vertices::iterator iterator; - typedef typename Vertices::const_iterator const_iterator; - - iterator begin() - { - return m_data.begin(); - } - iterator end() - { - return m_data.end(); - } - const_iterator begin() const - { - return m_data.begin(); - } - const_iterator end() const - { - return m_data.end(); - } - - bool empty() const - { - return m_data.empty(); - } - RenderIndex size() const - { - return RenderIndex(m_data.size()); - } - const Vertex* data() const - { - return &(*m_data.begin()); - } - Vertex& operator[](std::size_t index) - { - return m_data[index]; - } - const Vertex& operator[](std::size_t index) const - { - return m_data[index]; - } - - void clear() - { - m_data.clear(); - } - void reserve(std::size_t max_vertices) - { - m_data.reserve(max_vertices); - } - void push_back(const Vertex& vertex) - { - m_data.push_back(vertex); - } +typedef typename Vertices::iterator iterator; +typedef typename Vertices::const_iterator const_iterator; + +iterator begin(){ + return m_data.begin(); +} +iterator end(){ + return m_data.end(); +} +const_iterator begin() const { + return m_data.begin(); +} +const_iterator end() const { + return m_data.end(); +} + +bool empty() const { + return m_data.empty(); +} +RenderIndex size() const { + return RenderIndex( m_data.size() ); +} +const Vertex* data() const { + return &( *m_data.begin() ); +} +Vertex& operator[]( std::size_t index ){ + return m_data[index]; +} +const Vertex& operator[]( std::size_t index ) const { + return m_data[index]; +} + +void clear(){ + m_data.clear(); +} +void reserve( std::size_t max_vertices ){ + m_data.reserve( max_vertices ); +} +void push_back( const Vertex& vertex ){ + m_data.push_back( vertex ); +} }; /// \brief A wrapper around a VertexBuffer which inserts only vertices which have not already been inserted. @@ -180,1192 +154,1047 @@ public: template class UniqueVertexBuffer { - typedef VertexBuffer Vertices; - Vertices& m_data; - - struct bnode - { - bnode() - : m_left(0), m_right(0) - { - } - RenderIndex m_left; - RenderIndex m_right; - }; - - std::vector m_btree; - RenderIndex m_prev0; - RenderIndex m_prev1; - RenderIndex m_prev2; - - const RenderIndex find_or_insert(const Vertex& vertex) - { - RenderIndex index = 0; - - while(1) - { - if(vertex < m_data[index]) - { - bnode& node = m_btree[index]; - if(node.m_left != 0) - { - index = node.m_left; - continue; - } - else - { - node.m_left = RenderIndex(m_btree.size()); - m_btree.push_back(bnode()); - m_data.push_back(vertex); - return RenderIndex(m_btree.size()-1); - } - } - if(m_data[index] < vertex) - { - bnode& node = m_btree[index]; - if(node.m_right != 0) - { - index = node.m_right; - continue; - } - else - { - node.m_right = RenderIndex(m_btree.size()); - m_btree.push_back(bnode()); - m_data.push_back(vertex); - return RenderIndex(m_btree.size()-1); - } - } - - return index; - } - } +typedef VertexBuffer Vertices; +Vertices& m_data; + +struct bnode +{ + bnode() + : m_left( 0 ), m_right( 0 ){ + } + RenderIndex m_left; + RenderIndex m_right; +}; + +std::vector m_btree; +RenderIndex m_prev0; +RenderIndex m_prev1; +RenderIndex m_prev2; + +RenderIndex find_or_insert( const Vertex& vertex ){ + RenderIndex index = 0; + + while ( 1 ) + { + if ( vertex < m_data[index] ) { + bnode& node = m_btree[index]; + if ( node.m_left != 0 ) { + index = node.m_left; + continue; + } + else + { + node.m_left = RenderIndex( m_btree.size() ); + m_btree.push_back( bnode() ); + m_data.push_back( vertex ); + return RenderIndex( m_btree.size() - 1 ); + } + } + if ( m_data[index] < vertex ) { + bnode& node = m_btree[index]; + if ( node.m_right != 0 ) { + index = node.m_right; + continue; + } + else + { + node.m_right = RenderIndex( m_btree.size() ); + m_btree.push_back( bnode() ); + m_data.push_back( vertex ); + return RenderIndex( m_btree.size() - 1 ); + } + } + + return index; + } +} public: - UniqueVertexBuffer(Vertices& data) - : m_data(data), m_prev0(0), m_prev1(0), m_prev2(0) - { - } - - typedef typename Vertices::const_iterator iterator; - - iterator begin() const - { - return m_data.begin(); - } - iterator end() const - { - return m_data.end(); - } - - std::size_t size() const - { - return m_data.size(); - } - const Vertex* data() const - { - return &(*m_data.begin()); - } - Vertex& operator[](std::size_t index) - { - return m_data[index]; - } - const Vertex& operator[](std::size_t index) const - { - return m_data[index]; - } - - void clear() - { - m_prev0 = 0; - m_prev1 = 0; - m_prev2 = 0; - m_data.clear(); - m_btree.clear(); - } - void reserve(std::size_t max_vertices) - { - m_data.reserve(max_vertices); - m_btree.reserve(max_vertices); - } - /// \brief Returns the index of the element equal to \p vertex. - RenderIndex insert(const Vertex& vertex) - { - if(m_data.empty()) - { - m_data.push_back(vertex); - m_btree.push_back(bnode()); - return 0; - } - - if(m_data[m_prev0] == vertex) - return m_prev0; - if(m_prev1 != m_prev0 && m_data[m_prev1] == vertex) - return m_prev1; - if(m_prev2 != m_prev0 && m_prev2 != m_prev1 && m_data[m_prev2] == vertex) - return m_prev2; - - m_prev2 = m_prev1; - m_prev1 = m_prev0; - m_prev0 = find_or_insert(vertex); - - return m_prev0; - } +UniqueVertexBuffer( Vertices& data ) + : m_data( data ), m_prev0( 0 ), m_prev1( 0 ), m_prev2( 0 ){ +} + +typedef typename Vertices::const_iterator iterator; + +iterator begin() const { + return m_data.begin(); +} +iterator end() const { + return m_data.end(); +} + +std::size_t size() const { + return m_data.size(); +} +const Vertex* data() const { + return &( *m_data.begin() ); +} +Vertex& operator[]( std::size_t index ){ + return m_data[index]; +} +const Vertex& operator[]( std::size_t index ) const { + return m_data[index]; +} + +void clear(){ + m_prev0 = 0; + m_prev1 = 0; + m_prev2 = 0; + m_data.clear(); + m_btree.clear(); +} +void reserve( std::size_t max_vertices ){ + m_data.reserve( max_vertices ); + m_btree.reserve( max_vertices ); +} +/// \brief Returns the index of the element equal to \p vertex. +RenderIndex insert( const Vertex& vertex ){ + if ( m_data.empty() ) { + m_data.push_back( vertex ); + m_btree.push_back( bnode() ); + return 0; + } + + if ( m_data[m_prev0] == vertex ) { + return m_prev0; + } + if ( m_prev1 != m_prev0 && m_data[m_prev1] == vertex ) { + return m_prev1; + } + if ( m_prev2 != m_prev0 && m_prev2 != m_prev1 && m_data[m_prev2] == vertex ) { + return m_prev2; + } + + m_prev2 = m_prev1; + m_prev1 = m_prev0; + m_prev0 = find_or_insert( vertex ); + + return m_prev0; +} }; /// \brief A 4-byte colour. struct Colour4b { - unsigned char r, g, b, a; + unsigned char r, g, b, a; - Colour4b() - { - } + Colour4b(){ + } - Colour4b(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) - : r(_r), g(_g), b(_b), a(_a) - { - } + Colour4b( unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a ) + : r( _r ), g( _g ), b( _b ), a( _a ){ + } }; -const Colour4b colour_vertex(0, 255, 0, 255); -const Colour4b colour_selected(0, 0, 255, 255); +const Colour4b colour_vertex( 0, 255, 0, 255 ); +const Colour4b colour_selected( 0, 0, 255, 255 ); -inline bool operator<(const Colour4b& self, const Colour4b& other) -{ - if(self.r != other.r) - { - return self.r < other.r; - } - if(self.g != other.g) - { - return self.g < other.g; - } - if(self.b != other.b) - { - return self.b < other.b; - } - if(self.a != other.a) - { - return self.a < other.a; - } - return false; -} - -inline bool operator==(const Colour4b& self, const Colour4b& other) -{ - return self.r == other.r && self.g == other.g && self.b == other.b && self.a == other.a; +inline bool operator<( const Colour4b& self, const Colour4b& other ){ + if ( self.r != other.r ) { + return self.r < other.r; + } + if ( self.g != other.g ) { + return self.g < other.g; + } + if ( self.b != other.b ) { + return self.b < other.b; + } + if ( self.a != other.a ) { + return self.a < other.a; + } + return false; } -inline bool operator!=(const Colour4b& self, const Colour4b& other) -{ - return !operator==(self, other); +inline bool operator==( const Colour4b& self, const Colour4b& other ){ + return self.r == other.r && self.g == other.g && self.b == other.b && self.a == other.a; +} + +inline bool operator!=( const Colour4b& self, const Colour4b& other ){ + return !operator==( self, other ); } /// \brief A 3-float vertex. struct Vertex3f : public Vector3 { - Vertex3f() - { - } - - Vertex3f(float _x, float _y, float _z) - : Vector3(_x, _y, _z) - { - } + Vertex3f(){ + } + + Vertex3f( float _x, float _y, float _z ) + : Vector3( _x, _y, _z ){ + } }; -inline bool operator<(const Vertex3f& self, const Vertex3f& other) -{ - if(self.x() != other.x()) - { - return self.x() < other.x(); - } - if(self.y() != other.y()) - { - return self.y() < other.y(); - } - if(self.z() != other.z()) - { - return self.z() < other.z(); - } - return false; -} - -inline bool operator==(const Vertex3f& self, const Vertex3f& other) -{ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); +inline bool operator<( const Vertex3f& self, const Vertex3f& other ){ + if ( self.x() != other.x() ) { + return self.x() < other.x(); + } + if ( self.y() != other.y() ) { + return self.y() < other.y(); + } + if ( self.z() != other.z() ) { + return self.z() < other.z(); + } + return false; } -inline bool operator!=(const Vertex3f& self, const Vertex3f& other) -{ - return !operator==(self, other); +inline bool operator==( const Vertex3f& self, const Vertex3f& other ){ + return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); } +inline bool operator!=( const Vertex3f& self, const Vertex3f& other ){ + return !operator==( self, other ); +} -inline Vertex3f vertex3f_from_array(const float* array) -{ - return Vertex3f(array[0], array[1], array[2]); + +inline Vertex3f vertex3f_from_array( const float* array ){ + return Vertex3f( array[0], array[1], array[2] ); } -inline float* vertex3f_to_array(Vertex3f& vertex) -{ - return reinterpret_cast(&vertex); +inline float* vertex3f_to_array( Vertex3f& vertex ){ + return reinterpret_cast( &vertex ); } -inline const float* vertex3f_to_array(const Vertex3f& vertex) -{ - return reinterpret_cast(&vertex); +inline const float* vertex3f_to_array( const Vertex3f& vertex ){ + return reinterpret_cast( &vertex ); } -const Vertex3f vertex3f_identity(0, 0, 0); +const Vertex3f vertex3f_identity( 0, 0, 0 ); -inline Vertex3f vertex3f_for_vector3(const Vector3& vector3) -{ - return Vertex3f(vector3.x(), vector3.y(), vector3.z()); +inline Vertex3f vertex3f_for_vector3( const Vector3& vector3 ){ + return Vertex3f( vector3.x(), vector3.y(), vector3.z() ); } -inline const Vector3& vertex3f_to_vector3(const Vertex3f& vertex) -{ - return vertex; +inline const Vector3& vertex3f_to_vector3( const Vertex3f& vertex ){ + return vertex; } -inline Vector3& vertex3f_to_vector3(Vertex3f& vertex) -{ - return vertex; +inline Vector3& vertex3f_to_vector3( Vertex3f& vertex ){ + return vertex; } /// \brief A 3-float normal. struct Normal3f : public Vector3 { - Normal3f() - { - } - - Normal3f(float _x, float _y, float _z) - : Vector3(_x, _y, _z) - { - } + Normal3f(){ + } + + Normal3f( float _x, float _y, float _z ) + : Vector3( _x, _y, _z ){ + } }; -inline bool operator<(const Normal3f& self, const Normal3f& other) -{ - if(self.x() != other.x()) - { - return self.x() < other.x(); - } - if(self.y() != other.y()) - { - return self.y() < other.y(); - } - if(self.z() != other.z()) - { - return self.z() < other.z(); - } - return false; -} - -inline bool operator==(const Normal3f& self, const Normal3f& other) -{ - return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); +inline bool operator<( const Normal3f& self, const Normal3f& other ){ + if ( self.x() != other.x() ) { + return self.x() < other.x(); + } + if ( self.y() != other.y() ) { + return self.y() < other.y(); + } + if ( self.z() != other.z() ) { + return self.z() < other.z(); + } + return false; } -inline bool operator!=(const Normal3f& self, const Normal3f& other) -{ - return !operator==(self, other); +inline bool operator==( const Normal3f& self, const Normal3f& other ){ + return self.x() == other.x() && self.y() == other.y() && self.z() == other.z(); } +inline bool operator!=( const Normal3f& self, const Normal3f& other ){ + return !operator==( self, other ); +} -inline Normal3f normal3f_from_array(const float* array) -{ - return Normal3f(array[0], array[1], array[2]); + +inline Normal3f normal3f_from_array( const float* array ){ + return Normal3f( array[0], array[1], array[2] ); } -inline float* normal3f_to_array(Normal3f& normal) -{ - return reinterpret_cast(&normal); +inline float* normal3f_to_array( Normal3f& normal ){ + return reinterpret_cast( &normal ); } -inline const float* normal3f_to_array(const Normal3f& normal) -{ - return reinterpret_cast(&normal); +inline const float* normal3f_to_array( const Normal3f& normal ){ + return reinterpret_cast( &normal ); } -inline Normal3f normal3f_for_vector3(const Vector3& vector3) -{ - return Normal3f(vector3.x(), vector3.y(), vector3.z()); +inline Normal3f normal3f_for_vector3( const Vector3& vector3 ){ + return Normal3f( vector3.x(), vector3.y(), vector3.z() ); } -inline const Vector3& normal3f_to_vector3(const Normal3f& normal) -{ - return normal; +inline const Vector3& normal3f_to_vector3( const Normal3f& normal ){ + return normal; } -inline Vector3& normal3f_to_vector3(Normal3f& normal) -{ - return normal; +inline Vector3& normal3f_to_vector3( Normal3f& normal ){ + return normal; } /// \brief A 2-float texture-coordinate set. struct TexCoord2f : public Vector2 { - TexCoord2f() - { - } - - TexCoord2f(float _s, float _t) - : Vector2(_s, _t) - { - } - - float& s() - { - return x(); - } - const float& s() const - { - return x(); - } - float& t() - { - return y(); - } - const float& t() const - { - return y(); - } + TexCoord2f(){ + } + + TexCoord2f( float _s, float _t ) + : Vector2( _s, _t ){ + } + + float& s(){ + return x(); + } + const float& s() const { + return x(); + } + float& t(){ + return y(); + } + const float& t() const { + return y(); + } }; -inline bool operator<(const TexCoord2f& self, const TexCoord2f& other) -{ - if(self.s() != other.s()) - { - return self.s() < other.s(); - } - if(self.t() != other.t()) - { - return self.t() < other.t(); - } - return false; -} - -inline bool operator==(const TexCoord2f& self, const TexCoord2f& other) -{ - return self.s() == other.s() && self.t() == other.t(); +inline bool operator<( const TexCoord2f& self, const TexCoord2f& other ){ + if ( self.s() != other.s() ) { + return self.s() < other.s(); + } + if ( self.t() != other.t() ) { + return self.t() < other.t(); + } + return false; } -inline bool operator!=(const TexCoord2f& self, const TexCoord2f& other) -{ - return !operator==(self, other); +inline bool operator==( const TexCoord2f& self, const TexCoord2f& other ){ + return self.s() == other.s() && self.t() == other.t(); +} + +inline bool operator!=( const TexCoord2f& self, const TexCoord2f& other ){ + return !operator==( self, other ); } -inline float* texcoord2f_to_array(TexCoord2f& texcoord) -{ - return reinterpret_cast(&texcoord); +inline float* texcoord2f_to_array( TexCoord2f& texcoord ){ + return reinterpret_cast( &texcoord ); } -inline const float* texcoord2f_to_array(const TexCoord2f& texcoord) -{ - return reinterpret_cast(&texcoord); +inline const float* texcoord2f_to_array( const TexCoord2f& texcoord ){ + return reinterpret_cast( &texcoord ); } -inline const TexCoord2f& texcoord2f_from_array(const float* array) -{ - return *reinterpret_cast(array); +inline const TexCoord2f& texcoord2f_from_array( const float* array ){ + return *reinterpret_cast( array ); } -inline TexCoord2f texcoord2f_for_vector2(const Vector2& vector2) -{ - return TexCoord2f(vector2.x(), vector2.y()); +inline TexCoord2f texcoord2f_for_vector2( const Vector2& vector2 ){ + return TexCoord2f( vector2.x(), vector2.y() ); } -inline const Vector2& texcoord2f_to_vector2(const TexCoord2f& vertex) -{ - return vertex; +inline const Vector2& texcoord2f_to_vector2( const TexCoord2f& vertex ){ + return vertex; } -inline Vector2& texcoord2f_to_vector2(TexCoord2f& vertex) -{ - return vertex; +inline Vector2& texcoord2f_to_vector2( TexCoord2f& vertex ){ + return vertex; } -/// \brief Returns \p normal rescaled to be unit-length. -inline Normal3f normal3f_normalised(const Normal3f& normal) -{ - return normal3f_for_vector3(vector3_normalised(normal3f_to_vector3(normal))); +/// \brief Returns \p normal rescaled to be unit-length. +inline Normal3f normal3f_normalised( const Normal3f& normal ){ + return normal3f_for_vector3( vector3_normalised( normal3f_to_vector3( normal ) ) ); } enum UnitSphereOctant { - UNITSPHEREOCTANT_000 = 0 << 0 | 0 << 1 | 0 << 2, - UNITSPHEREOCTANT_001 = 0 << 0 | 0 << 1 | 1 << 2, - UNITSPHEREOCTANT_010 = 0 << 0 | 1 << 1 | 0 << 2, - UNITSPHEREOCTANT_011 = 0 << 0 | 1 << 1 | 1 << 2, - UNITSPHEREOCTANT_100 = 1 << 0 | 0 << 1 | 0 << 2, - UNITSPHEREOCTANT_101 = 1 << 0 | 0 << 1 | 1 << 2, - UNITSPHEREOCTANT_110 = 1 << 0 | 1 << 1 | 0 << 2, - UNITSPHEREOCTANT_111 = 1 << 0 | 1 << 1 | 1 << 2, + UNITSPHEREOCTANT_000 = 0 << 0 | 0 << 1 | 0 << 2, + UNITSPHEREOCTANT_001 = 0 << 0 | 0 << 1 | 1 << 2, + UNITSPHEREOCTANT_010 = 0 << 0 | 1 << 1 | 0 << 2, + UNITSPHEREOCTANT_011 = 0 << 0 | 1 << 1 | 1 << 2, + UNITSPHEREOCTANT_100 = 1 << 0 | 0 << 1 | 0 << 2, + UNITSPHEREOCTANT_101 = 1 << 0 | 0 << 1 | 1 << 2, + UNITSPHEREOCTANT_110 = 1 << 0 | 1 << 1 | 0 << 2, + UNITSPHEREOCTANT_111 = 1 << 0 | 1 << 1 | 1 << 2, }; /// \brief Returns the octant for \p normal indicating the sign of the region of unit-sphere space it lies within. -inline UnitSphereOctant normal3f_classify_octant(const Normal3f& normal) -{ - return static_cast( - ((normal.x() > 0) << 0) | ((normal.y() > 0) << 1) | ((normal.z() > 0) << 2) - ); +inline UnitSphereOctant normal3f_classify_octant( const Normal3f& normal ){ + return static_cast( + ( ( normal.x() > 0 ) << 0 ) | ( ( normal.y() > 0 ) << 1 ) | ( ( normal.z() > 0 ) << 2 ) + ); } /// \brief Returns \p normal with its components signs made positive based on \p octant. -inline Normal3f normal3f_fold_octant(const Normal3f& normal, UnitSphereOctant octant) -{ - switch(octant) - { - case UNITSPHEREOCTANT_000: - return Normal3f(-normal.x(), -normal.y(), -normal.z()); - case UNITSPHEREOCTANT_001: - return Normal3f(normal.x(), -normal.y(), -normal.z()); - case UNITSPHEREOCTANT_010: - return Normal3f(-normal.x(), normal.y(), -normal.z()); - case UNITSPHEREOCTANT_011: - return Normal3f(normal.x(), normal.y(), -normal.z()); - case UNITSPHEREOCTANT_100: - return Normal3f(-normal.x(), -normal.y(), normal.z()); - case UNITSPHEREOCTANT_101: - return Normal3f(normal.x(), -normal.y(), normal.z()); - case UNITSPHEREOCTANT_110: - return Normal3f(-normal.x(), normal.y(), normal.z()); - case UNITSPHEREOCTANT_111: - return Normal3f(normal.x(), normal.y(), normal.z()); - } - return Normal3f(); +inline Normal3f normal3f_fold_octant( const Normal3f& normal, UnitSphereOctant octant ){ + switch ( octant ) + { + case UNITSPHEREOCTANT_000: + return Normal3f( -normal.x(), -normal.y(), -normal.z() ); + case UNITSPHEREOCTANT_001: + return Normal3f( normal.x(), -normal.y(), -normal.z() ); + case UNITSPHEREOCTANT_010: + return Normal3f( -normal.x(), normal.y(), -normal.z() ); + case UNITSPHEREOCTANT_011: + return Normal3f( normal.x(), normal.y(), -normal.z() ); + case UNITSPHEREOCTANT_100: + return Normal3f( -normal.x(), -normal.y(), normal.z() ); + case UNITSPHEREOCTANT_101: + return Normal3f( normal.x(), -normal.y(), normal.z() ); + case UNITSPHEREOCTANT_110: + return Normal3f( -normal.x(), normal.y(), normal.z() ); + case UNITSPHEREOCTANT_111: + return Normal3f( normal.x(), normal.y(), normal.z() ); + } + return Normal3f(); } /// \brief Reverses the effect of normal3f_fold_octant() on \p normal with \p octant. /// \p normal must have been obtained with normal3f_fold_octant(). /// \p octant must have been obtained with normal3f_classify_octant(). -inline Normal3f normal3f_unfold_octant(const Normal3f& normal, UnitSphereOctant octant) -{ - return normal3f_fold_octant(normal, octant); +inline Normal3f normal3f_unfold_octant( const Normal3f& normal, UnitSphereOctant octant ){ + return normal3f_fold_octant( normal, octant ); } enum UnitSphereSextant { - UNITSPHERESEXTANT_XYZ = 0, - UNITSPHERESEXTANT_XZY = 1, - UNITSPHERESEXTANT_YXZ = 2, - UNITSPHERESEXTANT_YZX = 3, - UNITSPHERESEXTANT_ZXY = 4, - UNITSPHERESEXTANT_ZYX = 5, + UNITSPHERESEXTANT_XYZ = 0, + UNITSPHERESEXTANT_XZY = 1, + UNITSPHERESEXTANT_YXZ = 2, + UNITSPHERESEXTANT_YZX = 3, + UNITSPHERESEXTANT_ZXY = 4, + UNITSPHERESEXTANT_ZYX = 5, }; /// \brief Returns the sextant for \p normal indicating how to sort its components so that x > y > z. /// All components of \p normal must be positive. /// \p normal must be normalised. -inline UnitSphereSextant normal3f_classify_sextant(const Normal3f& normal) -{ - return - normal.x() >= normal.y() - ? normal.x() >= normal.z() - ? normal.y() >= normal.z() - ? UNITSPHERESEXTANT_XYZ - : UNITSPHERESEXTANT_XZY - : UNITSPHERESEXTANT_ZXY - : normal.y() >= normal.z() - ? normal.x() >= normal.z() - ? UNITSPHERESEXTANT_YXZ - : UNITSPHERESEXTANT_YZX - : UNITSPHERESEXTANT_ZYX; +inline UnitSphereSextant normal3f_classify_sextant( const Normal3f& normal ){ + return + normal.x() >= normal.y() + ? normal.x() >= normal.z() + ? normal.y() >= normal.z() + ? UNITSPHERESEXTANT_XYZ + : UNITSPHERESEXTANT_XZY + : UNITSPHERESEXTANT_ZXY + : normal.y() >= normal.z() + ? normal.x() >= normal.z() + ? UNITSPHERESEXTANT_YXZ + : UNITSPHERESEXTANT_YZX + : UNITSPHERESEXTANT_ZYX; } /// \brief Returns \p normal with its components sorted so that x > y > z based on \p sextant. /// All components of \p normal must be positive. /// \p normal must be normalised. -inline Normal3f normal3f_fold_sextant(const Normal3f& normal, UnitSphereSextant sextant) -{ - switch(sextant) - { - case UNITSPHERESEXTANT_XYZ: - return Normal3f(normal.x(), normal.y(), normal.z()); - case UNITSPHERESEXTANT_XZY: - return Normal3f(normal.x(), normal.z(), normal.y()); - case UNITSPHERESEXTANT_YXZ: - return Normal3f(normal.y(), normal.x(), normal.z()); - case UNITSPHERESEXTANT_YZX: - return Normal3f(normal.y(), normal.z(), normal.x()); - case UNITSPHERESEXTANT_ZXY: - return Normal3f(normal.z(), normal.x(), normal.y()); - case UNITSPHERESEXTANT_ZYX: - return Normal3f(normal.z(), normal.y(), normal.x()); - } - return Normal3f(); +inline Normal3f normal3f_fold_sextant( const Normal3f& normal, UnitSphereSextant sextant ){ + switch ( sextant ) + { + case UNITSPHERESEXTANT_XYZ: + return Normal3f( normal.x(), normal.y(), normal.z() ); + case UNITSPHERESEXTANT_XZY: + return Normal3f( normal.x(), normal.z(), normal.y() ); + case UNITSPHERESEXTANT_YXZ: + return Normal3f( normal.y(), normal.x(), normal.z() ); + case UNITSPHERESEXTANT_YZX: + return Normal3f( normal.y(), normal.z(), normal.x() ); + case UNITSPHERESEXTANT_ZXY: + return Normal3f( normal.z(), normal.x(), normal.y() ); + case UNITSPHERESEXTANT_ZYX: + return Normal3f( normal.z(), normal.y(), normal.x() ); + } + return Normal3f(); } /// \brief Reverses the effect of normal3f_fold_sextant() on \p normal with \p sextant. /// \p normal must have been obtained with normal3f_fold_sextant(). /// \p sextant must have been obtained with normal3f_classify_sextant(). -inline Normal3f normal3f_unfold_sextant(const Normal3f& normal, UnitSphereSextant sextant) -{ - return normal3f_fold_sextant(normal, sextant); +inline Normal3f normal3f_unfold_sextant( const Normal3f& normal, UnitSphereSextant sextant ){ + return normal3f_fold_sextant( normal, sextant ); } const std::size_t c_quantise_normal = 1 << 6; /// \brief All the components of \p folded must be positive and sorted so that x > y > z. -inline Normal3f normal3f_folded_quantised(const Normal3f& folded) -{ - // compress - double scale = static_cast(c_quantise_normal) / (folded.x() + folded.y() + folded.z()); - unsigned int zbits = static_cast(folded.z() * scale); - unsigned int ybits = static_cast(folded.y() * scale); +inline Normal3f normal3f_folded_quantised( const Normal3f& folded ){ + // compress + double scale = static_cast( c_quantise_normal ) / ( folded.x() + folded.y() + folded.z() ); + unsigned int zbits = static_cast( folded.z() * scale ); + unsigned int ybits = static_cast( folded.y() * scale ); - // decompress - return normal3f_normalised(Normal3f( - static_cast(c_quantise_normal - zbits - ybits), - static_cast(ybits), - static_cast(zbits) - )); + // decompress + return normal3f_normalised( Normal3f( + static_cast( c_quantise_normal - zbits - ybits ), + static_cast( ybits ), + static_cast( zbits ) + ) ); } /// \brief Returns \p normal quantised by compressing and then decompressing its representation. -inline Normal3f normal3f_quantised_custom(const Normal3f& normal) -{ - UnitSphereOctant octant = normal3f_classify_octant(normal); - Normal3f folded = normal3f_fold_octant(normal, octant); - UnitSphereSextant sextant = normal3f_classify_sextant(folded); - folded = normal3f_fold_sextant(folded, sextant); - return normal3f_unfold_octant(normal3f_unfold_sextant(normal3f_folded_quantised(folded), sextant), octant); +inline Normal3f normal3f_quantised_custom( const Normal3f& normal ){ + UnitSphereOctant octant = normal3f_classify_octant( normal ); + Normal3f folded = normal3f_fold_octant( normal, octant ); + UnitSphereSextant sextant = normal3f_classify_sextant( folded ); + folded = normal3f_fold_sextant( folded, sextant ); + return normal3f_unfold_octant( normal3f_unfold_sextant( normal3f_folded_quantised( folded ), sextant ), octant ); } struct spherical_t { - double longditude, latitude; + double longditude, latitude; - spherical_t(double _longditude, double _latitude) - : longditude(_longditude), latitude(_latitude) - { - } + spherical_t( double _longditude, double _latitude ) + : longditude( _longditude ), latitude( _latitude ){ + } }; /* -{ - theta = 2pi * U; - phi = acos((2 * V) - 1); + { + theta = 2pi * U; + phi = acos((2 * V) - 1); - U = theta / 2pi; - V = (cos(phi) + 1) / 2; -} + U = theta / 2pi; + V = (cos(phi) + 1) / 2; + } -longitude = atan(y / x); -latitude = acos(z); -*/ + longitude = atan(y / x); + latitude = acos(z); + */ struct uniformspherical_t { - double U, V; + double U, V; - uniformspherical_t(double U_, double V_) - : U(U_), V(V_) - { - } + uniformspherical_t( double U_, double V_ ) + : U( U_ ), V( V_ ){ + } }; -inline spherical_t spherical_from_normal3f(const Normal3f& normal) -{ - return spherical_t(normal.x() == 0 ? c_pi / 2 : normal.x() > 0 ? atan(normal.y() / normal.x()) : atan(normal.y() / normal.x()) + c_pi, acos(normal.z())); +inline spherical_t spherical_from_normal3f( const Normal3f& normal ){ + return spherical_t( normal.x() == 0 ? c_pi / 2 : normal.x() > 0 ? atan( normal.y() / normal.x() ) : atan( normal.y() / normal.x() ) + c_pi, acos( normal.z() ) ); } -inline Normal3f normal3f_from_spherical(const spherical_t& spherical) -{ - return Normal3f( - static_cast(cos(spherical.longditude) * sin(spherical.latitude)), - static_cast(sin(spherical.longditude) * sin(spherical.latitude)), - static_cast(cos(spherical.latitude)) - ); +inline Normal3f normal3f_from_spherical( const spherical_t& spherical ){ + return Normal3f( + static_cast( cos( spherical.longditude ) * sin( spherical.latitude ) ), + static_cast( sin( spherical.longditude ) * sin( spherical.latitude ) ), + static_cast( cos( spherical.latitude ) ) + ); } -inline uniformspherical_t uniformspherical_from_spherical(const spherical_t& spherical) -{ - return uniformspherical_t(spherical.longditude * c_inv_2pi, (cos(spherical.latitude) + 1) * 0.5); +inline uniformspherical_t uniformspherical_from_spherical( const spherical_t& spherical ){ + return uniformspherical_t( spherical.longditude * c_inv_2pi, ( cos( spherical.latitude ) + 1 ) * 0.5 ); } -inline spherical_t spherical_from_uniformspherical(const uniformspherical_t& uniformspherical) -{ - return spherical_t(c_2pi * uniformspherical.U, acos((2 * uniformspherical.V) - 1)); +inline spherical_t spherical_from_uniformspherical( const uniformspherical_t& uniformspherical ){ + return spherical_t( c_2pi * uniformspherical.U, acos( ( 2 * uniformspherical.V ) - 1 ) ); } -inline uniformspherical_t uniformspherical_from_normal3f(const Normal3f& normal) -{ - return uniformspherical_from_spherical(spherical_from_normal3f(normal)); - //return uniformspherical_t(atan2(normal.y / normal.x) * c_inv_2pi, (normal.z + 1) * 0.5); +inline uniformspherical_t uniformspherical_from_normal3f( const Normal3f& normal ){ + return uniformspherical_from_spherical( spherical_from_normal3f( normal ) ); + //return uniformspherical_t(atan2(normal.y / normal.x) * c_inv_2pi, (normal.z + 1) * 0.5); } -inline Normal3f normal3f_from_uniformspherical(const uniformspherical_t& uniformspherical) -{ - return normal3f_from_spherical(spherical_from_uniformspherical(uniformspherical)); +inline Normal3f normal3f_from_uniformspherical( const uniformspherical_t& uniformspherical ){ + return normal3f_from_spherical( spherical_from_uniformspherical( uniformspherical ) ); } /// \brief Returns a single-precision \p component quantised to \p precision. -inline float float_quantise(float component, float precision) -{ - return float_snapped(component, precision); +inline float float_quantise( float component, float precision ){ + return float_snapped( component, precision ); } /// \brief Returns a double-precision \p component quantised to \p precision. -inline double double_quantise(double component, double precision) -{ - return float_snapped(component, precision); +inline double double_quantise( double component, double precision ){ + return float_snapped( component, precision ); } -inline spherical_t spherical_quantised(const spherical_t& spherical, float snap) -{ - return spherical_t(double_quantise(spherical.longditude, snap), double_quantise(spherical.latitude, snap)); +inline spherical_t spherical_quantised( const spherical_t& spherical, float snap ){ + return spherical_t( double_quantise( spherical.longditude, snap ), double_quantise( spherical.latitude, snap ) ); } -inline uniformspherical_t uniformspherical_quantised(const uniformspherical_t& uniformspherical, float snap) -{ - return uniformspherical_t(double_quantise(uniformspherical.U, snap), double_quantise(uniformspherical.V, snap)); +inline uniformspherical_t uniformspherical_quantised( const uniformspherical_t& uniformspherical, float snap ){ + return uniformspherical_t( double_quantise( uniformspherical.U, snap ), double_quantise( uniformspherical.V, snap ) ); } /// \brief Returns a \p vertex quantised to \p precision. -inline Vertex3f vertex3f_quantised(const Vertex3f& vertex, float precision) -{ - return Vertex3f(float_quantise(vertex.x(), precision), float_quantise(vertex.y(), precision), float_quantise(vertex.z(), precision)); +inline Vertex3f vertex3f_quantised( const Vertex3f& vertex, float precision ){ + return Vertex3f( float_quantise( vertex.x(), precision ), float_quantise( vertex.y(), precision ), float_quantise( vertex.z(), precision ) ); } /// \brief Returns a \p normal quantised to a fixed precision. -inline Normal3f normal3f_quantised(const Normal3f& normal) -{ - return normal3f_quantised_custom(normal); - //return normal3f_from_spherical(spherical_quantised(spherical_from_normal3f(normal), snap)); - //return normal3f_from_uniformspherical(uniformspherical_quantised(uniformspherical_from_normal3f(normal), snap)); - // float_quantise(normal.x, snap), float_quantise(normal.y, snap), float_quantise(normal.y, snap)); +inline Normal3f normal3f_quantised( const Normal3f& normal ){ + return normal3f_quantised_custom( normal ); + //return normal3f_from_spherical(spherical_quantised(spherical_from_normal3f(normal), snap)); + //return normal3f_from_uniformspherical(uniformspherical_quantised(uniformspherical_from_normal3f(normal), snap)); + // float_quantise(normal.x, snap), float_quantise(normal.y, snap), float_quantise(normal.y, snap)); } /// \brief Returns a \p texcoord quantised to \p precision. -inline TexCoord2f texcoord2f_quantised(const TexCoord2f& texcoord, float precision) -{ - return TexCoord2f(float_quantise(texcoord.s(), precision), float_quantise(texcoord.t(), precision)); +inline TexCoord2f texcoord2f_quantised( const TexCoord2f& texcoord, float precision ){ + return TexCoord2f( float_quantise( texcoord.s(), precision ), float_quantise( texcoord.t(), precision ) ); } /// \brief Standard vertex type for lines and points. struct PointVertex { - Colour4b colour; - Vertex3f vertex; - - PointVertex() - { - } - PointVertex(Vertex3f _vertex) - : colour(Colour4b(255, 255, 255, 255)), vertex(_vertex) - { - } - PointVertex(Vertex3f _vertex, Colour4b _colour) - : colour(_colour), vertex(_vertex) - { - } + Colour4b colour; + Vertex3f vertex; + + PointVertex(){ + } + PointVertex( Vertex3f _vertex ) + : colour( Colour4b( 255, 255, 255, 255 ) ), vertex( _vertex ){ + } + PointVertex( Vertex3f _vertex, Colour4b _colour ) + : colour( _colour ), vertex( _vertex ){ + } }; -inline bool operator<(const PointVertex& self, const PointVertex& other) -{ - if(self.vertex != other.vertex) - { - return self.vertex < other.vertex; - } - if(self.colour != other.colour) - { - return self.colour < other.colour; - } - return false; -} - -inline bool operator==(const PointVertex& self, const PointVertex& other) -{ - return self.colour == other.colour && self.vertex == other.vertex; +inline bool operator<( const PointVertex& self, const PointVertex& other ){ + if ( self.vertex != other.vertex ) { + return self.vertex < other.vertex; + } + if ( self.colour != other.colour ) { + return self.colour < other.colour; + } + return false; } -inline bool operator!=(const PointVertex& self, const PointVertex& other) -{ - return !operator==(self, other); +inline bool operator==( const PointVertex& self, const PointVertex& other ){ + return self.colour == other.colour && self.vertex == other.vertex; +} + +inline bool operator!=( const PointVertex& self, const PointVertex& other ){ + return !operator==( self, other ); } /// \brief Standard vertex type for lit/textured meshes. struct ArbitraryMeshVertex { - TexCoord2f texcoord; - Normal3f normal; - Vertex3f vertex; - Normal3f tangent; - Normal3f bitangent; - - ArbitraryMeshVertex() : tangent(0, 0, 0), bitangent(0, 0, 0) - { - } - ArbitraryMeshVertex(Vertex3f _vertex, Normal3f _normal, TexCoord2f _texcoord) - : texcoord(_texcoord), normal(_normal), vertex(_vertex), tangent(0, 0, 0), bitangent(0, 0, 0) - { - } + TexCoord2f texcoord; + Normal3f normal; + Vertex3f vertex; + Normal3f tangent; + Normal3f bitangent; + + ArbitraryMeshVertex() : tangent( 0, 0, 0 ), bitangent( 0, 0, 0 ){ + } + ArbitraryMeshVertex( Vertex3f _vertex, Normal3f _normal, TexCoord2f _texcoord ) + : texcoord( _texcoord ), normal( _normal ), vertex( _vertex ), tangent( 0, 0, 0 ), bitangent( 0, 0, 0 ){ + } }; -inline bool operator<(const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other) -{ - if(self.texcoord != other.texcoord) - { - return self.texcoord < other.texcoord; - } - if(self.normal != other.normal) - { - return self.normal < other.normal; - } - if(self.vertex != other.vertex) - { - return self.vertex < other.vertex; - } - return false; -} - -inline bool operator==(const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other) -{ - return self.texcoord == other.texcoord && self.normal == other.normal && self.vertex == other.vertex; +inline bool operator<( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ + if ( self.texcoord != other.texcoord ) { + return self.texcoord < other.texcoord; + } + if ( self.normal != other.normal ) { + return self.normal < other.normal; + } + if ( self.vertex != other.vertex ) { + return self.vertex < other.vertex; + } + return false; } -inline bool operator!=(const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other) -{ - return !operator==(self, other); +inline bool operator==( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ + return self.texcoord == other.texcoord && self.normal == other.normal && self.vertex == other.vertex; } -const float c_quantise_vertex = 1.f / static_cast(1 << 3); +inline bool operator!=( const ArbitraryMeshVertex& self, const ArbitraryMeshVertex& other ){ + return !operator==( self, other ); +} + +const float c_quantise_vertex = 1.f / static_cast( 1 << 3 ); /// \brief Returns \p v with vertex quantised to a fixed precision. -inline PointVertex pointvertex_quantised(const PointVertex& v) -{ - return PointVertex(vertex3f_quantised(v.vertex, c_quantise_vertex), v.colour); +inline PointVertex pointvertex_quantised( const PointVertex& v ){ + return PointVertex( vertex3f_quantised( v.vertex, c_quantise_vertex ), v.colour ); } -const float c_quantise_texcoord = 1.f / static_cast(1 << 8); +const float c_quantise_texcoord = 1.f / static_cast( 1 << 8 ); /// \brief Returns \p v with vertex, normal and texcoord quantised to a fixed precision. -inline ArbitraryMeshVertex arbitrarymeshvertex_quantised(const ArbitraryMeshVertex& v) -{ - return ArbitraryMeshVertex(vertex3f_quantised(v.vertex, c_quantise_vertex), normal3f_quantised(v.normal), texcoord2f_quantised(v.texcoord, c_quantise_texcoord)); +inline ArbitraryMeshVertex arbitrarymeshvertex_quantised( const ArbitraryMeshVertex& v ){ + return ArbitraryMeshVertex( vertex3f_quantised( v.vertex, c_quantise_vertex ), normal3f_quantised( v.normal ), texcoord2f_quantised( v.texcoord, c_quantise_texcoord ) ); } /// \brief Sets up the OpenGL colour and vertex arrays for \p array. -inline void pointvertex_gl_array(const PointVertex* array) -{ - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PointVertex), &array->colour); - glVertexPointer(3, GL_FLOAT, sizeof(PointVertex), &array->vertex); +inline void pointvertex_gl_array( const PointVertex* array ){ + glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &array->colour ); + glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &array->vertex ); } class RenderablePointArray : public OpenGLRenderable { - const Array& m_array; - const GLenum m_mode; +const Array& m_array; +const GLenum m_mode; public: - RenderablePointArray(const Array& array, GLenum mode) - : m_array(array), m_mode(mode) - { - } - void render(RenderStateFlags state) const - { +RenderablePointArray( const Array& array, GLenum mode ) + : m_array( array ), m_mode( mode ){ +} +void render( RenderStateFlags state ) const { #define NV_DRIVER_BUG 1 #if NV_DRIVER_BUG - glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0); - glVertexPointer(3, GL_FLOAT, 0, 0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 0); + glColorPointer( 4, GL_UNSIGNED_BYTE, 0, 0 ); + glVertexPointer( 3, GL_FLOAT, 0, 0 ); + glDrawArrays( GL_TRIANGLE_FAN, 0, 0 ); #endif - pointvertex_gl_array(m_array.data()); - glDrawArrays(m_mode, 0, GLsizei(m_array.size())); - } + pointvertex_gl_array( m_array.data() ); + glDrawArrays( m_mode, 0, GLsizei( m_array.size() ) ); +} }; class RenderablePointVector : public OpenGLRenderable { - std::vector m_vector; - const GLenum m_mode; +std::vector m_vector; +const GLenum m_mode; public: - RenderablePointVector(GLenum mode) - : m_mode(mode) - { - } - - void render(RenderStateFlags state) const - { - pointvertex_gl_array(&m_vector.front()); - glDrawArrays(m_mode, 0, GLsizei(m_vector.size())); - } - - std::size_t size() const - { - return m_vector.size(); - } - bool empty() const - { - return m_vector.empty(); - } - void clear() - { - m_vector.clear(); - } - void reserve(std::size_t size) - { - m_vector.reserve(size); - } - void push_back(const PointVertex& point) - { - m_vector.push_back(point); - } +RenderablePointVector( GLenum mode ) + : m_mode( mode ){ +} + +void render( RenderStateFlags state ) const { + pointvertex_gl_array( &m_vector.front() ); + glDrawArrays( m_mode, 0, GLsizei( m_vector.size() ) ); +} + +std::size_t size() const { + return m_vector.size(); +} +bool empty() const { + return m_vector.empty(); +} +void clear(){ + m_vector.clear(); +} +void reserve( std::size_t size ){ + m_vector.reserve( size ); +} +void push_back( const PointVertex& point ){ + m_vector.push_back( point ); +} }; class RenderableVertexBuffer : public OpenGLRenderable { - const GLenum m_mode; - const VertexBuffer& m_vertices; +const GLenum m_mode; +const VertexBuffer& m_vertices; public: - RenderableVertexBuffer(GLenum mode, const VertexBuffer& vertices) - : m_mode(mode), m_vertices(vertices) - { - } - - void render(RenderStateFlags state) const - { - pointvertex_gl_array(m_vertices.data()); - glDrawArrays(m_mode, 0, m_vertices.size()); - } +RenderableVertexBuffer( GLenum mode, const VertexBuffer& vertices ) + : m_mode( mode ), m_vertices( vertices ){ +} + +void render( RenderStateFlags state ) const { + pointvertex_gl_array( m_vertices.data() ); + glDrawArrays( m_mode, 0, m_vertices.size() ); +} }; class RenderableIndexBuffer : public OpenGLRenderable { - const GLenum m_mode; - const IndexBuffer& m_indices; - const VertexBuffer& m_vertices; +const GLenum m_mode; +const IndexBuffer& m_indices; +const VertexBuffer& m_vertices; public: - RenderableIndexBuffer(GLenum mode, const IndexBuffer& indices, const VertexBuffer& vertices) - : m_mode(mode), m_indices(indices), m_vertices(vertices) - { - } +RenderableIndexBuffer( GLenum mode, const IndexBuffer& indices, const VertexBuffer& vertices ) + : m_mode( mode ), m_indices( indices ), m_vertices( vertices ){ +} - void render(RenderStateFlags state) const - { +void render( RenderStateFlags state ) const { #if 1 - pointvertex_gl_array(m_vertices.data()); - glDrawElements(m_mode, GLsizei(m_indices.size()), RenderIndexTypeID, m_indices.data()); + pointvertex_gl_array( m_vertices.data() ); + glDrawElements( m_mode, GLsizei( m_indices.size() ), RenderIndexTypeID, m_indices.data() ); #else - glBegin(m_mode); - if(state & RENDER_COLOURARRAY != 0) - { - for(std::size_t i = 0; i < m_indices.size(); ++i) - { - glColor4ubv(&m_vertices[m_indices[i]].colour.r); - glVertex3fv(&m_vertices[m_indices[i]].vertex.x); - } - } - else - { - for(std::size_t i = 0; i < m_indices.size(); ++i) - { - glVertex3fv(&m_vertices[m_indices[i]].vertex.x); - } - } - glEnd(); + glBegin( m_mode ); + if ( state & RENDER_COLOURARRAY != 0 ) { + for ( std::size_t i = 0; i < m_indices.size(); ++i ) + { + glColor4ubv( &m_vertices[m_indices[i]].colour.r ); + glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); + } + } + else + { + for ( std::size_t i = 0; i < m_indices.size(); ++i ) + { + glVertex3fv( &m_vertices[m_indices[i]].vertex.x ); + } + } + glEnd(); #endif - } +} }; class RemapXYZ { public: - static void set(Vertex3f& vertex, float x, float y, float z) - { - vertex.x() = x; - vertex.y() = y; - vertex.z() = z; - } +static void set( Vertex3f& vertex, float x, float y, float z ){ + vertex.x() = x; + vertex.y() = y; + vertex.z() = z; +} }; class RemapYZX { public: - static void set(Vertex3f& vertex, float x, float y, float z) - { - vertex.x() = z; - vertex.y() = x; - vertex.z() = y; - } +static void set( Vertex3f& vertex, float x, float y, float z ){ + vertex.x() = z; + vertex.y() = x; + vertex.z() = y; +} }; class RemapZXY { public: - static void set(Vertex3f& vertex, float x, float y, float z) - { - vertex.x() = y; - vertex.y() = z; - vertex.z() = x; - } +static void set( Vertex3f& vertex, float x, float y, float z ){ + vertex.x() = y; + vertex.y() = z; + vertex.z() = x; +} }; template -inline void draw_circle(const std::size_t segments, const float radius, PointVertex* vertices, remap_policy remap) -{ - const double increment = c_pi / double(segments << 2); +inline void draw_circle( const std::size_t segments, const float radius, PointVertex* vertices, remap_policy remap ){ + const double increment = c_pi / double(segments << 2); - std::size_t count = 0; - float x = radius; - float y = 0; - while(count < segments) - { - PointVertex* i = vertices + count; - PointVertex* j = vertices + ((segments << 1) - (count + 1)); + std::size_t count = 0; + float x = radius; + float y = 0; + while ( count < segments ) + { + PointVertex* i = vertices + count; + PointVertex* j = vertices + ( ( segments << 1 ) - ( count + 1 ) ); - PointVertex* k = i + (segments << 1); - PointVertex* l = j + (segments << 1); + PointVertex* k = i + ( segments << 1 ); + PointVertex* l = j + ( segments << 1 ); - PointVertex* m = i + (segments << 2); - PointVertex* n = j + (segments << 2); - PointVertex* o = k + (segments << 2); - PointVertex* p = l + (segments << 2); + PointVertex* m = i + ( segments << 2 ); + PointVertex* n = j + ( segments << 2 ); + PointVertex* o = k + ( segments << 2 ); + PointVertex* p = l + ( segments << 2 ); - remap_policy::set(i->vertex, x,-y, 0); - remap_policy::set(k->vertex,-y,-x, 0); - remap_policy::set(m->vertex,-x, y, 0); - remap_policy::set(o->vertex, y, x, 0); + remap_policy::set( i->vertex, x,-y, 0 ); + remap_policy::set( k->vertex,-y,-x, 0 ); + remap_policy::set( m->vertex,-x, y, 0 ); + remap_policy::set( o->vertex, y, x, 0 ); - ++count; + ++count; - { - const double theta = increment * count; - x = static_cast(radius * cos(theta)); - y = static_cast(radius * sin(theta)); - } + { + const double theta = increment * count; + x = static_cast( radius * cos( theta ) ); + y = static_cast( radius * sin( theta ) ); + } - remap_policy::set(j->vertex, y,-x, 0); - remap_policy::set(l->vertex,-x,-y, 0); - remap_policy::set(n->vertex,-y, x, 0); - remap_policy::set(p->vertex, x, y, 0); - } + remap_policy::set( j->vertex, y,-x, 0 ); + remap_policy::set( l->vertex,-x,-y, 0 ); + remap_policy::set( n->vertex,-y, x, 0 ); + remap_policy::set( p->vertex, x, y, 0 ); + } } #if 0 class PointVertexArrayIterator { - PointVertex* m_point; +PointVertex* m_point; public: - PointVertexArrayIterator(PointVertex* point) - : m_point(point) - { - } - PointVertexArrayIterator& operator++() - { - ++m_point; - return *this; - } - PointVertexArrayIterator operator++(int) - { - PointVertexArrayIterator tmp(*this); - ++m_point; - return tmp; - } - Vertex3f& operator*() - { - return m_point.vertex; - } - Vertex3f* operator->() - { - return &(operator*()); - } +PointVertexArrayIterator( PointVertex* point ) + : m_point( point ){ +} +PointVertexArrayIterator& operator++(){ + ++m_point; + return *this; +} +PointVertexArrayIterator operator++( int ){ + PointVertexArrayIterator tmp( *this ); + ++m_point; + return tmp; +} +Vertex3f& operator*(){ + return m_point.vertex; +} +Vertex3f* operator->(){ + return &( operator*() ); } - -template 0.000001f) - { - s.x() = -cross.y() / cross.x(); - } - - if(fabs(cross.x()) > 0.000001f) - { - t.x() = -cross.z() / cross.x(); - } - } - - { - Vector3 cross( - vector3_cross( - vector3_subtracted( - Vector3(b.vertex.y(), b.texcoord.s(), b.texcoord.t()), - Vector3(a.vertex.y(), a.texcoord.s(), a.texcoord.t()) - ), - vector3_subtracted( - Vector3(c.vertex.y(), c.texcoord.s(), c.texcoord.t()), - Vector3(a.vertex.y(), a.texcoord.s(), a.texcoord.t()) - ) - ) - ); - - if(fabs(cross.x()) > 0.000001f) - { - s.y() = -cross.y() / cross.x(); - } - - if(fabs(cross.x()) > 0.000001f) - { - t.y() = -cross.z() / cross.x(); - } - } - - { - Vector3 cross( - vector3_cross( - vector3_subtracted( - Vector3(b.vertex.z(), b.texcoord.s(), b.texcoord.t()), - Vector3(a.vertex.z(), a.texcoord.s(), a.texcoord.t()) - ), - vector3_subtracted( - Vector3(c.vertex.z(), c.texcoord.s(), c.texcoord.t()), - Vector3(a.vertex.z(), a.texcoord.s(), a.texcoord.t()) - ) - ) - ); - - if(fabs(cross.x()) > 0.000001f) - { - s.z() = -cross.y() / cross.x(); - } - - if(fabs(cross.x()) > 0.000001f) - { - t.z() = -cross.z() / cross.x(); - } - } -} - -inline void ArbitraryMeshTriangle_sumTangents(ArbitraryMeshVertex& a, ArbitraryMeshVertex& b, ArbitraryMeshVertex& c) -{ - Vector3 s, t; - - ArbitraryMeshTriangle_calcTangents(a, b, c, s, t); - - reinterpret_cast(a.tangent) += s; - reinterpret_cast(b.tangent) += s; - reinterpret_cast(c.tangent) += s; - - reinterpret_cast(a.bitangent) += t; - reinterpret_cast(b.bitangent) += t; - reinterpret_cast(c.bitangent) += t; +inline void ArbitraryMeshTriangle_calcTangents( const ArbitraryMeshVertex& a, const ArbitraryMeshVertex& b, const ArbitraryMeshVertex& c, Vector3& s, Vector3& t ){ + s = Vector3( 0, 0, 0 ); + t = Vector3( 0, 0, 0 ); + { + Vector3 cross( + vector3_cross( + vector3_subtracted( + Vector3( b.vertex.x(), b.texcoord.s(), b.texcoord.t() ), + Vector3( a.vertex.x(), a.texcoord.s(), a.texcoord.t() ) + ), + vector3_subtracted( + Vector3( c.vertex.x(), c.texcoord.s(), c.texcoord.t() ), + Vector3( a.vertex.x(), a.texcoord.s(), a.texcoord.t() ) + ) + ) + ); + + if ( fabs( cross.x() ) > 0.000001f ) { + s.x() = -cross.y() / cross.x(); + } + + if ( fabs( cross.x() ) > 0.000001f ) { + t.x() = -cross.z() / cross.x(); + } + } + + { + Vector3 cross( + vector3_cross( + vector3_subtracted( + Vector3( b.vertex.y(), b.texcoord.s(), b.texcoord.t() ), + Vector3( a.vertex.y(), a.texcoord.s(), a.texcoord.t() ) + ), + vector3_subtracted( + Vector3( c.vertex.y(), c.texcoord.s(), c.texcoord.t() ), + Vector3( a.vertex.y(), a.texcoord.s(), a.texcoord.t() ) + ) + ) + ); + + if ( fabs( cross.x() ) > 0.000001f ) { + s.y() = -cross.y() / cross.x(); + } + + if ( fabs( cross.x() ) > 0.000001f ) { + t.y() = -cross.z() / cross.x(); + } + } + + { + Vector3 cross( + vector3_cross( + vector3_subtracted( + Vector3( b.vertex.z(), b.texcoord.s(), b.texcoord.t() ), + Vector3( a.vertex.z(), a.texcoord.s(), a.texcoord.t() ) + ), + vector3_subtracted( + Vector3( c.vertex.z(), c.texcoord.s(), c.texcoord.t() ), + Vector3( a.vertex.z(), a.texcoord.s(), a.texcoord.t() ) + ) + ) + ); + + if ( fabs( cross.x() ) > 0.000001f ) { + s.z() = -cross.y() / cross.x(); + } + + if ( fabs( cross.x() ) > 0.000001f ) { + t.z() = -cross.z() / cross.x(); + } + } +} + +inline void ArbitraryMeshTriangle_sumTangents( ArbitraryMeshVertex& a, ArbitraryMeshVertex& b, ArbitraryMeshVertex& c ){ + Vector3 s, t; + + ArbitraryMeshTriangle_calcTangents( a, b, c, s, t ); + + reinterpret_cast( a.tangent ) += s; + reinterpret_cast( b.tangent ) += s; + reinterpret_cast( c.tangent ) += s; + + reinterpret_cast( a.bitangent ) += t; + reinterpret_cast( b.bitangent ) += t; + reinterpret_cast( c.bitangent ) += t; }