sandsurf/glide basics
[carveJwlIkooP6JGAAIwe30JlM.git] / ent_tornado.c
diff --git a/ent_tornado.c b/ent_tornado.c
new file mode 100644 (file)
index 0000000..d59c6b7
--- /dev/null
@@ -0,0 +1,83 @@
+#include "world.h"
+#include "particle.h"
+
+static f32 k_tornado_strength = 0.0f,
+           k_tornado_ratio    = 0.5f,
+           k_tornado_range    = 10.f;
+
+static void ent_tornado_init(void){
+   vg_console_reg_var( "k_tonado_strength", &k_tornado_strength,
+                        k_var_dtype_f32, VG_VAR_PERSISTENT|VG_VAR_CHEAT );
+   vg_console_reg_var( "k_tonado_ratio", &k_tornado_ratio,
+                        k_var_dtype_f32, VG_VAR_PERSISTENT|VG_VAR_CHEAT );
+   vg_console_reg_var( "k_tonado_range", &k_tornado_range,
+                        k_var_dtype_f32, VG_VAR_PERSISTENT|VG_VAR_CHEAT );
+}
+
+static void ent_tornado_debug(void) {
+   world_instance *world = world_current_instance();
+   for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
+      ent_marker *marker = mdl_arritm( &world->ent_marker, i );
+
+      if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
+         v3f p1;
+         v3_add( marker->transform.co, (v3f){0,20,0}, p1 );
+         vg_line( marker->transform.co, p1, VG__RED );
+
+         m4x3f mmdl;
+         m4x3_identity( mmdl );
+         v3_copy( marker->transform.co, mmdl[3] );
+         vg_line_sphere( mmdl, k_tornado_range, 0 );
+      }
+   }
+}
+
+static void ent_tornado_forces( v3f co, v3f cv, v3f out_a ){
+   world_instance *world = world_current_instance();
+   v3_zero( out_a );
+
+   for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
+      ent_marker *marker = mdl_arritm( &world->ent_marker, i );
+
+      if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
+         v3f d, dir;
+         v3_sub( co, marker->transform.co, d );
+         d[1] = 0.0f;
+
+         f32 dist = v3_length( d );
+         v3_normalize( d );
+
+         v3_cross( d, (v3f){0,1,0}, dir );
+         if( v3_dot( dir, cv ) < 0.0f )
+            v3_negate( dir, dir );
+
+         f32  s = vg_maxf(0.0f, 1.0f-dist/k_tornado_range),
+              F0 = s*k_tornado_strength,
+              F1 = s*s*k_tornado_strength;
+
+         v3_muladds( out_a, dir, F0 * k_tornado_ratio, out_a );
+         v3_muladds( out_a, d,   F1 * -(1.0f-k_tornado_ratio), out_a );
+      }
+   }
+}
+
+static void ent_tornado_pre_update(void){
+   world_instance *world = world_current_instance();
+   for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
+      ent_marker *marker = mdl_arritm( &world->ent_marker, i );
+
+      if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
+         v3f co;
+         vg_rand_sphere( &vg.rand, co );
+
+         v3f tangent = { co[2], 0, co[0] };
+
+         f32 s = vg_signf( co[1] );
+         v3_muls( tangent, s*10.0f, tangent );
+         co[1] *= s;
+
+         v3_muladds( marker->transform.co, co, k_tornado_range, co );
+         particle_spawn( &particles_env, co, tangent, 2.0f, 0xffffffff );
+      }
+   }
+}