commit 6660d383385d8476c8d60f200ae5841098479d01 parent 3c66af2384ebfd48b89bbe828efa78a2643feafc Author: Michael Savage <mikejsavage@gmail.com> Date: Thu Aug 27 23:18:19 +0200 Initial work on TerrainManager refactor Diffstat:
hm.cc | | | 8 | ++++---- |
terrain_manager.cc | | | 200 | +++++++++++++++++++++++++++++++++---------------------------------------------- |
terrain_manager.h | | | 48 | +++++++++++++++++------------------------------- |
diff --git a/hm.cc b/hm.cc @@ -98,8 +98,8 @@ static WORK_QUEUE_CALLBACK( testwq ) { extern "C" GAME_INIT( game_init ) { state->pos = glm::vec3( 15000, 3000, 50 ); state->angles = glm::radians( glm::vec3( -90, 45, 0 ) ); - state->tm.use( "Srtm_ramp2.world.21600x10800.jpg.parts" ); - state->tm.teleport( state->pos ); + terrain_init( &state->tm, "Srtm_ramp2.world.21600x10800.jpg.parts" ); + terrain_teleport( &state->tm, state->pos ); workqueue_init( &state->background_tasks, 2 ); u32 nums[ 10 ]; @@ -239,7 +239,7 @@ extern "C" GAME_FRAME( game_frame ) { // pos.z = hm.height( pos.x, pos.y ) + 8; state->pos.z += dz * 50.0f * dt; - state->tm.update( state->pos ); + terrain_update( &state->tm, state->pos ); const glm::mat4 VP = glm::translate( glm::rotate( @@ -254,7 +254,7 @@ extern "C" GAME_FRAME( game_frame ) { -state->pos ); - state->tm.render( VP ); + terrain_render( &state->tm, VP ); glDisable( GL_DEPTH_TEST ); glUseProgram( state->test_shader ); diff --git a/terrain_manager.cc b/terrain_manager.cc @@ -8,7 +8,7 @@ * - wx/wy are used to denote global coordinates */ -#include <string> +#include <string.h> #include <glm/glm.hpp> @@ -16,163 +16,129 @@ #include "heightmap.h" #include "terrain_manager.h" -int iabs( const int x ) { - return x < 0 ? -x : x; +// TODO: lol +static char tp_path[ 256 ]; +static char * tp( const TerrainManager * const tm, const u32 tx, const u32 ty ) { + sprintf( tp_path, "%s/%d_%d.tga", tm->dir, tx, ty ); + return tp_path; } -TerrainManager::TerrainManager( const std::string & dir ) { - use( dir ); -} +void terrain_init( TerrainManager * const tm, const char * const tiles_dir ) { + assert( strlen( tiles_dir ) < array_count( tm->dir ) ); + strcpy( tm->dir, tiles_dir ); -void TerrainManager::use( const std::string & dir ) { - this->dir = dir; + char dims_path[ 256 ]; + sprintf( dims_path, "%s/dims.txt", tm->dir ); - FILE * dims = fopen( ( dir + "/dims.txt" ).c_str(), "r" ); - fscanf( dims, "%d %d", &w, &h ); + FILE * dims = fopen( dims_path, "r" ); + fscanf( dims, "%d %d", &tm->width, &tm->height ); fclose( dims ); - printf( "%d %d\n", w, h ); + printf( "%d %d\n", tm->width, tm->height ); - for( int ty = 0; ty < REGION_SIZE; ty++ ) { - for( int tx = 0; tx < REGION_SIZE; tx++ ) { - const int rx = tx - REGION_HALF; - const int ry = ty - REGION_HALF; + for( u32 ty = 0; ty < tm->height / TILE_SIZE; ty++ ) { + printf( "init %u\n", ty ); + for( u32 tx = 0; tx < tm->width / TILE_SIZE; tx++ ) { + tm->tiles[ tx ][ ty ].init(); + } + } - if( rx == ry || rx == -ry ) { - lods[ tx ][ ty ] = std::max( 1, iabs( rx ) + iabs( ry ) - 1 ); - } - else { - lods[ tx ][ ty ] = std::max( iabs( rx ), iabs( ry ) ); - } + tm->first_teleport = true; +} + +void terrain_teleport( TerrainManager * const tm, const glm::vec3 position ) { + const u32 new_tx = position.x / TILE_SIZE; + const u32 new_ty = position.y / TILE_SIZE; - tiles[ tx ][ ty ].init(); + // TODO: this is a cheap hack + if( !tm->first_teleport ) { + for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { + for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { + tm->tiles[ tm->last_tx + tx - VIEW_HALF ][ tm->last_ty + ty - VIEW_HALF ].unload(); + } } } - for( int ty = 0; ty < REGION_SIZE; ty++ ) { - for( int tx = 0; tx < REGION_SIZE; tx++ ) { - printf( "%d ", lods[ tx ][ ty ] ); + tm->first_teleport = false; + + tm->last_tx = new_tx; + tm->last_ty = new_ty; + + for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { + for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { + tm->tiles[ new_tx + tx - VIEW_HALF ][ new_ty + ty - VIEW_HALF ].load( + tp( tm, new_tx + tx - VIEW_HALF, new_ty + ty - VIEW_HALF ), + ( new_tx + tx - VIEW_HALF ) * TILE_SIZE, + ( new_ty + ty - VIEW_HALF ) * TILE_SIZE + ); } - printf( "\n" ); } } -std::string TerrainManager::tp( const int tx, const int ty ) const { - return dir + "/" + std::to_string( tx ) + "_" + std::to_string( ty ) + ".tga"; -} +void terrain_update( TerrainManager * const tm, const glm::vec3 position ) { + const u32 new_tx = position.x / TILE_SIZE; + const u32 new_ty = position.y / TILE_SIZE; -void TerrainManager::update( const glm::vec3 & position ) { - const int new_ptx = position.x / TILE_SIZE; - const int new_pty = position.y / TILE_SIZE; - - if( new_ptx != ptx ) { - if( new_ptx > ptx ) { + if( new_tx != tm->last_tx ) { + if( new_tx > tm->last_tx ) { printf( "boundary +x\n" ); - for( int ty = 0; ty < REGION_SIZE; ty++ ) { - tiles[ 0 ][ ty ].unload(); - - for( int tx = 1; tx < REGION_SIZE; tx++ ) { - tiles[ tx - 1 ][ ty ] = std::move( tiles[ tx ][ ty ] ); - } + for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { + tm->tiles[ tm->last_tx - VIEW_HALF ][ ty ].unload(); - tiles[ REGION_SIZE - 1 ][ ty ].load( - tp( ptx + REGION_HALF + 1, pty + ty - REGION_HALF ), - ( ptx + REGION_HALF + 1 ) * TILE_SIZE, - ( pty + ty - REGION_HALF ) * TILE_SIZE ); + tm->tiles[ tm->last_tx + VIEW_HALF + 1 ][ ty ].load( + tp( tm, tm->last_tx + VIEW_HALF + 1, tm->last_ty + ty - VIEW_HALF ), + ( tm->last_tx + VIEW_HALF + 1 ) * TILE_SIZE, + ( tm->last_ty + ty - VIEW_HALF ) * TILE_SIZE ); } - ptx++; + tm->last_tx++; } else { printf( "boundary -x\n" ); - for( int ty = 0; ty < REGION_SIZE; ty++ ) { - tiles[ REGION_SIZE - 1 ][ ty ].unload(); - - for( int tx = REGION_SIZE - 2; tx >= 0; tx-- ) { - tiles[ tx + 1 ][ ty ] = std::move( tiles[ tx ][ ty ] ); - } + for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { + tm->tiles[ tm->last_tx + VIEW_HALF ][ ty ].unload(); - tiles[ 0 ][ ty ].load( - tp( ptx - REGION_HALF - 1, pty + ty - REGION_HALF ), - ( ptx - REGION_HALF - 1 ) * TILE_SIZE, - ( pty + ty - REGION_HALF ) * TILE_SIZE ); + tm->tiles[ tm->last_tx - VIEW_HALF - 1 ][ ty ].load( + tp( tm, tm->last_tx - VIEW_HALF - 1, tm->last_ty + ty - VIEW_HALF ), + ( tm->last_tx - VIEW_HALF - 1 ) * TILE_SIZE, + ( tm->last_ty + ty - VIEW_HALF ) * TILE_SIZE ); } - ptx--; + tm->last_tx--; } } - if( new_pty != pty ) { - if( new_pty > pty ) { + if( new_ty != tm->last_ty ) { + if( new_ty > tm->last_ty ) { printf( "boundary +y\n" ); - for( int tx = 0; tx < REGION_SIZE; tx++ ) { - tiles[ tx ][ 0 ].unload(); + for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { + tm->tiles[ tx ][ tm->last_ty - VIEW_HALF ].unload(); - for( int ty = 1; ty < REGION_SIZE; ty++ ) { - tiles[ tx ][ ty - 1 ] = std::move( tiles[ tx ][ ty ] ); - } - - tiles[ tx ][ REGION_SIZE - 1 ].load( - tp( ptx + tx - REGION_HALF, pty + REGION_HALF + 1 ), - ( ptx + tx - REGION_HALF ) * TILE_SIZE, - ( pty + REGION_HALF + 1 ) * TILE_SIZE ); + tm->tiles[ tx ][ tm->last_ty + VIEW_HALF + 1 ].load( + tp( tm, tm->last_tx + tx - VIEW_HALF, tm->last_ty + VIEW_HALF + 1 ), + ( tm->last_tx + tx - VIEW_HALF ) * TILE_SIZE, + ( tm->last_ty + VIEW_HALF + 1 ) * TILE_SIZE ); } - pty++; + tm->last_ty++; } else { printf( "boundary -y\n" ); - for( int tx = 0; tx < REGION_SIZE; tx++ ) { - tiles[ tx ][ REGION_SIZE - 1 ].unload(); - - for( int ty = REGION_SIZE - 2; ty >= 0; ty-- ) { - tiles[ tx ][ ty + 1 ] = std::move( tiles[ tx ][ ty ] ); - } + for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { + tm->tiles[ tx ][ tm->last_ty + VIEW_HALF ].unload(); - tiles[ tx ][ 0 ].load( - tp( ptx + tx - REGION_HALF, pty - REGION_HALF - 1 ), - ( ptx + tx - REGION_HALF ) * TILE_SIZE, - ( pty - REGION_HALF - 1 ) * TILE_SIZE ); + tm->tiles[ tx ][ tm->last_ty - VIEW_HALF - 1 ].load( + tp( tm, tm->last_tx + tx - VIEW_HALF, tm->last_ty - VIEW_HALF - 1 ), + ( tm->last_tx + tx - VIEW_HALF ) * TILE_SIZE, + ( tm->last_ty - VIEW_HALF - 1 ) * TILE_SIZE ); } - pty--; + tm->last_ty--; } } } -void TerrainManager::prepare_teleport( const glm::vec3 & position ) { -} - -bool TerrainManager::teleport_ready() { - return false; -} - -void TerrainManager::teleport( const glm::vec3 & position ) { - cx = cy = REGION_HALF; - ptx = position.x / TILE_SIZE; - pty = position.y / TILE_SIZE; - - for( int ty = 0; ty < REGION_SIZE; ty++ ) { - for( int tx = 0; tx < REGION_SIZE; tx++ ) { - const int ltx = ptx + tx - REGION_HALF; - const int lty = pty + ty - REGION_HALF; - - if( ltx >= 0 && ltx < w && lty >= 0 && lty < h ) { - tiles[ tx ][ ty ].load( - dir + "/" + std::to_string( ltx ) + "_" + std::to_string( lty ) + ".tga", - ltx * TILE_SIZE, - lty * TILE_SIZE - ); - } - else { - tiles[ tx ][ ty ].unload(); - } - } - } - -} - -void TerrainManager::render( const glm::mat4 & VP ) { - for( int ty = 0; ty < REGION_SIZE; ty++ ) { - for( int tx = 0; tx < REGION_SIZE; tx++ ) { - tiles[ tx ][ ty ].render( VP ); +void terrain_render( const TerrainManager * const tm, const glm::mat4 VP ) { + for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { + for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { + tm->tiles[ tm->last_tx + tx - VIEW_HALF ][ tm->last_ty + ty - VIEW_HALF ].render( VP ); } } } diff --git a/terrain_manager.h b/terrain_manager.h @@ -7,37 +7,23 @@ #include "intrinsics.h" #include "heightmap.h" -class TerrainManager { -private: - static const int TILE_SIZE = 128; - static const int REGION_SIZE = 5; - static const int REGION_HALF = REGION_SIZE / 2; - - std::string dir; - - int w, h; - - Heightmap tiles[ REGION_SIZE ][ REGION_SIZE ]; - Heightmap alt_tiles[ REGION_SIZE ][ REGION_SIZE ]; - - u8 lods[ REGION_SIZE ][ REGION_SIZE ]; - - int cx, cy; - int ptx, pty; - -public: - TerrainManager( const std::string & dir ); - void use( const std::string & dir ); - - std::string tp( const int tx, const int ty ) const; - void update( const glm::vec3 & position ); - - // maybe these aren't needed - void prepare_teleport( const glm::vec3 & position ); - bool teleport_ready(); - void teleport( const glm::vec3 & position ); - - void render( const glm::mat4 & VP ); +static const u32 TILE_SIZE = 128; +static const u32 MAX_TILES_DIM = 256; + +static const u32 VIEW_SIZE = 5; +static const u32 VIEW_HALF = VIEW_SIZE / 2; + +struct TerrainManager { + char dir[ 128 ]; + u32 width, height; + u32 last_tx, last_ty; + bool first_teleport; + Heightmap tiles[ MAX_TILES_DIM ][ MAX_TILES_DIM ]; }; +void terrain_init( TerrainManager * const tm, const char * const tiles_dir ); +void terrain_teleport( TerrainManager * const tm, const glm::vec3 position ); +void terrain_update( TerrainManager * const tm, const glm::vec3 position ); +void terrain_render( const TerrainManager * const tm, const glm::mat4 VP ); + #endif // _TERRAIN_MANAGER_H_