void Triangle::merge( VertexArray& va ) { free = dirty = true; parent->dirty = true; VertexArray::index_t* indices = va.triangle( index ); VertexArray::index_t* pindices = va.triangle( parent->index ); va.update_triangle( parent->index, pindices[2], pindices[0], indices[0] ); va.update_triangle( index, 0, 0, 0 ); parent->set_neighbors( parent->neighbors[2], neighbors[2], neighbors[0] ); parent->priority_data.midpoint_vector = Vector3f( va.vertex( pindices[0] ) ); parent->priority_data.depth /= split_size; if( neighbors[2]->neighbors[2] == this ) neighbors[2]->neighbors[2] = parent; else if( neighbors[2]->neighbors[1] == this ) neighbors[2]->neighbors[1] = parent; else neighbors[2]->neighbors[0] = parent; //va.remove_triangle( index ); }
void Diamond::initialize( VertexArray& va, Triangle* child1, Triangle* child2 ) { free = false; dirty = true; children[0] = child1; children[1] = child2; if( child1->diamond ) std::cout << "Bas diamond." << std::endl; child1->parent->neighbors[0] = child1; child1->neighbors[1] = child1->parent; child1->neighbors[0] = child2->parent; child2->parent->neighbors[1] = child1; child2->parent->neighbors[0] = child2; child2->neighbors[1] = child2->parent; child2->neighbors[0] = child1->parent; child1->parent->neighbors[1] = child2; children[0]->parent->diamond = children[1]->parent->diamond = children[0]->diamond = children[1]->diamond = this; priority_data.midpoint_vector = Vector3f( va.vertex( va.triangle( child1->index )[ 1 ] ) ); priority_data.depth = child1->priority_data.depth; }
bool Diamond::initialize( VertexArray& va, Triangle* base ) { free = false; dirty = true; //if( !base->parent ) // return false; if( base->parent == base->neighbors[1] ) base = base->neighbors[1]; if( base->diamond ) std::cout << "Bad diamond." << std::endl; //if( !base->neighbors[0]->parent || !base->neighbors[1]->parent ) // return false; children[0] = base->neighbors[0]; children[1] = base->neighbors[1]; children[0]->parent->diamond = children[1]->parent->diamond = children[0]->diamond = children[1]->diamond = this; priority_data.midpoint_vector = Vector3f( va.vertex( va.triangle( base->index )[ 1 ] ) ); priority_data.depth = base->priority_data.depth; return true; }
void Diamond::merge( VertexArray& va ) { if( children[0]->diamond != this ) std::cout << "I have found the problem." << std::endl; size_t mid = va.triangle( children[0]->index )[ 1 ]; va.remove_point( mid ); children[0]->merge( va ); children[1]->merge( va ); children[0]->parent->diamond = children[0]->diamond = 0; children[1]->parent->diamond = children[1]->diamond = 0; }
void SphericalROAMSystem::initial_geometry( SphericalROAM& roam, VertexArray& array ) { roam.initialized = true; size_t pts[6]; pts[0] = get_vertex( roam, array, Vector3f( 0., 1., 0. ) ); pts[1] = get_vertex( roam, array, Vector3f( 1., 0., 1. ) ); pts[2] = get_vertex( roam, array, Vector3f( 1., 0., -1. ) ); pts[3] = get_vertex( roam, array, Vector3f( -1., 0., -1. ) ); pts[4] = get_vertex( roam, array, Vector3f( -1., 0., 1. ) ); pts[5] = get_vertex( roam, array, Vector3f( 0., -1., 0. ) ); size_t tris[8]; tris[0] = array.add_triangle( pts[2], pts[0], pts[1] ); tris[1] = array.add_triangle( pts[3], pts[0], pts[2] ); tris[2] = array.add_triangle( pts[4], pts[0], pts[3] ); tris[3] = array.add_triangle( pts[1], pts[0], pts[4] ); tris[4] = array.add_triangle( pts[4], pts[5], pts[1] ); tris[5] = array.add_triangle( pts[3], pts[5], pts[4] ); tris[6] = array.add_triangle( pts[2], pts[5], pts[3] ); tris[7] = array.add_triangle( pts[1], pts[5], pts[2] ); Triangle* ts[8]; for( size_t i = 0; i < 8; ++i ) { ts[ i ] = new Triangle( tris[i] ); roam.triangles.push_back( ts[ i ] ); roam.splits.push_back( TriangleData( ts[i] ) ); std::push_heap( roam.splits.begin(), roam.splits.end() ); } ts[0]->set_neighbors( ts[1], ts[3], ts[7] ); ts[1]->set_neighbors( ts[2], ts[0], ts[6] ); ts[2]->set_neighbors( ts[3], ts[1], ts[5] ); ts[3]->set_neighbors( ts[0], ts[2], ts[4] ); ts[4]->set_neighbors( ts[5], ts[7], ts[3] ); ts[5]->set_neighbors( ts[6], ts[4], ts[2] ); ts[6]->set_neighbors( ts[7], ts[5], ts[1] ); ts[7]->set_neighbors( ts[4], ts[6], ts[0] ); for( size_t i = 0; i < 4; ++i ) ts[ i ]->priority_data.midpoint_vector = Vector3f( 0., 1., 0. ); for( size_t i = 4; i < 8; ++i ) ts[ i ]->priority_data.midpoint_vector = Vector3f( 0., -1., 0. ); Vector3f look; size_t ndirty = 0; std::vector< Triangle* > split_queue; while( array.nvertices - array.nused_vertices ) { TriangleData d = roam.splits.front(); std::pop_heap( roam.splits.begin(), roam.splits.end() ); roam.splits.pop_back(); if( d.dirty() ) { d.update( pos, look ); roam.splits.push_back( d ); std::push_heap( roam.splits.begin(), roam.splits.end() ); ++ndirty; continue; } Triangle* split = d.triangle; do { split_queue.push_back( split ); } while( split = split->split_first() ); do { split = split_queue.back(); split_queue.pop_back(); VertexArray::index_t* indices = array.triangle( split->index ); Vector3f midpoint_dir = Vector3f( array.vertex( indices[0] ) ) + Vector3f( array.vertex( indices[2] ) ); size_t new_vert = get_vertex( roam, array, midpoint_dir ); Triangle* tri1 = new Triangle( array.add_triangle( 0, 0, 0 ) ); Triangle* tri2 = new Triangle( array.add_triangle( 0, 0, 0 ) ); roam.triangles.push_back( tri1 ); roam.triangles.push_back( tri2 ); Diamond* frees[2]; frees[0] = split->neighbors[2]->split( array, tri2, new_vert ); frees[1] = split->split( array, tri1, new_vert ); for( unsigned char i = 0; i < 2; ++i ) { roam.free_diamond( frees[i] ); } Diamond* diamond = roam.get_free_diamond(); diamond->initialize( array, tri1, tri2 ); //roam.merges.push_back( DiamondData( diamond, pos, look ) ); //std::push_heap( roam.merges.begin(), roam.merges.end() ); roam.splits.push_back( TriangleData( tri1, pos, look ) ); std::push_heap( roam.splits.begin(), roam.splits.end() ); roam.splits.push_back( TriangleData( tri2, pos, look ) ); std::push_heap( roam.splits.begin(), roam.splits.end() ); } while( array.nvertices - array.nused_vertices && split_queue.size() ); d.update( pos, look ); roam.splits.push_back( d ); std::push_heap( roam.splits.begin(), roam.splits.end() ); } }
void SphericalROAMSystem::split( SphericalROAM& roam, VertexArray& array, Triangle* tri ) { if( tri->split_first() ) { split( roam, array, tri->split_first() ); } /* if( !dia.children[0]->is_diamond() ) std::cout << "No diamond." << std::endl; dia.merge( array ); Triangle* parents[2]; for( unsigned char i = 0; i < 2; ++i ) { Triangle* par = parents[i] = dia.children[i]->parent; if( par->parent && par->is_diamond() ) { Diamond* newdia = roam.get_free_diamond(); if( !newdia->initialize( array, par ) ) { roam.free_diamond( newdia ); continue; } roam.merges.push_back( DiamondData( newdia ) ); std::push_heap( roam.merges.begin(), roam.merges.end() ); } //if( check_diamonds( roam ) > 1 ) // std::cout << "I did it." << std::endl; } while( queue.back()->split_first() ) { queue.push_back( queue.back()->split_first() ); //array.remove_triangle( dia.children[0]->index ); //array.remove_triangle( dia.children[1]->index ); //roam.free_diamond( &dia ); //return; } Triangle& tri = *queue.back(); queue.pop_back(); */ Triangle* news[2]; news[0] = &roam.free_triangles.back(); roam.free_triangles.pop_back(); news[1] = &roam.free_triangles.back(); roam.free_triangles.pop_back(); roam.triangles.push_back( news[0] ); roam.triangles.push_back( news[1] ); roam.nfree_triangles -= 2; VertexArray::index_t* indices = array.triangle( tri->index ); Vector3f midpoint_dir = Vector3f( array.vertex( indices[0] ) ) + Vector3f( array.vertex( indices[2] ) ); size_t vert = get_vertex( roam, array, midpoint_dir ); Diamond* frees[2]; frees[0] = tri->neighbors[2]->split( array, news[1], vert ); frees[1] = tri->split( array, news[0], vert ); for( unsigned char i = 0; i < 2; ++i ) { roam.free_diamond( frees[i] ); } Diamond* newdia = roam.get_free_diamond(); newdia->initialize( array, news[0], news[1] ); //roam.merges.push_back( DiamondData( newdia ) ); //std::push_heap( roam.merges.begin(), roam.merges.end() ); //roam.free_diamond( &dia ); //if( check_diamonds( roam ) ) // std::cout << "I did it." << std::endl; }