medfall

A super great game engine
Log | Files | Refs

commit 7651cd98b8d8a2f3cfd86e1854914b5d994d0526
parent 4845c6f755e600053866a59aa265a89e6f82fcd7
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Fri, 10 Nov 2017 21:34:39 +0200

Forgot to copy the tree planting code

Diffstat:
pp.cc | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+), 0 deletions(-)

diff --git a/pp.cc b/pp.cc @@ -9,6 +9,8 @@ #include "decompress_bc.h" #include "autogdb.h" +#include "rng/well512.h" + #include "libs/lz4/lz4.h" #include "libs/lz4/lz4hc.h" @@ -195,6 +197,66 @@ static u8 * write_compressed_texture( MemoryArena * arena, const DynamicString & return dxt; } +const size_t MAX_TREES = 262144 / 4; + +static bool ok_tree_position( RNGWell512 * rng, const array2d< u16 > heightmap, const array2d< v3 > normalmap, v2 pos, v3 * tree ) { + u16 height = bilerp01( heightmap, pos.x, pos.y ); + double p = 1; + if( height <= 5 * 256 ) return false; + if( height > 235 * 256 ) return false; + if( height >= 200 * 256 ) { + p *= double( 235 * 256 - height ) / double( 235 * 256 - 200 * 256 ); + } + + v3 normal = normalize( bilerp01( normalmap, pos.x, pos.y ) ); + if( normal.z < 0.3 ) return false; + + p *= ( normal.z - 0.3 ) / 0.7; + + if( !rng_p( rng, p ) ) return false; + + *tree = v3( pos.x * heightmap.w, pos.y * heightmap.h, height / 256 ); + return true; +} + +static void hammersley( size_t n, array< v2 > points ) { + for( size_t i = 0; i < n; i++ ) { + float u = 0; + float v = ( i + 0.5f ) / n; + float p = 0.5; + + size_t x = i; + while( x > 0 ) { + if( x % 2 == 1 ) u += p; + p /= 2; + x /= 2; + } + + points[ i ] = v2( u, v ); + } +} + +static size_t place_trees( MemoryArena * arena, const array2d< u16 > heightmap, const array2d< v3 > normalmap, array< v3 > trees ) { + MEMARENA_SCOPED_CHECKPOINT( arena ); + + array< v2 > points = memarena_push_array( arena, v2, trees.n ); + hammersley( MAX_TREES, points ); + + RNGWell512 rng; + rng_well512_init( &rng ); + + size_t placed = 0; + for( v2 point : points ) { + v3 pos; + if( ok_tree_position( &rng, heightmap, normalmap, point, &pos ) ) { + trees[ placed ] = pos; + placed++; + } + } + + return placed; +} + int main( int argc, char ** argv ) { install_debug_signal_handlers( true ); @@ -213,6 +275,9 @@ int main( int argc, char ** argv ) { array2d< u16 > heightmap( png, w, h ); u8 * bc5_heightmap; + mkdir( "terrains", 0755 ); + mkdir( output_path.c_str(), 0755 ); + { printf( "computing heightmaps\n" ); @@ -252,6 +317,17 @@ int main( int argc, char ** argv ) { printf( "compressing\n" ); DynamicString normalmap_path( "{}/normalmap.bc5.lz4", output_path ); write_compressed_texture( &arena, normalmap_path, normalmap, squish::kBc5 ); + + { + printf( "planting trees\n" ); + + array< v3 > trees = alloc_array< v3 >( &arena, MAX_TREES ); + size_t num_trees = place_trees( &arena, heightmap, normalmap_v3, trees ); + + printf( "compressing\n" ); + DynamicString trees_path( "{}/trees.lz4", output_path ); + write_compressed_file( &arena, trees_path, trees.ptr(), num_trees * sizeof( v3 ) ); + } } {