From e1f9315d807caad59c038b0796cf8792e1f96a9e Mon Sep 17 00:00:00 2001 From: hgn Date: Fri, 31 Mar 2023 03:18:39 +0100 Subject: [PATCH] perlin --- vg_audio.h | 144 +++++++++++++++++------------------------------- vg_log.h | 6 +- vg_m.h | 3 +- vg_perlin.h | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+), 100 deletions(-) create mode 100644 vg_perlin.h diff --git a/vg_audio.h b/vg_audio.h index 279b7f4..bff400f 100644 --- a/vg_audio.h +++ b/vg_audio.h @@ -474,8 +474,7 @@ static void audio_channel_sidechain_lfo( audio_channel *ch, int lfo_id, static void audio_channel_set_spacial( audio_channel *ch, v3f co, float range ) { - if( ch->flags & AUDIO_FLAG_SPACIAL_3D ) - { + if( ch->flags & AUDIO_FLAG_SPACIAL_3D ){ v3_copy( co, ch->editable_state.spacial_falloff ); if( range == 0.0f ) @@ -485,8 +484,7 @@ static void audio_channel_set_spacial( audio_channel *ch, v3f co, float range ) ch->editble_state_write_mask |= AUDIO_EDIT_SPACIAL; } - else - { + else{ vg_warn( "Tried to set spacialization paramaters for 2D channel (%s)\n", ch->name ); } @@ -497,8 +495,7 @@ static int audio_oneshot_3d( audio_clip *clip, v3f position, { audio_channel *ch = audio_request_channel( clip, AUDIO_FLAG_SPACIAL_3D ); - if( ch ) - { + if( ch ){ audio_channel_set_spacial( ch, position, range ); audio_channel_edit_volume( ch, volume, 1 ); ch = audio_relinquish_channel( ch ); @@ -513,8 +510,7 @@ static int audio_oneshot( audio_clip *clip, float volume, float pan ) { audio_channel *ch = audio_request_channel( clip, 0x00 ); - if( ch ) - { + if( ch ){ audio_channel_edit_volume( ch, volume, 1 ); ch = audio_relinquish_channel( ch ); @@ -542,7 +538,6 @@ static void audio_set_lfo_frequency( int id, float freq ) } - /* * Committers * ----------------------------------------------------------------------------- @@ -660,15 +655,13 @@ stb_vorbis_get_samples_i16_downmixed( stb_vorbis *f, i16 *buffer, int len ) int n = 0, c = VG_MIN( 1, f->channels - 1 ); - while( n < len ) - { + while( n < len ) { int k = f->channel_buffer_end - f->channel_buffer_start; if( n+k >= len ) k = len - n; - for( int j=0; j < k; ++j ) - { + for( int j=0; j < k; ++j ) { float sl = f->channel_buffers[ 0 ][f->channel_buffer_start+j], sr = f->channel_buffers[ c ][f->channel_buffer_start+j]; @@ -699,8 +692,7 @@ static inline float audio_lfo_pull_sample( audio_lfo *lfo ) float t = lfo->time; t /= (float)lfo->_.period; - if( lfo->_.wave_type == k_lfo_polynomial_bipolar ) - { + if( lfo->_.wave_type == k_lfo_polynomial_bipolar ){ /* * # * # # @@ -722,8 +714,7 @@ static inline float audio_lfo_pull_sample( audio_lfo *lfo ) ) * (1.0f-fabsf(t)); } - else - { + else{ return 0.0f; } } @@ -738,45 +729,37 @@ static void audio_channel_get_samples( audio_channel *ch, u32 format = ch->source->flags & AUDIO_FLAG_FORMAT; - while( remaining ) - { + while( remaining ){ u32 samples_this_run = VG_MIN(remaining, ch->source_length - ch->cursor); remaining -= samples_this_run; float *dst = &buf[ buffer_pos * 2 ]; - if( format == k_audio_format_stereo ) - { - for( int i=0;ivorbis_handle, dst, samples_this_run ); - if( read_samples != samples_this_run ) - { + if( read_samples != samples_this_run ){ vg_warn( "Invalid samples read (%s)\n", ch->source->path ); - for( int i=0; ibird_handle, dst, samples_this_run ); } - else - { + else{ i16 *src_buffer = ch->source->data, *src = &src_buffer[ch->cursor]; @@ -786,8 +769,7 @@ static void audio_channel_get_samples( audio_channel *ch, ch->cursor += samples_this_run; buffer_pos += samples_this_run; - if( (ch->flags & AUDIO_FLAG_LOOP) && remaining ) - { + if( (ch->flags & AUDIO_FLAG_LOOP) && remaining ){ if( format == k_audio_format_vorbis ) stb_vorbis_seek_start( ch->vorbis_handle ); else if( format == k_audio_format_bird ) @@ -800,8 +782,7 @@ static void audio_channel_get_samples( audio_channel *ch, break; } - while( remaining ) - { + while( remaining ){ buf[ buffer_pos*2 + 0 ] = 0.0f; buf[ buffer_pos*2 + 1 ] = 0.0f; buffer_pos ++; @@ -819,39 +800,24 @@ static void audio_channel_mix( audio_channel *ch, float *buffer ) float frame_samplerate = ch->_.sampling_rate; - if( ch->flags & AUDIO_FLAG_SPACIAL_3D ) - { - if( !vg_validf(vg_audio.listener_pos[0]) || - !vg_validf(vg_audio.listener_pos[1]) || - !vg_validf(vg_audio.listener_pos[2]) || - !vg_validf(vg_audio.listener_velocity[0]) || - !vg_validf(vg_audio.listener_velocity[1]) || - !vg_validf(vg_audio.listener_velocity[2]) || - !vg_validf(ch->_.spacial_falloff[0]) || - !vg_validf(ch->_.spacial_falloff[1]) || - !vg_validf(ch->_.spacial_falloff[2]) ) - { - vg_error( "NaN listener/world position (%s)\n", ch->name ); + if( ch->flags & AUDIO_FLAG_SPACIAL_3D ){ + v3f delta; + v3_sub( ch->_.spacial_falloff, vg_audio.listener_pos, delta ); + + float dist = v3_length( delta ), + vol = vg_maxf( 0.0f, 1.0f - ch->_.spacial_falloff[3]*dist ); - framevol_l = 0.0f; - framevol_r = 0.0f; + if( dist <= 0.01f ){ + } else{ - v3f delta; - v3_sub( ch->_.spacial_falloff, vg_audio.listener_pos, delta ); - - float dist = v3_length( delta ), - vol = vg_maxf( 0.0f, 1.0f - ch->_.spacial_falloff[3]*dist ); - v3_muls( delta, 1.0f/dist, delta ); - float pan = v3_dot( vg_audio.listener_ears, delta ); + float pan = v3_dot( vg_audio.listener_ears, delta ); vol = powf( vol, 5.0f ); framevol_l *= (vol * 0.5f) * (1.0f - pan); framevol_r *= (vol * 0.5f) * (1.0f + pan); - v3_muls( delta, 1.0f/dist, delta ); - const float vs = 100.0f; float doppler = (vs+v3_dot(delta,vg_audio.listener_velocity))/vs; doppler = vg_clampf( doppler, 0.6f, 1.4f ); @@ -859,11 +825,15 @@ static void audio_channel_mix( audio_channel *ch, float *buffer ) if( fabsf(doppler-1.0f) > 0.01f ) frame_samplerate *= doppler; } + + if( !vg_validf( framevol_l ) ) vg_fatal_exit_loop( "NaN left channel" ); + if( !vg_validf( framevol_r ) ) vg_fatal_exit_loop( "NaN right channel" ); + if( !vg_validf( frame_samplerate ) ) + vg_fatal_exit_loop( "NaN sample rate" ); } u32 buffer_length = AUDIO_MIX_FRAME_SIZE; - if( frame_samplerate != 1.0f ) - { + if( frame_samplerate != 1.0f ){ float l = ceilf( (float)(AUDIO_MIX_FRAME_SIZE) * frame_samplerate ); buffer_length = l+1; } @@ -882,8 +852,7 @@ static void audio_channel_mix( audio_channel *ch, float *buffer ) const float volume_start = ch->volume_movement_start; const float volume_target = ch->_.volume_target; - for( u32 j=0; jallocated ) continue; - if( ch->activity == k_channel_activity_alive ) - { + if( ch->activity == k_channel_activity_alive ){ if( (ch->cursor >= ch->source_length) && !(ch->flags & AUDIO_FLAG_LOOP) ) { @@ -966,8 +933,7 @@ VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int byte_count ) } /* process relinquishments */ - if( (ch->activity != k_channel_activity_reset) && ch->_.relinquished ) - { + if( (ch->activity != k_channel_activity_reset) && ch->_.relinquished ){ if( (ch->activity == k_channel_activity_end) || (ch->_.volume == 0.0f) || (ch->activity == k_channel_activity_error) ) @@ -980,8 +946,7 @@ VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int byte_count ) } /* process new channels */ - if( ch->activity == k_channel_activity_reset ) - { + if( ch->activity == k_channel_activity_reset ){ ch->_ = ch->editable_state; ch->cursor = 0; ch->source_length = 0; @@ -994,27 +959,23 @@ VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int byte_count ) ch->editable_state.relinquished = ch->_.relinquished; - if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME ) - { + if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME ){ ch->_.volume = ch->editable_state.volume; ch->_.volume_target = ch->editable_state.volume; } - else - { + else{ ch->editable_state.volume = ch->_.volume; } - if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME_SLOPE ) - { + if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME_SLOPE ){ ch->volume_movement_start = ch->_.volume; ch->volume_movement = 0; ch->_.volume_target = ch->editable_state.volume_target; ch->_.volume_rate = ch->editable_state.volume_rate; } - else - { + else{ ch->editable_state.volume_target = ch->_.volume_target; ch->editable_state.volume_rate = ch->_.volume_rate; } @@ -1026,13 +987,11 @@ VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int byte_count ) ch->editable_state.sampling_rate = ch->_.sampling_rate; - if( ch->editble_state_write_mask & AUDIO_EDIT_LFO_ATTACHMENT ) - { + if( ch->editble_state_write_mask & AUDIO_EDIT_LFO_ATTACHMENT ){ ch->_.lfo = ch->editable_state.lfo; ch->_.lfo_amount = ch->editable_state.lfo_amount; } - else - { + else{ ch->editable_state.lfo = ch->_.lfo; ch->editable_state.lfo_amount = ch->_.lfo_amount; } @@ -1050,12 +1009,10 @@ VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int byte_count ) ch->editble_state_write_mask = 0x00; } - for( int i=0; ieditble_state_write_mask & AUDIO_EDIT_LFO_WAVE ) - { + if( lfo->editble_state_write_mask & AUDIO_EDIT_LFO_WAVE ){ lfo->_.wave_type = lfo->editable_state.wave_type; if( lfo->_.wave_type == k_lfo_polynomial_bipolar ) @@ -1067,18 +1024,15 @@ VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int byte_count ) } } - if( lfo->editble_state_write_mask & AUDIO_EDIT_LFO_PERIOD ) - { - if( lfo->_.period ) - { + if( lfo->editble_state_write_mask & AUDIO_EDIT_LFO_PERIOD ){ + if( lfo->_.period ){ float t = lfo->time; t/= (float)lfo->_.period; lfo->_.period = lfo->editable_state.period; lfo->time = lfo->_.period * t; } - else - { + else{ lfo->time = 0; lfo->_.period = lfo->editable_state.period; } diff --git a/vg_log.h b/vg_log.h index d30e7ba..5a6ab89 100644 --- a/vg_log.h +++ b/vg_log.h @@ -16,9 +16,9 @@ #define KCYN "\x1B[36m" #define KWHT "\x1B[37m" -#define PRINTF_v2f( V2 ) "%.2f %.2f\n", V2[0], V2[1] -#define PRINTF_v3f( V3 ) "%.2f %.2f %.2f\n", V3[0], V3[1], V3[2] -#define PRINTF_v4f( V4 ) "%.2f %.2f %.2f %.2f\n", V4[0], V4[1], V4[2], V4[3] +#define PRINTF_v2f( V2 ) "%.4f %.4f\n", V2[0], V2[1] +#define PRINTF_v3f( V3 ) "%.4f %.4f %.4f\n", V3[0], V3[1], V3[2] +#define PRINTF_v4f( V4 ) "%.4f %.4f %.4f %.4f\n", V4[0], V4[1], V4[2], V4[3] #ifdef VG_GAME static SDL_SpinLock log_print_sl; diff --git a/vg_m.h b/vg_m.h index 4429aa7..2a5082d 100644 --- a/vg_m.h +++ b/vg_m.h @@ -1386,8 +1386,7 @@ static inline void q_inv( v4f q, v4f d ) static inline void q_nlerp( v4f a, v4f b, float t, v4f d ) { - if( v4_dot(a,b) < 0.0f ) - { + if( v4_dot(a,b) < 0.0f ){ v4_muls( b, -1.0f, d ); v4_lerp( a, d, t, d ); } diff --git a/vg_perlin.h b/vg_perlin.h new file mode 100644 index 0000000..6047620 --- /dev/null +++ b/vg_perlin.h @@ -0,0 +1,155 @@ +#ifndef PERLIN_H +#define PERLIN_H + +#include "vg/vg_m.h" + +static int perlin_hash[] = { +0x46,0xD5,0xB8,0xD3,0xF2,0xE5,0xCC,0x07,0xD0,0xB3,0x7A,0xA2,0xC3,0xDA,0xDC,0x7F, +0xE0,0xB7,0x42,0xA0,0xBF,0x41,0x92,0x32,0x6F,0x0D,0x45,0xC7,0x54,0xDB,0x30,0xC2, +0xD5,0xDA,0x55,0x09,0xDE,0x74,0x48,0x20,0xE1,0x24,0x5C,0x4D,0x6F,0x36,0xD8,0xE9, +0x8D,0x8F,0x54,0x99,0x98,0x51,0xFE,0xDB,0x26,0x04,0x65,0x57,0x56,0xF3,0x53,0x30, +0x3D,0x16,0xC0,0xB6,0xF2,0x47,0xCF,0x62,0xB0,0x6C,0x8F,0x4F,0x8C,0x4C,0x17,0xF0, +0x19,0x7E,0x2D,0x81,0x8D,0xFB,0x10,0xD3,0x49,0x50,0x60,0xFD,0x38,0x15,0x3B,0xEE, +0x05,0xC1,0xCF,0x62,0x97,0x75,0xDF,0x4E,0x4D,0x89,0x5E,0x88,0x5C,0x30,0x8C,0x54, +0x1D,0x39,0x41,0xEA,0xA2,0x63,0x12,0x1B,0x8E,0x35,0x22,0x9B,0x98,0xA3,0x7F,0x80, +0xD6,0x27,0x94,0x66,0xB5,0x1D,0x7E,0xDF,0x96,0x28,0x38,0x3A,0xA0,0xE8,0x71,0x09, +0x62,0x5E,0x9D,0x53,0x58,0x1B,0x7D,0x0D,0x2D,0x99,0x77,0x83,0xC3,0x89,0xC2,0xA2, +0xA7,0x1D,0x78,0x80,0x37,0xC1,0x87,0xFF,0x65,0xBF,0x2C,0xF1,0xE5,0xB3,0x09,0xE0, +0x25,0x92,0x83,0x0F,0x8A,0x57,0x3C,0x0B,0xC6,0xBC,0x44,0x16,0xE3,0xCE,0xC3,0x0D, +0x69,0xD3,0xC6,0x99,0xB8,0x46,0x44,0xC4,0xF3,0x1E,0xBF,0xF5,0xB4,0xDB,0xFB,0x93, +0xA1,0x7B,0xC9,0x08,0x77,0x22,0xE5,0x02,0xEF,0x9E,0x90,0x94,0x8A,0xA6,0x3D,0x7E, +0xA2,0xA0,0x10,0x82,0x47,0x5C,0xAA,0xF8,0x2F,0x0D,0x9F,0x76,0xDA,0x99,0x0F,0xCB, +0xE2,0x02,0x0C,0x75,0xCA,0x35,0x29,0xA6,0x49,0x83,0x6D,0x91,0xB4,0xEC,0x31,0x69, +0xBA,0x13,0xF3,0xC7,0x21,0x06,0xC8,0x79,0xEF,0xB1,0x9C,0x6A,0xEE,0x64,0x9A,0xDC, +0x1E,0xC6,0x18,0x93,0xA9,0x7E,0x89,0x7D,0x96,0xE5,0x44,0xB8,0x00,0x15,0xAF,0x8C, +0x78,0x8F,0xA8,0x05,0xA7,0x07,0x25,0x9A,0xC8,0x5D,0x90,0x1A,0x41,0x53,0x30,0xD3, +0x24,0x33,0x71,0xB4,0x50,0x6E,0xE4,0xEA,0x0D,0x2B,0x6D,0xF5,0x17,0x08,0x74,0x49, +0x71,0xC2,0xAC,0xF7,0xDC,0xB2,0x7E,0xCC,0xB6,0x1B,0xB8,0xA9,0x52,0xCF,0x6B,0x51, +0xD2,0x4E,0xC9,0x43,0xEE,0x2E,0x92,0x24,0xBB,0x47,0x4D,0x0C,0x3E,0x21,0x53,0x19, +0xD4,0x82,0xE2,0xC6,0x93,0x85,0x0A,0xF8,0xFA,0x04,0x07,0xD3,0x1D,0xEC,0x03,0x66, +0xFD,0xB1,0xFB,0x8F,0xC5,0xDE,0xE8,0x29,0xDF,0x23,0x09,0x9D,0x7C,0x43,0x3D,0x4D, +0x89,0xB9,0x6F,0xB4,0x6B,0x4A,0x51,0xC3,0x94,0xF4,0x7C,0x5E,0x19,0x87,0x79,0xC1, +0x80,0x0C,0x45,0x12,0xEC,0x95,0xF3,0x31,0x68,0x42,0xE1,0x06,0x57,0x0E,0xA7,0xFB, +0x78,0x96,0x87,0x23,0xA5,0x20,0x7A,0x09,0x3A,0x45,0xE6,0xD9,0x5E,0x6A,0xD6,0xAA, +0x29,0x50,0x92,0x4E,0xD0,0xB5,0x91,0xC2,0x9A,0xCF,0x07,0xFE,0xB2,0x15,0xEB,0xE4, +0x84,0x40,0x14,0x47,0xFA,0x93,0xB9,0x06,0x69,0xDB,0xBD,0x4E,0xEA,0x52,0x9B,0xDE, +0x5B,0x50,0x36,0xAB,0xB3,0x1F,0xD2,0xCD,0x9C,0x13,0x07,0x7E,0x8B,0xED,0x72,0x62, +0x74,0x77,0x3B,0x88,0xAC,0x5B,0x6A,0xBC,0xDA,0x99,0xE8,0x24,0x90,0x5A,0xCA,0x8D, +0x5C,0x2B,0xF8,0xF1,0xE1,0x1D,0x94,0x11,0xEA,0xCC,0x02,0x09,0x1E,0xA2,0x48,0x67, +0x87,0x5A,0x7E,0xC6,0xCC,0xA3,0xFB,0xC5,0x36,0xEB,0x5C,0xE1,0xAF,0x1E,0xBE,0xE7, +0xD8,0x8F,0x70,0xAE,0x42,0x05,0xF5,0xCD,0x2D,0xA2,0xB0,0xFD,0xEF,0x65,0x2C,0x22, +0xCB,0x8C,0x8B,0xAA,0x3D,0x86,0xE2,0xCD,0xBE,0xC3,0x42,0x38,0xE3,0x9C,0x08,0xB5, +0xAE,0xBD,0x54,0x73,0x83,0x70,0x24,0x47,0xCA,0x4C,0x04,0xC4,0xE0,0x1D,0x40,0xED, +0xF4,0x2B,0x50,0x8E,0x97,0xB3,0xF0,0xA6,0x76,0xDB,0x49,0x30,0xE5,0xD9,0x71,0x07, +0xB2,0xF1,0x0F,0xD6,0x77,0xAA,0x72,0xC0,0xAF,0x66,0xD8,0x40,0xC6,0x08,0x19,0x8C, +0xD9,0x8F,0x5A,0x75,0xAC,0xBE,0xC2,0x40,0x5B,0xBD,0x0D,0x1D,0x00,0xAF,0x26,0x5E, +0x78,0x43,0xAA,0xC6,0x4F,0xF3,0xD8,0xE2,0x7F,0x0C,0x1E,0x77,0x4D,0x35,0x96,0x23, +0x32,0x44,0x03,0x8D,0x92,0xE7,0xFD,0x48,0x07,0xD0,0x58,0xFC,0x6D,0xC9,0x91,0x33, +0xF0,0x23,0x45,0xA4,0x29,0xB9,0xF5,0xB0,0x68,0x8F,0x7B,0x59,0x15,0x8E,0xA6,0x66, +0x15,0xA0,0x76,0x9B,0x69,0xCB,0x38,0xA5,0xF4,0xB4,0x6B,0xDC,0x1F,0xAB,0xAE,0x12, +0x77,0xC0,0x8C,0x4A,0x03,0xB9,0x73,0xD3,0x6D,0x52,0xC5,0xF5,0x6E,0x4E,0x4B,0xA3, +0x24,0x02,0x58,0xEE,0x5F,0xF9,0xD6,0xD0,0x1D,0xBC,0xF4,0xB8,0x4F,0xFD,0x4B,0x2D, +0x34,0x77,0x46,0xE5,0xD4,0x33,0x7B,0x9C,0x35,0xCD,0xB0,0x5D,0x06,0x39,0x99,0xEB, +0x0C,0xD0,0x0F,0xF7,0x92,0xB5,0x58,0x5B,0x5E,0x79,0x12,0xF4,0x05,0xF6,0x21,0x07, +0x0B,0x49,0x1A,0xFB,0xD4,0x98,0xC4,0xEF,0x7A,0xD6,0xCA,0xA1,0xDA,0xB3,0x51,0x00, +0x76,0xEC,0x08,0x48,0x40,0x35,0xD7,0x94,0xBE,0xF5,0x7B,0xA4,0x20,0x81,0x5F,0x82, +0xF3,0x6F,0x96,0x24,0x98,0xB6,0x49,0x18,0xC8,0xC5,0x8C,0xD2,0x38,0x7F,0xC4,0xF6, +0xAA,0x87,0xDC,0x73,0x5B,0xA1,0xAF,0xE5,0x3D,0x37,0x6B,0x85,0xED,0x38,0x62,0x7D, +0x57,0xBD,0xCF,0xB5,0x1B,0xA8,0xBB,0x32,0x33,0xD3,0x34,0x5A,0xC1,0x5D,0xFB,0x28, +0x6E,0xE1,0x67,0x51,0xBB,0x31,0x92,0x83,0xAC,0xAA,0x72,0x52,0xFD,0x13,0x4F,0x73, +0xD3,0xF0,0x5E,0xFC,0xBA,0xB1,0x3C,0x7B,0x08,0x76,0x03,0x38,0x1E,0xD1,0xCC,0x33, +0xA3,0x1E,0xFC,0xE0,0x82,0x30,0x27,0x93,0x71,0x35,0x75,0x77,0xBA,0x78,0x10,0x33, +0xCD,0xAB,0xCF,0x8E,0xAD,0xF9,0x32,0xC9,0x15,0x9F,0xD6,0x6D,0xA8,0xAE,0xB1,0x3F, +0x90,0xEB,0xD4,0xF9,0x31,0x81,0xA3,0x53,0x99,0x4B,0x3C,0x93,0x3B,0xFE,0x55,0xFF, +0x25,0x9F,0xCC,0x07,0xC5,0x2C,0x14,0xA7,0xA4,0x1E,0x6C,0xB6,0x91,0x2A,0xE0,0x3E, +0x7F,0x39,0x0A,0xD9,0x24,0x3C,0x01,0xA0,0x30,0x99,0x8E,0xB8,0x1D,0xF9,0xA7,0x78, +0x86,0x95,0x35,0x0E,0x21,0xDA,0x7A,0x7B,0xAD,0x9F,0x4E,0xF6,0x63,0x5B,0x96,0xBB, +0x87,0x36,0x3F,0xA7,0x1A,0x66,0x91,0xCD,0xB0,0x3B,0xC0,0x4F,0x54,0xD2,0x5F,0xBB, +0x38,0x89,0x1C,0x79,0x7E,0xA2,0x02,0xE4,0x80,0x84,0x1E,0x33,0xAB,0x74,0xFA,0xBE, +0x31,0x46,0x2E,0xC5,0x15,0xB9,0x12,0xE9,0xD3,0x73,0x43,0xEA,0x74,0x11,0xA7,0xC0, +0xD5,0xD8,0x39,0x08,0x9F,0x4F,0xC7,0x71,0x25,0x09,0x51,0x65,0xD6,0xA8,0x02,0x1F +}; + +// Note: Hash must be power of 2! +#define PERLIN_HASH_LENGTH 1024 +#define PERLIN_HASH_MASK (PERLIN_HASH_LENGTH-1) + +static int perlin_noise2( int x, int y, int seed ) +{ + return perlin_hash[ (perlin_hash[(y+seed) & PERLIN_HASH_MASK] + x) + & PERLIN_HASH_MASK ]; +} + +static int perlin_noise1( int i, int seed ) +{ + return perlin_hash[ (seed + i) & PERLIN_HASH_MASK ]; +} + +static float perlin_smooth( float x, float y, float t ) +{ + return vg_lerpf( x, y, t*t*(3.0f-2.0f*t) ); +} + +static float perlin_noise2d( float x, float y, int seed ) +{ + int ix = x, iy = y; + float x_frac = x - ix, + y_frac = y - iy; + + int s = perlin_noise2( ix, iy, seed ), + t = perlin_noise2( ix+1, iy, seed ), + u = perlin_noise2( ix, iy+1, seed ), + v = perlin_noise2( ix+1, iy+1, seed ); + + float low = perlin_smooth( s,t,x_frac ), + high = perlin_smooth( u,v,x_frac ); + + return perlin_smooth( low, high, y_frac ); +} + +static float perlin_noise( float v, int seed ) +{ + int iv = v; + float frac = v-iv; + int s = perlin_noise1( iv, seed ), + t = perlin_noise1( iv+1, seed ); + + return perlin_smooth( s, t, frac ); +} + +static float perlin1d( float v, float freq, int octaves, int seed ) +{ + float xa = v*freq, + amp = 1.0f, + fin = 0.f, + div = 0.f; + + for( int i=0; i