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 ) );
+ }
}
{