0cc1ed608929b03aaf094afd49ff4e4cba7cb5ac
[carveJwlIkooP6JGAAIwe30JlM.git] / world_volumes.c
1 #ifndef WORLD_VOLUMES_C
2 #define WORLD_VOLUMES_C
3
4 #include "world_volumes.h"
5
6 static void world_volumes_update( world_instance *world, v3f pos ){
7 /* filter and check the existing ones */
8 u32 j=0;
9 for( u32 i=0; i<world_static.active_trigger_volume_count; i++ ){
10 i32 idx = world_static.active_trigger_volumes[i];
11 ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
12
13 v3f local;
14 m4x3_mulv( volume->to_local, pos, local );
15 if( (fabsf(local[0]) <= 1.0f) &&
16 (fabsf(local[1]) <= 1.0f) &&
17 (fabsf(local[2]) <= 1.0f) )
18 {
19 world_static.active_trigger_volumes[ j ++ ] = idx;
20 boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
21 vg_line_boxf_transformed( volume->to_world, cube, 0xff00ccff );
22 /* triggr on stay ..... */
23 }
24 else{
25 /* trigger on exit...... */
26 }
27 }
28 world_static.active_trigger_volume_count = j;
29
30 static float random_accum = 0.0f;
31 random_accum += vg.time_delta;
32
33 u32 random_ticks = 0;
34
35 while( random_accum > 0.1f ){
36 random_accum -= 0.1f;
37 random_ticks ++;
38 }
39
40 float radius = 25.0f;
41 boxf volume_proximity;
42 v3_add( pos, (v3f){ radius, radius, radius }, volume_proximity[1] );
43 v3_sub( pos, (v3f){ radius, radius, radius }, volume_proximity[0] );
44
45 bh_iter it;
46 bh_iter_init_box( 0, &it, volume_proximity );
47 i32 idx;
48
49 while( bh_next( world->volume_bh, &it, &idx ) ){
50 ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
51
52 boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
53
54 if( volume->type == k_volume_subtype_trigger ){
55 for( u32 i=0; i<world_static.active_trigger_volume_count; i++ )
56 if( world_static.active_trigger_volumes[i] == idx )
57 goto next_volume;
58
59 if( world_static.active_trigger_volume_count >
60 vg_list_size(world_static.active_trigger_volumes) ) continue;
61
62 v3f local;
63 m4x3_mulv( volume->to_local, pos, local );
64
65 if( (fabsf(local[0]) <= 1.0f) &&
66 (fabsf(local[1]) <= 1.0f) &&
67 (fabsf(local[2]) <= 1.0f) )
68 {
69 ent_call basecall;
70 basecall.function = k_ent_function_trigger;
71 basecall.id = mdl_entity_id( k_ent_volume, idx );
72 basecall.data = NULL;
73
74 entity_call( world, &basecall );
75 world_static.active_trigger_volumes[
76 world_static.active_trigger_volume_count ++ ] = idx;
77 }
78 else
79 vg_line_boxf_transformed( volume->to_world, cube, 0xffcccccc );
80 }
81 else if( volume->type == k_volume_subtype_particle ){
82 vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff );
83
84 for( int j=0; j<random_ticks; j++ ){
85 ent_call basecall;
86 basecall.id = mdl_entity_id( k_ent_volume, idx );
87 basecall.data = NULL;
88
89 entity_call( world, &basecall );
90 }
91 }
92 next_volume:;
93 }
94 }
95
96 /*
97 * BVH implementation
98 * ----------------------------------------------------------------------------
99 */
100
101 VG_STATIC void volume_vg_expand_bound( void *user, boxf bound, u32 item_index )
102 {
103 world_instance *world = user;
104
105 ent_volume *volume = mdl_arritm( &world->ent_volume, item_index );
106
107 m4x3_expand_aabb_point( volume->to_world, bound, (v3f){ 1.0f, 1.0f, 1.0f} );
108 m4x3_expand_aabb_point( volume->to_world, bound, (v3f){ 1.0f, 1.0f,-1.0f} );
109 m4x3_expand_aabb_point( volume->to_world, bound, (v3f){ 1.0f,-1.0f, 1.0f} );
110 m4x3_expand_aabb_point( volume->to_world, bound, (v3f){ 1.0f,-1.0f,-1.0f} );
111 m4x3_expand_aabb_point( volume->to_world, bound, (v3f){-1.0f, 1.0f, 1.0f} );
112 m4x3_expand_aabb_point( volume->to_world, bound, (v3f){-1.0f, 1.0f,-1.0f} );
113 m4x3_expand_aabb_point( volume->to_world, bound, (v3f){-1.0f,-1.0f, 1.0f} );
114 m4x3_expand_aabb_point( volume->to_world, bound, (v3f){-1.0f,-1.0f,-1.0f} );
115 }
116
117 VG_STATIC float volume_vg_centroid( void *user, u32 item_index, int axis )
118 {
119 world_instance *world = user;
120 ent_volume *volume = mdl_arritm( &world->ent_volume, item_index );
121 return volume->to_world[3][axis];
122 }
123
124 VG_STATIC void volume_vg_swap( void *user, u32 ia, u32 ib )
125 {
126 world_instance *world = user;
127 ent_volume *a = mdl_arritm( &world->ent_volume, ia ),
128 *b = mdl_arritm( &world->ent_volume, ib ),
129 temp;
130
131 temp = *a;
132 *a = *b;
133 *b = temp;
134 }
135
136 VG_STATIC void volume_vg_debug( void *user, u32 item_index )
137 {
138 world_instance *world = user;
139 ent_volume *volume = mdl_arritm( &world->ent_volume, item_index );
140 vg_line_boxf_transformed( volume->to_world, (boxf){{-1.0f,-1.0f,-1.0f},
141 { 1.0f, 1.0f, 1.0f}},
142 0xff00ff00 );
143 }
144
145 #endif /* WORLD_VOLUMES_H */