--- /dev/null
+#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 );
+ }
+ }
+}