TODO about preupdate call style
[carveJwlIkooP6JGAAIwe30JlM.git] / ent_tornado.c
1 #include "world.h"
2 #include "particle.h"
3
4 static f32 k_tornado_strength = 0.0f,
5 k_tornado_ratio = 0.5f,
6 k_tornado_range = 10.f;
7
8 void ent_tornado_init(void)
9 {
10 vg_console_reg_var( "k_tonado_strength", &k_tornado_strength,
11 k_var_dtype_f32, VG_VAR_PERSISTENT|VG_VAR_CHEAT );
12 vg_console_reg_var( "k_tonado_ratio", &k_tornado_ratio,
13 k_var_dtype_f32, VG_VAR_PERSISTENT|VG_VAR_CHEAT );
14 vg_console_reg_var( "k_tonado_range", &k_tornado_range,
15 k_var_dtype_f32, VG_VAR_PERSISTENT|VG_VAR_CHEAT );
16 }
17
18 void ent_tornado_debug(void)
19 {
20 world_instance *world = world_current_instance();
21 for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
22 ent_marker *marker = mdl_arritm( &world->ent_marker, i );
23
24 if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
25 v3f p1;
26 v3_add( marker->transform.co, (v3f){0,20,0}, p1 );
27 vg_line( marker->transform.co, p1, VG__RED );
28
29 m4x3f mmdl;
30 m4x3_identity( mmdl );
31 v3_copy( marker->transform.co, mmdl[3] );
32 vg_line_sphere( mmdl, k_tornado_range, 0 );
33 }
34 }
35 }
36
37 void ent_tornado_forces( v3f co, v3f cv, v3f out_a )
38 {
39 world_instance *world = world_current_instance();
40 v3_zero( out_a );
41
42 for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
43 ent_marker *marker = mdl_arritm( &world->ent_marker, i );
44
45 if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
46 v3f d, dir;
47 v3_sub( co, marker->transform.co, d );
48 d[1] = 0.0f;
49
50 f32 dist = v3_length( d );
51 v3_normalize( d );
52
53 v3_cross( d, (v3f){0,1,0}, dir );
54 if( v3_dot( dir, cv ) < 0.0f )
55 v3_negate( dir, dir );
56
57 f32 s = vg_maxf(0.0f, 1.0f-dist/k_tornado_range),
58 F0 = s*k_tornado_strength,
59 F1 = s*s*k_tornado_strength;
60
61 v3_muladds( out_a, dir, F0 * k_tornado_ratio, out_a );
62 v3_muladds( out_a, d, F1 * -(1.0f-k_tornado_ratio), out_a );
63 }
64 }
65 }
66
67 void ent_tornado_pre_update(void)
68 {
69 world_instance *world = world_current_instance();
70 for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
71 ent_marker *marker = mdl_arritm( &world->ent_marker, i );
72
73 if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
74 v3f co;
75 vg_rand_sphere( &vg.rand, co );
76
77 v3f tangent = { co[2], 0, co[0] };
78
79 f32 s = vg_signf( co[1] );
80 v3_muls( tangent, s*10.0f, tangent );
81 co[1] *= s;
82
83 v3_muladds( marker->transform.co, co, k_tornado_range, co );
84 particle_spawn( &particles_env, co, tangent, 2.0f, 0xffffffff );
85 }
86 }
87 }