/* Continue kd-tree setup, create intermediary or leaf nodes as required. */ void VertexBufferNode::setupTree( VertexData& data, const Index start, const Index length, const Axis axis, const size_t depth, VertexBufferData& globalData, boost::progress_display& progress ) { data.sort( start, length, axis ); const Index median = start + ( length / 2 ); // left child will include elements smaller than the median const Index leftLength = length / 2; const bool subdivideLeft = _subdivide( leftLength, depth ); if( subdivideLeft ) _left = new VertexBufferNode; else _left = new VertexBufferLeaf( globalData ); // right child will include elements equal to or greater than the median const Index rightLength = ( length + 1 ) / 2; const bool subdivideRight = _subdivide( rightLength, depth ); if( subdivideRight ) _right = new VertexBufferNode; else _right = new VertexBufferLeaf( globalData ); // move to next axis and continue contruction in the child nodes const Axis newAxisLeft = subdivideLeft ? data.getLongestAxis( start , leftLength ) : AXIS_X; const Axis newAxisRight = subdivideRight ? data.getLongestAxis( median, rightLength ) : AXIS_X; static_cast< VertexBufferNode* > ( _left )->setupTree( data, start, leftLength, newAxisLeft, depth+1, globalData, progress ); static_cast< VertexBufferNode* > ( _right )->setupTree( data, median, rightLength, newAxisRight, depth+1, globalData, progress ); if( depth == 3 ) ++progress; }
/* Finish partial setup - sort, reindex and merge into global data. */ void VertexBufferLeaf::setupTree( VertexData& data, const Index start, const Index length, const Axis axis, const size_t depth, VertexBufferData& globalData ) { data.sort( start, length, axis ); _vertexStart = globalData.vertices.size(); _vertexLength = 0; _indexStart = globalData.indices.size(); _indexLength = 0; const bool hasColors = ( data.colors.size() > 0 ); // stores the new indices (relative to _start) map< Index, ShortIndex > newIndex; for( Index t = 0; t < length; ++t ) { for( Index v = 0; v < 3; ++v ) { Index i = data.triangles[start + t][v]; if( newIndex.find( i ) == newIndex.end() ) { newIndex[i] = _vertexLength++; // assert number of vertices does not exceed SmallIndex range MESHASSERT( _vertexLength ); globalData.vertices.push_back( data.vertices[i] ); if( hasColors ) globalData.colors.push_back( data.colors[i] ); globalData.normals.push_back( data.normals[i] ); } globalData.indices.push_back( newIndex[i] ); ++_indexLength; } } #ifndef NDEBUG MESHINFO << "VertexBufferLeaf::setupTree" << "( " << _indexStart << ", " << _indexLength << "; start " << _vertexStart << ", " << _vertexLength << " vertices)." << endl; #endif }