the walk manifold is alive
[carveJwlIkooP6JGAAIwe30JlM.git] / world.h
1 #ifndef WORLD_H
2 #define WORLD_H
3
4 #define VG_3D
5 #include "vg/vg.h"
6
7 #include "scene.h"
8 #include "terrain.h"
9 #include "render.h"
10 #include "water.h"
11
12 #include "shaders/standard.h"
13
14 static struct gworld
15 {
16 scene geo, foliage;
17 submodel sm_road, sm_terrain;
18 glmesh skybox;
19
20 v3f tutorial;
21 }
22 world;
23
24 static void render_world( m4x4f projection, m4x3f camera )
25 {
26 render_sky( camera );
27
28 m4x3f identity_matrix;
29 m4x3_identity( identity_matrix );
30
31 render_terrain( projection, camera[3] );
32 scene_bind( &world.geo );
33 scene_draw( &world.geo );
34
35 glDisable(GL_CULL_FACE);
36 scene_bind( &world.foliage );
37 scene_draw( &world.foliage );
38 glEnable(GL_CULL_FACE);
39 }
40
41 static void ray_world_get_tri( ray_hit *hit, v3f tri[3] )
42 {
43 for( int i=0; i<3; i++ )
44 v3_copy( world.geo.verts[ hit->tri[i] ].co, tri[i] );
45 }
46
47 static int ray_world( v3f pos, v3f dir, ray_hit *hit )
48 {
49 return bvh_raycast( &world.geo, pos, dir, hit );
50 }
51
52 static int ray_hit_is_ramp( ray_hit *hit )
53 {
54 return hit->tri[0] < world.sm_road.vertex_count;
55 }
56
57 static void world_load(void)
58 {
59 /* Setup scene */
60 scene_init( &world.geo );
61 model *mworld = vg_asset_read( "models/mp_dev.mdl" );
62
63 scene_add_model( &world.geo, mworld, submodel_get( mworld, "mp_dev" ),
64 (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
65 scene_copy_slice( &world.geo, &world.sm_road );
66
67 scene_add_model( &world.geo, mworld, submodel_get( mworld, "terrain" ),
68 (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
69 scene_copy_slice( &world.geo, &world.sm_terrain );
70
71 v3_copy( model_marker_get( mworld, "mp_dev_tutorial" )->co, world.tutorial );
72
73
74 /* GATE DEV */
75 #if 0
76 {
77 model_marker *ga = model_marker_get(mworld,"gate_a"),
78 *gb = model_marker_get(mworld,"gate_a_recv");
79
80 v3_copy( ga->co, gate_a.co );
81 v3_copy( gb->co, gate_b.co );
82 v4_copy( ga->q, gate_a.q );
83 v4_copy( gb->q, gate_b.q );
84 v2_copy( ga->s, gate_a.dims );
85 v2_copy( gb->s, gate_b.dims );
86
87 gate_a.other = &gate_b;
88 gate_b.other = &gate_a;
89
90 gate_transform_update( &gate_a );
91 gate_transform_update( &gate_b );
92 }
93 #endif
94
95 /* WATER DEV */
96 {
97 glmesh surf;
98 submodel *sm = submodel_get(mworld,"mp_dev_water");
99 model_unpack_submodel( mworld, &surf, sm );
100
101 water_init();
102 water_set_surface( &surf, sm->pivot[1] );
103 }
104
105 free( mworld );
106 scene_upload( &world.geo );
107 bvh_create( &world.geo );
108
109 water_compute_depth( world.geo.bbx );
110
111 scene_init( &world.foliage );
112 model *mfoliage = vg_asset_read("models/rs_foliage.mdl");
113
114 v3f volume;
115 v3_sub( world.geo.bbx[1], world.geo.bbx[0], volume );
116 volume[1] = 1.0f;
117
118 m4x3f transform;
119
120 submodel *sm_blob = submodel_get( mfoliage, "blob" ),
121 *sm_tree = submodel_get( mfoliage, "tree" );
122
123 for( int i=0;i<100000;i++ )
124 {
125 v3f pos;
126 v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
127 v3_add( pos, world.geo.bbx[0], pos );
128
129 ray_hit hit;
130 hit.dist = INFINITY;
131
132 if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
133 {
134 if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) &&
135 hit.pos[1] > wrender.height )
136 {
137 v4f qsurface, qrandom;
138 v3f axis;
139
140 v3_cross( (v3f){0.0f,1.0f,0.0f}, hit.normal, axis );
141
142 float angle = v3_dot(hit.normal,(v3f){0.0f,1.0f,0.0f});
143 q_axis_angle( qsurface, axis, angle );
144 q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf()*VG_TAUf );
145 q_mul( qsurface, qrandom, qsurface );
146 q_m3x3( qsurface, transform );
147
148 v3_copy( hit.pos, transform[3] );
149
150 if( vg_randf() < 0.00000006f )
151 {
152 m3x3_identity( transform );
153 scene_add_foliage( &world.foliage, mfoliage, sm_tree, transform );
154 }
155 else
156 scene_add_foliage( &world.foliage, mfoliage, sm_blob, transform );
157 }
158 }
159 }
160
161 free( mfoliage );
162 scene_upload( &world.foliage );
163 }
164
165 #endif /* WORLD_H */