vertexBufferNode.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "vertexBufferNode.h"
00025 #include "vertexBufferLeaf.h"
00026 #include "vertexBufferState.h"
00027 #include "vertexData.h"
00028 #include <set>
00029
00030
00031 using namespace std;
00032
00033 namespace mesh
00034 {
00035
00036 inline static bool _subdivide( const Index length, const size_t depth )
00037 {
00038 return ( length / 2 > LEAF_SIZE ) || ( depth < 3 && length > 1 );
00039 }
00040
00041
00042 void VertexBufferNode::setupTree( VertexData& data, const Index start,
00043 const Index length, const Axis axis,
00044 const size_t depth,
00045 VertexBufferData& globalData )
00046 {
00047 #ifndef NDEBUG
00048 MESHINFO << "Entering VertexBufferNode::setupTree"
00049 << "( " << start << ", " << length << ", " << axis << ", "
00050 << depth << " )." << endl;
00051 #endif
00052
00053 data.sort( start, length, axis );
00054 const Index median = start + ( length / 2 );
00055
00056
00057 const Index leftLength = length / 2;
00058 const bool subdivideLeft = _subdivide( leftLength, depth );
00059
00060 if( subdivideLeft )
00061 _left = new VertexBufferNode;
00062 else
00063 _left = new VertexBufferLeaf( globalData );
00064
00065
00066 const Index rightLength = ( length + 1 ) / 2;
00067 const bool subdivideRight = _subdivide( rightLength, depth );
00068
00069 if( subdivideRight )
00070 _right = new VertexBufferNode;
00071 else
00072 _right = new VertexBufferLeaf( globalData );
00073
00074
00075 const Axis newAxisLeft = subdivideLeft ?
00076 data.getLongestAxis( start , leftLength ) : AXIS_X;
00077
00078 const Axis newAxisRight = subdivideRight ?
00079 data.getLongestAxis( median, rightLength ) : AXIS_X;
00080
00081 static_cast< VertexBufferNode* >
00082 ( _left )->setupTree( data, start, leftLength, newAxisLeft, depth+1,
00083 globalData );
00084 static_cast< VertexBufferNode* >
00085 ( _right )->setupTree( data, median, rightLength, newAxisRight, depth+1,
00086 globalData );
00087
00088 }
00089
00090
00091
00092 const BoundingSphere& VertexBufferNode::updateBoundingSphere()
00093 {
00094
00095 const BoundingSphere& sphere1 = _left->updateBoundingSphere();
00096 const BoundingSphere& sphere2 = _right->updateBoundingSphere();
00097
00098
00099 const Vertex center1( sphere1.array );
00100 const Vertex center2( sphere2.array );
00101 Vertex c1ToC2 = center2 - center1;
00102 c1ToC2.normalize();
00103
00104 const Vertex outer1 = center1 - c1ToC2 * sphere1.w();
00105 const Vertex outer2 = center2 + c1ToC2 * sphere2.w();
00106
00107 Vertex vertexBoundingSphere = Vertex( outer1 + outer2 ) * 0.5f;
00108 _boundingSphere.x() = vertexBoundingSphere.x();
00109 _boundingSphere.y() = vertexBoundingSphere.y();
00110 _boundingSphere.z() = vertexBoundingSphere.z();
00111 _boundingSphere.w() = Vertex( outer1 - outer2 ).length() * 0.5f;
00112
00113 #ifndef NDEBUG
00114 MESHINFO << "Exiting VertexBufferNode::updateBoundingSphere"
00115 << "( " << _boundingSphere << " )."
00116 << endl;
00117 #endif
00118
00119 return _boundingSphere;
00120 }
00121
00122
00123
00124 void VertexBufferNode::updateRange()
00125 {
00126
00127 static_cast< VertexBufferNode* >( _left )->updateRange();
00128 static_cast< VertexBufferNode* >( _right )->updateRange();
00129
00130
00131 _range[0] = min( _left->getRange()[0], _right->getRange()[0] );
00132 _range[1] = max( _left->getRange()[1], _right->getRange()[1] );
00133
00134 #ifndef NDEBUG
00135 MESHINFO << "Exiting VertexBufferNode::updateRange"
00136 << "( " << _range[0] << ", " << _range[1] << " )." << endl;
00137 #endif
00138 }
00139
00140
00141
00142 void VertexBufferNode::render( VertexBufferState& state ) const
00143 {
00144 _left->render( state );
00145 _right->render( state );
00146 }
00147
00148
00149
00150 void VertexBufferNode::fromMemory( char** addr, VertexBufferData& globalData )
00151 {
00152
00153 size_t nodeType;
00154 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
00155 if( nodeType != NODE_TYPE )
00156 throw MeshException( "Error reading binary file. Expected a regular "
00157 "node, but found something else instead." );
00158 VertexBufferBase::fromMemory( addr, globalData );
00159
00160
00161 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
00162 if( nodeType != NODE_TYPE && nodeType != LEAF_TYPE )
00163 throw MeshException( "Error reading binary file. Expected either a "
00164 "regular or a leaf node, but found neither." );
00165 *addr -= sizeof( size_t );
00166 if( nodeType == NODE_TYPE )
00167 _left = new VertexBufferNode;
00168 else
00169 _left = new VertexBufferLeaf( globalData );
00170 static_cast< VertexBufferNode* >( _left )->fromMemory( addr, globalData );
00171
00172
00173 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
00174 if( nodeType != NODE_TYPE && nodeType != LEAF_TYPE )
00175 throw MeshException( "Error reading binary file. Expected either a "
00176 "regular or a leaf node, but found neither." );
00177 *addr -= sizeof( size_t );
00178 if( nodeType == NODE_TYPE )
00179 _right = new VertexBufferNode;
00180 else
00181 _right = new VertexBufferLeaf( globalData );
00182 static_cast< VertexBufferNode* >( _right )->fromMemory( addr, globalData );
00183 }
00184
00185
00186
00187 void VertexBufferNode::toStream( std::ostream& os )
00188 {
00189 size_t nodeType = NODE_TYPE;
00190 os.write( reinterpret_cast< char* >( &nodeType ), sizeof( size_t ) );
00191 VertexBufferBase::toStream( os );
00192 static_cast< VertexBufferNode* >( _left )->toStream( os );
00193 static_cast< VertexBufferNode* >( _right )->toStream( os );
00194 }
00195
00196
00197
00198 VertexBufferNode::~VertexBufferNode()
00199 {
00200 delete static_cast< VertexBufferNode* >( _left );
00201 delete static_cast< VertexBufferNode* >( _right );
00202 }
00203 }