31 #include "vertexBufferNode.h"
32 #include "vertexBufferLeaf.h"
33 #include "vertexBufferState.h"
34 #include "vertexData.h"
41 VertexBufferNode::~VertexBufferNode()
49 inline static bool _subdivide(
const Index length,
const size_t depth )
51 return ( length / 2 > LEAF_SIZE ) || ( depth < 3 && length > 1 );
55 void VertexBufferNode::setupTree( VertexData& data,
const Index start,
56 const Index length,
const Axis axis,
58 VertexBufferData& globalData )
61 MESHINFO <<
"setupTree"
62 <<
"( " << start <<
", " << length <<
", " << axis <<
", "
63 << depth <<
" )." << std::endl;
66 data.sort( start, length, axis );
67 const Index median = start + ( length / 2 );
70 const Index leftLength = length / 2;
71 const bool subdivideLeft = _subdivide( leftLength, depth );
74 _left =
new VertexBufferNode;
76 _left =
new VertexBufferLeaf( globalData );
79 const Index rightLength = ( length + 1 ) / 2;
80 const bool subdivideRight = _subdivide( rightLength, depth );
83 _right =
new VertexBufferNode;
85 _right =
new VertexBufferLeaf( globalData );
88 const Axis newAxisLeft = subdivideLeft ?
89 data.getLongestAxis( start , leftLength ) : AXIS_X;
91 const Axis newAxisRight = subdivideRight ?
92 data.getLongestAxis( median, rightLength ) : AXIS_X;
94 static_cast< VertexBufferNode*
>
95 ( _left )->setupTree( data, start, leftLength, newAxisLeft, depth+1,
97 static_cast< VertexBufferNode*
>
98 ( _right )->setupTree( data, median, rightLength, newAxisRight, depth+1,
105 const BoundingSphere& VertexBufferNode::updateBoundingSphere()
108 const BoundingSphere& sphere1 = _left->updateBoundingSphere();
109 const BoundingSphere& sphere2 = _right->updateBoundingSphere();
112 const Vertex center1( sphere1.array );
113 const Vertex center2( sphere2.array );
114 Vertex c1ToC2 = center2 - center1;
117 const Vertex outer1 = center1 - c1ToC2 * sphere1.w();
118 const Vertex outer2 = center2 + c1ToC2 * sphere2.w();
120 Vertex vertexBoundingSphere = Vertex( outer1 + outer2 ) * 0.5f;
121 _boundingSphere.x() = vertexBoundingSphere.x();
122 _boundingSphere.y() = vertexBoundingSphere.y();
123 _boundingSphere.z() = vertexBoundingSphere.z();
124 _boundingSphere.w() = Vertex( outer1 - outer2 ).length() * 0.5f;
127 MESHINFO <<
"updateBoundingSphere" <<
"( " << _boundingSphere <<
" )."
131 return _boundingSphere;
136 void VertexBufferNode::updateRange()
139 static_cast< VertexBufferNode*
>( _left )->updateRange();
140 static_cast< VertexBufferNode*
>( _right )->updateRange();
143 _range[0] = std::min( _left->getRange()[0], _right->getRange()[0] );
144 _range[1] = std::max( _left->getRange()[1], _right->getRange()[1] );
147 MESHINFO <<
"updateRange" <<
"( " << _range[0] <<
", " << _range[1]
148 <<
" )." << std::endl;
154 void VertexBufferNode::draw( VertexBufferState& state )
const
156 if ( state.stopRendering( ))
159 _left->draw( state );
160 _right->draw( state );
165 void VertexBufferNode::fromMemory(
char** addr, VertexBufferData& globalData )
169 memRead( reinterpret_cast< char* >( &nodeType ), addr,
sizeof(
size_t ) );
170 if( nodeType != NODE_TYPE )
171 throw MeshException(
"Error reading binary file. Expected a regular "
172 "node, but found something else instead." );
173 VertexBufferBase::fromMemory( addr, globalData );
176 memRead( reinterpret_cast< char* >( &nodeType ), addr,
sizeof(
size_t ) );
177 if( nodeType != NODE_TYPE && nodeType != LEAF_TYPE )
178 throw MeshException(
"Error reading binary file. Expected either a "
179 "regular or a leaf node, but found neither." );
180 *addr -=
sizeof( size_t );
181 if( nodeType == NODE_TYPE )
182 _left =
new VertexBufferNode;
184 _left =
new VertexBufferLeaf( globalData );
185 static_cast< VertexBufferNode*
>( _left )->fromMemory( addr, globalData );
188 memRead( reinterpret_cast< char* >( &nodeType ), addr,
sizeof(
size_t ) );
189 if( nodeType != NODE_TYPE && nodeType != LEAF_TYPE )
190 throw MeshException(
"Error reading binary file. Expected either a "
191 "regular or a leaf node, but found neither." );
192 *addr -=
sizeof( size_t );
193 if( nodeType == NODE_TYPE )
194 _right =
new VertexBufferNode;
196 _right =
new VertexBufferLeaf( globalData );
197 static_cast< VertexBufferNode*
>( _right )->fromMemory( addr, globalData );
202 void VertexBufferNode::toStream( std::ostream& os )
204 size_t nodeType = NODE_TYPE;
205 os.write( reinterpret_cast< char* >( &nodeType ),
sizeof(
size_t ) );
206 VertexBufferBase::toStream( os );
207 static_cast< VertexBufferNode*
>( _left )->toStream( os );
208 static_cast< VertexBufferNode*
>( _right )->toStream( os );