31 #include "vertexBufferLeaf.h"
32 #include "vertexBufferData.h"
33 #include "vertexBufferState.h"
34 #include "vertexData.h"
41 void VertexBufferLeaf::setupTree( VertexData& data,
const Index start,
42 const Index length,
const Axis axis,
44 VertexBufferData& globalData )
46 data.sort( start, length, axis );
47 _vertexStart = globalData.vertices.size();
49 _indexStart = globalData.indices.size();
52 const bool hasColors = !data.colors.empty();
55 std::map< Index, ShortIndex > newIndex;
57 for( Index t = 0; t < length; ++t )
59 for( Index v = 0; v < 3; ++v )
61 Index i = data.triangles[start + t][v];
62 if( newIndex.find( i ) == newIndex.end() )
64 newIndex[i] = _vertexLength++;
66 MESHASSERT( _vertexLength );
67 globalData.vertices.push_back( data.vertices[i] );
69 globalData.colors.push_back( data.colors[i] );
70 globalData.normals.push_back( data.normals[i] );
72 globalData.indices.push_back( newIndex[i] );
78 MESHINFO <<
"setupTree" <<
"( " << _indexStart <<
", " << _indexLength
79 <<
"; start " << _vertexStart <<
", " << _vertexLength
80 <<
" vertices)." << std::endl;
86 const BoundingSphere& VertexBufferLeaf::updateBoundingSphere()
96 _boundingBox[0] = _globalData.vertices[ _vertexStart +
97 _globalData.indices[_indexStart] ];
98 _boundingBox[1] = _globalData.vertices[ _vertexStart +
99 _globalData.indices[_indexStart] ];
101 for( Index i = 1 + _indexStart; i < _indexStart + _indexLength; ++i )
103 const Vertex& vertex = _globalData.vertices[ _vertexStart +
104 _globalData.indices[ i ] ];
105 _boundingBox[0][0] = std::min( _boundingBox[0][0], vertex[0] );
106 _boundingBox[1][0] = std::max( _boundingBox[1][0], vertex[0] );
107 _boundingBox[0][1] = std::min( _boundingBox[0][1], vertex[1] );
108 _boundingBox[1][1] = std::max( _boundingBox[1][1], vertex[1] );
109 _boundingBox[0][2] = std::min( _boundingBox[0][2], vertex[2] );
110 _boundingBox[1][2] = std::max( _boundingBox[1][2], vertex[2] );
114 _boundingSphere.x() = ( _boundingBox[0].x() + _boundingBox[1].x() ) * 0.5f;
115 _boundingSphere.y() = ( _boundingBox[0].y() + _boundingBox[1].y() ) * 0.5f;
116 _boundingSphere.z() = ( _boundingBox[0].z() + _boundingBox[1].z() ) * 0.5f;
118 _boundingSphere.w() = LB_MAX( _boundingBox[1].x() - _boundingBox[0].x(),
119 _boundingBox[1].y() - _boundingBox[0].y() );
120 _boundingSphere.w() = LB_MAX( _boundingBox[1].z() - _boundingBox[0].z(),
121 _boundingSphere.w() );
122 _boundingSphere.w() *= .5f;
124 float radius = _boundingSphere.w();
125 float radiusSquared = radius * radius;
126 Vertex center( _boundingSphere.array );
129 for( Index offset = 0; offset < _indexLength; ++offset )
131 const Vertex& vertex =
132 _globalData.vertices[ _vertexStart +
133 _globalData.indices[_indexStart + offset] ];
135 const Vertex centerToPoint = vertex - center;
136 const float distanceSquared = centerToPoint.squared_length();
137 if( distanceSquared <= radiusSquared )
141 const float distance = sqrtf( distanceSquared );
142 const float delta = distance - radius;
144 radius = ( radius + distance ) * .5f;
145 radiusSquared = radius * radius;
146 const Vertex normdelta = normalize( centerToPoint ) * ( 0.5f * delta );
150 LBASSERTINFO( Vertex( vertex-center ).squared_length() <=
151 ( radiusSquared + 2.f * std::numeric_limits<float>::epsilon( )),
152 vertex <<
" c " << center <<
" r " << radius <<
" ("
153 << Vertex( vertex-center ).length() <<
")" );
158 for( Index offset = 0; offset < _indexLength; ++offset )
160 const Vertex& vertex =
161 _globalData.vertices[ _vertexStart +
162 _globalData.indices[_indexStart + offset] ];
164 const Vertex centerToPoint = vertex - center;
165 const float distanceSquared = centerToPoint.squared_length();
166 LBASSERTINFO( distanceSquared <=
167 ( radiusSquared + 2.f * std::numeric_limits<float>::epsilon( )),
168 vertex <<
" c " << center <<
" r " << radius <<
" ("
169 << Vertex( vertex-center ).length() <<
")" );
174 _boundingSphere.x() = center.x();
175 _boundingSphere.y() = center.y();
176 _boundingSphere.z() = center.z();
177 _boundingSphere.w() = radius;
180 MESHINFO <<
"updateBoundingSphere" <<
"( " << _boundingSphere <<
" )."
184 return _boundingSphere;
189 void VertexBufferLeaf::updateRange()
191 _range[0] = 1.0f * _indexStart / _globalData.indices.size();
192 _range[1] = _range[0] + 1.0f * _indexLength / _globalData.indices.size();
195 MESHINFO <<
"updateRange" <<
"( " << _range[0] <<
", " << _range[1]
196 <<
" )." << std::endl;
200 #define glewGetContext state.glewGetContext
203 void VertexBufferLeaf::setupRendering( VertexBufferState& state,
206 switch( state.getRenderMode() )
208 case RENDER_MODE_IMMEDIATE:
211 case RENDER_MODE_BUFFER_OBJECT:
213 const char* charThis =
reinterpret_cast< const char*
>( this );
215 if( data[VERTEX_OBJECT] == state.INVALID )
216 data[VERTEX_OBJECT] = state.newBufferObject( charThis + 0 );
217 glBindBuffer( GL_ARRAY_BUFFER, data[VERTEX_OBJECT] );
218 glBufferData( GL_ARRAY_BUFFER, _vertexLength *
sizeof( Vertex ),
219 &_globalData.vertices[_vertexStart], GL_STATIC_DRAW );
221 if( data[NORMAL_OBJECT] == state.INVALID )
222 data[NORMAL_OBJECT] = state.newBufferObject( charThis + 1 );
223 glBindBuffer( GL_ARRAY_BUFFER, data[NORMAL_OBJECT] );
224 glBufferData( GL_ARRAY_BUFFER, _vertexLength *
sizeof( Normal ),
225 &_globalData.normals[_vertexStart], GL_STATIC_DRAW );
227 if( data[COLOR_OBJECT] == state.INVALID )
228 data[COLOR_OBJECT] = state.newBufferObject( charThis + 2 );
229 if( state.useColors() )
231 glBindBuffer( GL_ARRAY_BUFFER, data[COLOR_OBJECT] );
232 glBufferData( GL_ARRAY_BUFFER, _vertexLength *
sizeof( Color ),
233 &_globalData.colors[_vertexStart], GL_STATIC_DRAW );
236 if( data[INDEX_OBJECT] == state.INVALID )
237 data[INDEX_OBJECT] = state.newBufferObject( charThis + 3 );
238 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, data[INDEX_OBJECT] );
239 glBufferData( GL_ELEMENT_ARRAY_BUFFER,
240 _indexLength *
sizeof( ShortIndex ),
241 &_globalData.indices[_indexStart], GL_STATIC_DRAW );
245 case RENDER_MODE_DISPLAY_LIST:
248 if( data[0] == state.INVALID )
250 char* key = (
char*)(
this );
251 if( state.useColors( ))
253 data[0] = state.newDisplayList( key );
255 glNewList( data[0], GL_COMPILE );
256 renderImmediate( state );
264 void VertexBufferLeaf::draw( VertexBufferState& state )
const
266 if( state.stopRendering( ))
269 state.updateRegion( _boundingBox );
270 switch( state.getRenderMode() )
272 case RENDER_MODE_IMMEDIATE:
273 renderImmediate( state );
275 case RENDER_MODE_BUFFER_OBJECT:
276 renderBufferObject( state );
278 case RENDER_MODE_DISPLAY_LIST:
280 renderDisplayList( state );
286 void VertexBufferLeaf::renderBufferObject( VertexBufferState& state )
const
289 for(
int i = 0; i < 4; ++i )
291 state.getBufferObject( reinterpret_cast< const char* >(
this) + i );
292 if( buffers[VERTEX_OBJECT] == state.INVALID ||
293 buffers[NORMAL_OBJECT] == state.INVALID ||
294 buffers[COLOR_OBJECT] == state.INVALID ||
295 buffers[INDEX_OBJECT] == state.INVALID )
297 setupRendering( state, buffers );
299 if( state.useColors() )
301 glBindBuffer( GL_ARRAY_BUFFER, buffers[COLOR_OBJECT] );
302 glColorPointer( 3, GL_UNSIGNED_BYTE, 0, 0 );
304 glBindBuffer( GL_ARRAY_BUFFER, buffers[NORMAL_OBJECT] );
305 glNormalPointer( GL_FLOAT, 0, 0 );
306 glBindBuffer( GL_ARRAY_BUFFER, buffers[VERTEX_OBJECT] );
307 glVertexPointer( 3, GL_FLOAT, 0, 0 );
308 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers[INDEX_OBJECT] );
309 glDrawElements( GL_TRIANGLES, GLsizei(_indexLength), GL_UNSIGNED_SHORT, 0 );
315 void VertexBufferLeaf::renderDisplayList( VertexBufferState& state )
const
317 char* key = (
char*)(
this );
318 if( state.useColors( ))
321 GLuint displayList = state.getDisplayList( key );
323 if( displayList == state.INVALID )
324 setupRendering( state, &displayList );
326 glCallList( displayList );
332 void VertexBufferLeaf::renderImmediate( VertexBufferState& state )
const
334 glBegin( GL_TRIANGLES );
335 for( Index offset = 0; offset < _indexLength; ++offset )
337 const Index i =_vertexStart + _globalData.indices[_indexStart + offset];
338 if( state.useColors() )
339 glColor3ubv( &_globalData.colors[i][0] );
340 glNormal3fv( &_globalData.normals[i][0] );
341 glVertex3fv( &_globalData.vertices[i][0] );
348 void VertexBufferLeaf::fromMemory(
char** addr, VertexBufferData& globalData )
351 memRead( reinterpret_cast< char* >( &nodeType ), addr,
sizeof(
size_t ) );
352 if( nodeType != LEAF_TYPE )
353 throw MeshException(
"Error reading binary file. Expected a leaf "
354 "node, but found something else instead." );
355 VertexBufferBase::fromMemory( addr, globalData );
356 memRead( reinterpret_cast< char* >( &_boundingBox ), addr,
357 sizeof( BoundingBox ) );
358 memRead( reinterpret_cast< char* >( &_vertexStart ), addr,
360 memRead( reinterpret_cast< char* >( &_vertexLength ), addr,
361 sizeof( ShortIndex ) );
362 memRead( reinterpret_cast< char* >( &_indexStart ), addr,
364 memRead( reinterpret_cast< char* >( &_indexLength ), addr,
370 void VertexBufferLeaf::toStream( std::ostream& os )
372 size_t nodeType = LEAF_TYPE;
373 os.write( reinterpret_cast< char* >( &nodeType ),
sizeof(
size_t ));
374 VertexBufferBase::toStream( os );
375 os.write( reinterpret_cast< char* >( &_boundingBox ),
sizeof( BoundingBox));
376 os.write( reinterpret_cast< char* >( &_vertexStart ),
sizeof( Index ));
377 os.write( reinterpret_cast< char* >( &_vertexLength ),
sizeof( ShortIndex ));
378 os.write( reinterpret_cast< char* >( &_indexStart ),
sizeof( Index ));
379 os.write( reinterpret_cast< char* >( &_indexLength ),
sizeof( Index ));