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 "vertexBufferLeaf.h"
00025 #include "vertexBufferData.h"
00026 #include "vertexBufferState.h"
00027 #include "vertexData.h"
00028 #include <map>
00029
00030 using namespace std;
00031
00032 namespace mesh
00033 {
00034
00035
00036 void VertexBufferLeaf::setupTree( VertexData& data, const Index start,
00037 const Index length, const Axis axis,
00038 const size_t depth,
00039 VertexBufferData& globalData )
00040 {
00041 #ifndef NDEBUG
00042 MESHINFO << "Entering VertexBufferLeaf::setupTree"
00043 << "( " << start << ", " << length << ", " << axis << ", "
00044 << depth << " )." << endl;
00045 #endif
00046
00047 data.sort( start, length, axis );
00048 _vertexStart = globalData.vertices.size();
00049 _vertexLength = 0;
00050 _indexStart = globalData.indices.size();
00051 _indexLength = 0;
00052
00053 const bool hasColors = ( data.colors.size() > 0 );
00054
00055
00056 map< Index, ShortIndex > newIndex;
00057
00058 for( Index t = 0; t < length; ++t )
00059 {
00060 for( Index v = 0; v < 3; ++v )
00061 {
00062 Index i = data.triangles[start + t][v];
00063 if( newIndex.find( i ) == newIndex.end() )
00064 {
00065 newIndex[i] = _vertexLength++;
00066
00067 MESHASSERT( _vertexLength );
00068 globalData.vertices.push_back( data.vertices[i] );
00069 if( hasColors )
00070 globalData.colors.push_back( data.colors[i] );
00071 globalData.normals.push_back( data.normals[i] );
00072 }
00073 globalData.indices.push_back( newIndex[i] );
00074 ++_indexLength;
00075 }
00076 }
00077
00078 #ifndef NDEBUG
00079 MESHINFO << "Exiting VertexBufferLeaf::setupTree"
00080 << "( " << _indexStart << ", " << _indexLength << "; "
00081 << _vertexStart << ", " << _vertexLength << " )." << endl;
00082 #else
00083 MESHINFO << "Leaf " << this << " contains " << _vertexLength << " vertices"
00084 << " and " << _indexLength / 3 << " triangles." << endl;
00085 #endif
00086 }
00087
00088
00089
00090 const BoundingSphere& VertexBufferLeaf::updateBoundingSphere()
00091 {
00092
00093
00094
00095
00096
00097
00098
00099
00100 BoundingBox boundingBox;
00101 boundingBox[0] =
00102 _globalData.vertices[ _vertexStart + _globalData.indices[_indexStart] ];
00103 boundingBox[1] =
00104 _globalData.vertices[ _vertexStart + _globalData.indices[_indexStart] ];
00105
00106 for( Index offset = 1; offset < _indexLength; ++offset )
00107 {
00108 const Vertex& vertex =
00109 _globalData.vertices[ _vertexStart +
00110 _globalData.indices[_indexStart + offset] ];
00111
00112 boundingBox[0][0] = min( boundingBox[0][0], vertex[0] );
00113 boundingBox[1][0] = max( boundingBox[1][0], vertex[0] );
00114 boundingBox[0][1] = min( boundingBox[0][1], vertex[1] );
00115 boundingBox[1][1] = max( boundingBox[1][1], vertex[1] );
00116 boundingBox[0][2] = min( boundingBox[0][2], vertex[2] );
00117 boundingBox[1][2] = max( boundingBox[1][2], vertex[2] );
00118 }
00119
00120
00121 _boundingSphere.x() =
00122 ( boundingBox[0].x() + boundingBox[1].x() ) * 0.5f;
00123 _boundingSphere.y() =
00124 ( boundingBox[0].y() + boundingBox[1].y() ) * 0.5f;
00125 _boundingSphere.z() =
00126 ( boundingBox[0].z() + boundingBox[1].z() ) * 0.5f;
00127
00128 _boundingSphere.w() = EQ_MAX( boundingBox[1].x() - boundingBox[0].x(),
00129 boundingBox[1].y() - boundingBox[0].y() );
00130 _boundingSphere.w() = EQ_MAX( boundingBox[1].z() - boundingBox[0].z(),
00131 _boundingSphere.w() );
00132 _boundingSphere.w() *= .5f;
00133
00134 float radius = _boundingSphere.w();
00135 float radiusSquared = radius * radius;
00136 Vertex center( _boundingSphere.array );
00137
00138
00139 for( Index offset = 0; offset < _indexLength; ++offset )
00140 {
00141 const Vertex& vertex =
00142 _globalData.vertices[ _vertexStart +
00143 _globalData.indices[_indexStart + offset] ];
00144
00145 const Vertex centerToPoint = vertex - center;
00146 const float distanceSquared = centerToPoint.squared_length();
00147 if( distanceSquared <= radiusSquared )
00148 continue;
00149
00150
00151 const float distance = sqrtf( distanceSquared );
00152 const float delta = distance - radius;
00153
00154 radius = ( radius + distance ) * .5f;
00155 radiusSquared = radius * radius;
00156 const Vertex normdelta = normalize( centerToPoint ) * ( 0.5f * delta );
00157
00158 center += normdelta;
00159
00160 EQASSERTINFO( Vertex( vertex-center ).squared_length() <=
00161 ( radiusSquared + 2.f* numeric_limits<float>::epsilon( )),
00162 vertex << " c " << center << " r " << radius << " ("
00163 << Vertex( vertex-center ).length() << ")" );
00164 }
00165
00166
00167 _boundingSphere.x() = center.x();
00168 _boundingSphere.y() = center.y();
00169 _boundingSphere.z() = center.z();
00170 _boundingSphere.w() = radius;
00171
00172 #ifndef NDEBUG
00173 MESHINFO << "Exiting VertexBufferLeaf::updateBoundingSphere"
00174 << "( " << _boundingSphere << " )." << endl;
00175 #endif
00176
00177 return _boundingSphere;
00178 }
00179
00180
00181
00182 void VertexBufferLeaf::updateRange()
00183 {
00184 _range[0] = 1.0f * _indexStart / _globalData.indices.size();
00185 _range[1] = _range[0] + 1.0f * _indexLength / _globalData.indices.size();
00186
00187 #ifndef NDEBUG
00188 MESHINFO << "Exiting VertexBufferLeaf::updateRange"
00189 << "( " << _range[0] << ", " << _range[1] << " )." << endl;
00190 #endif
00191 }
00192
00193 #define glewGetContext state.glewGetContext
00194
00195
00196 void VertexBufferLeaf::setupRendering( VertexBufferState& state,
00197 GLuint* data ) const
00198 {
00199 switch( state.getRenderMode() )
00200 {
00201 case RENDER_MODE_IMMEDIATE:
00202 break;
00203
00204 case RENDER_MODE_BUFFER_OBJECT:
00205 {
00206 const char* charThis = reinterpret_cast< const char* >( this );
00207
00208 if( data[VERTEX_OBJECT] == state.INVALID )
00209 data[VERTEX_OBJECT] = state.newBufferObject( charThis + 0 );
00210 glBindBuffer( GL_ARRAY_BUFFER, data[VERTEX_OBJECT] );
00211 glBufferData( GL_ARRAY_BUFFER, _vertexLength * sizeof( Vertex ),
00212 &_globalData.vertices[_vertexStart], GL_STATIC_DRAW );
00213
00214 if( data[NORMAL_OBJECT] == state.INVALID )
00215 data[NORMAL_OBJECT] = state.newBufferObject( charThis + 1 );
00216 glBindBuffer( GL_ARRAY_BUFFER, data[NORMAL_OBJECT] );
00217 glBufferData( GL_ARRAY_BUFFER, _vertexLength * sizeof( Normal ),
00218 &_globalData.normals[_vertexStart], GL_STATIC_DRAW );
00219
00220 if( data[COLOR_OBJECT] == state.INVALID )
00221 data[COLOR_OBJECT] = state.newBufferObject( charThis + 2 );
00222 if( state.useColors() )
00223 {
00224 glBindBuffer( GL_ARRAY_BUFFER, data[COLOR_OBJECT] );
00225 glBufferData( GL_ARRAY_BUFFER, _vertexLength * sizeof( Color ),
00226 &_globalData.colors[_vertexStart], GL_STATIC_DRAW );
00227 }
00228
00229 if( data[INDEX_OBJECT] == state.INVALID )
00230 data[INDEX_OBJECT] = state.newBufferObject( charThis + 3 );
00231 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, data[INDEX_OBJECT] );
00232 glBufferData( GL_ELEMENT_ARRAY_BUFFER,
00233 _indexLength * sizeof( ShortIndex ),
00234 &_globalData.indices[_indexStart], GL_STATIC_DRAW );
00235
00236 break;
00237 }
00238 case RENDER_MODE_DISPLAY_LIST:
00239 default:
00240 {
00241 if( data[0] == state.INVALID )
00242 {
00243 char* key = (char*)( this );
00244 if( state.useColors( ))
00245 ++key;
00246 data[0] = state.newDisplayList( key );
00247 }
00248 glNewList( data[0], GL_COMPILE );
00249 renderImmediate( state );
00250 glEndList();
00251 break;
00252 }
00253 }
00254 }
00255
00256
00257
00258 void VertexBufferLeaf::render( VertexBufferState& state ) const
00259 {
00260 switch( state.getRenderMode() )
00261 {
00262 case RENDER_MODE_IMMEDIATE:
00263 renderImmediate( state );
00264 return;
00265 case RENDER_MODE_BUFFER_OBJECT:
00266 renderBufferObject( state );
00267 return;
00268 case RENDER_MODE_DISPLAY_LIST:
00269 default:
00270 renderDisplayList( state );
00271 return;
00272 }
00273 }
00274
00275
00276
00277 void VertexBufferLeaf::renderBufferObject( VertexBufferState& state ) const
00278 {
00279 GLuint buffers[4];
00280 for( int i = 0; i < 4; ++i )
00281 buffers[i] =
00282 state.getBufferObject( reinterpret_cast< const char* >(this) + i );
00283 if( buffers[VERTEX_OBJECT] == state.INVALID ||
00284 buffers[NORMAL_OBJECT] == state.INVALID ||
00285 buffers[COLOR_OBJECT] == state.INVALID ||
00286 buffers[INDEX_OBJECT] == state.INVALID )
00287
00288 setupRendering( state, buffers );
00289
00290 if( state.useColors() )
00291 {
00292 glBindBuffer( GL_ARRAY_BUFFER, buffers[COLOR_OBJECT] );
00293 glColorPointer( 4, GL_UNSIGNED_BYTE, 0, 0 );
00294 }
00295 glBindBuffer( GL_ARRAY_BUFFER, buffers[NORMAL_OBJECT] );
00296 glNormalPointer( GL_FLOAT, 0, 0 );
00297 glBindBuffer( GL_ARRAY_BUFFER, buffers[VERTEX_OBJECT] );
00298 glVertexPointer( 3, GL_FLOAT, 0, 0 );
00299 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers[INDEX_OBJECT] );
00300 glDrawElements( GL_TRIANGLES, _indexLength, GL_UNSIGNED_SHORT, 0 );
00301 }
00302
00303
00304
00305 inline
00306 void VertexBufferLeaf::renderDisplayList( VertexBufferState& state ) const
00307 {
00308 char* key = (char*)( this );
00309 if( state.useColors( ))
00310 ++key;
00311
00312 GLuint displayList = state.getDisplayList( key );
00313
00314 if( displayList == state.INVALID )
00315 setupRendering( state, &displayList );
00316
00317 glCallList( displayList );
00318 }
00319
00320
00321
00322 inline
00323 void VertexBufferLeaf::renderImmediate( VertexBufferState& state ) const
00324 {
00325 glBegin( GL_TRIANGLES );
00326 for( Index offset = 0; offset < _indexLength; ++offset )
00327 {
00328 const Index i =_vertexStart + _globalData.indices[_indexStart + offset];
00329 if( state.useColors() )
00330 glColor4ubv( &_globalData.colors[i][0] );
00331 glNormal3fv( &_globalData.normals[i][0] );
00332 glVertex3fv( &_globalData.vertices[i][0] );
00333 }
00334 glEnd();
00335
00336
00337
00338
00339
00340
00341
00342
00343 }
00344
00345
00346
00347 void VertexBufferLeaf::fromMemory( char** addr, VertexBufferData& globalData )
00348 {
00349 size_t nodeType;
00350 memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
00351 if( nodeType != LEAF_TYPE )
00352 throw MeshException( "Error reading binary file. Expected a leaf "
00353 "node, but found something else instead." );
00354 VertexBufferBase::fromMemory( addr, globalData );
00355 memRead( reinterpret_cast< char* >( &_vertexStart ), addr,
00356 sizeof( Index ) );
00357 memRead( reinterpret_cast< char* >( &_vertexLength ), addr,
00358 sizeof( ShortIndex ) );
00359 memRead( reinterpret_cast< char* >( &_indexStart ), addr,
00360 sizeof( Index ) );
00361 memRead( reinterpret_cast< char* >( &_indexLength ), addr,
00362 sizeof( Index ) );
00363 }
00364
00365
00366
00367 void VertexBufferLeaf::toStream( std::ostream& os )
00368 {
00369 size_t nodeType = LEAF_TYPE;
00370 os.write( reinterpret_cast< char* >( &nodeType ), sizeof( size_t ) );
00371 VertexBufferBase::toStream( os );
00372 os.write( reinterpret_cast< char* >( &_vertexStart ), sizeof( Index ) );
00373 os.write( reinterpret_cast< char* >( &_vertexLength ), sizeof( ShortIndex ) );
00374 os.write( reinterpret_cast< char* >( &_indexStart ), sizeof( Index ) );
00375 os.write( reinterpret_cast< char* >( &_indexLength ), sizeof( Index ) );
00376 }
00377
00378 }