add player guide
[carveJwlIkooP6JGAAIwe30JlM.git] / world_physics.c
1 #ifndef WORLD_PHYSICS_C
2 #define WORLD_PHYSICS_C
3
4 #include "world.h"
5 #include "world_physics.h"
6
7 VG_STATIC void ray_world_get_tri( world_instance *world,
8 ray_hit *hit, v3f tri[3] )
9 {
10 for( int i=0; i<3; i++ )
11 v3_copy( world->scene_geo.arrvertices[ hit->tri[i] ].co, tri[i] );
12 }
13
14 VG_STATIC int ray_world( world_instance *world,
15 v3f pos, v3f dir, ray_hit *hit )
16 {
17 return scene_raycast( &world->scene_geo, world->geo_bh, pos, dir, hit );
18 }
19
20 /*
21 * Cast a sphere from a to b and see what time it hits
22 */
23 VG_STATIC int spherecast_world( world_instance *world,
24 v3f pa, v3f pb, float r, float *t, v3f n )
25 {
26 boxf region;
27 box_init_inf( region );
28 box_addpt( region, pa );
29 box_addpt( region, pb );
30
31 v3_add( (v3f){ r, r, r}, region[1], region[1] );
32 v3_add( (v3f){-r,-r,-r}, region[0], region[0] );
33
34 v3f dir;
35 v3_sub( pb, pa, dir );
36
37 v3f dir_inv;
38 dir_inv[0] = 1.0f/dir[0];
39 dir_inv[1] = 1.0f/dir[1];
40 dir_inv[2] = 1.0f/dir[2];
41
42 int hit = -1;
43 float min_t = 1.0f;
44
45 bh_iter it;
46 bh_iter_init_box( 0, &it, region );
47 i32 idx;
48 while( bh_next( world->geo_bh, &it, &idx ) ){
49 u32 *ptri = &world->scene_geo.arrindices[ idx*3 ];
50 v3f tri[3];
51
52 boxf box;
53 box_init_inf( box );
54
55 for( int j=0; j<3; j++ ){
56 v3_copy( world->scene_geo.arrvertices[ptri[j]].co, tri[j] );
57 box_addpt( box, tri[j] );
58 }
59
60 v3_add( (v3f){ r, r, r}, box[1], box[1] );
61 v3_add( (v3f){-r,-r,-r}, box[0], box[0] );
62
63 if( !ray_aabb1( box, pa, dir_inv, 1.0f ) )
64 continue;
65
66 float t;
67 v3f n1;
68 if( spherecast_triangle( tri, pa, dir, r, &t, n1 ) ){
69 if( t < min_t ){
70 min_t = t;
71 hit = idx;
72 v3_copy( n1, n );
73 }
74 }
75 }
76
77 *t = min_t;
78 return hit;
79 }
80
81 VG_STATIC
82 struct world_surface *world_tri_index_surface( world_instance *world,
83 u32 index )
84 {
85 for( int i=1; i<world->surface_count; i++ ){
86 struct world_surface *surf = &world->surfaces[i];
87
88 if( (index >= surf->sm_geo.vertex_start) &&
89 (index < surf->sm_geo.vertex_start+surf->sm_geo.vertex_count ) )
90 {
91 return surf;
92 }
93 }
94
95 return &world->surfaces[0];
96 }
97
98 VG_STATIC struct world_surface *world_contact_surface( world_instance *world,
99 rb_ct *ct )
100 {
101 return world_tri_index_surface( world, ct->element_id );
102 }
103
104 VG_STATIC struct world_surface *ray_hit_surface( world_instance *world,
105 ray_hit *hit )
106 {
107 return world_tri_index_surface( world, hit->tri[0] );
108 }
109
110 #endif /* WORLD_PHYSICS_C */