audio&island
[carveJwlIkooP6JGAAIwe30JlM.git] / world.h
1 #include "common.h"
2
3 static int ray_world( v3f pos, v3f dir, ray_hit *hit );
4
5 #ifndef WORLD_H
6 #define WORLD_H
7
8 #include "scene.h"
9 #include "terrain.h"
10 #include "render.h"
11 #include "water.h"
12 #include "rigidbody.h"
13 #include "gate.h"
14 #include "bvh.h"
15
16 #include "shaders/standard.h"
17
18 static struct gworld
19 {
20 scene geo, foliage;
21 submodel sm_road, sm_terrain;
22 glmesh skybox;
23
24 v3f tutorial;
25
26 teleport_gate gates[64];
27 u32 gate_count;
28
29 rigidbody temp_rbs[128];
30 u32 rb_count;
31
32 bh_tree bhcubes;
33 }
34 world;
35
36 static void render_world( m4x4f projection, m4x3f camera )
37 {
38 render_sky( camera );
39
40 m4x3f identity_matrix;
41 m4x3_identity( identity_matrix );
42
43 render_terrain( projection, camera[3] );
44 scene_bind( &world.geo );
45 scene_draw( &world.geo );
46
47 glDisable(GL_CULL_FACE);
48 scene_bind( &world.foliage );
49 scene_draw( &world.foliage );
50 glEnable(GL_CULL_FACE);
51
52 vg_line_boxf( world.geo.bbx, 0xff00ff00 );
53 }
54
55 static void ray_world_get_tri( ray_hit *hit, v3f tri[3] )
56 {
57 for( int i=0; i<3; i++ )
58 v3_copy( world.geo.verts[ hit->tri[i] ].co, tri[i] );
59 }
60
61 static int ray_world( v3f pos, v3f dir, ray_hit *hit )
62 {
63 return scene_raycast( &world.geo, pos, dir, hit );
64 }
65
66 static int ray_hit_is_ramp( ray_hit *hit )
67 {
68 return hit->tri[0] < world.sm_road.vertex_count;
69 }
70
71 static void world_load(void)
72 {
73 /* Setup scene */
74 scene_init( &world.geo );
75 model *mworld = vg_asset_read( "models/mp_dev.mdl" );
76
77 for( int i=0; i<mworld->layer_count; i++ )
78 {
79 submodel *sm = model_get_submodel( mworld, i );
80 if( !strcmp( sm->material, "surf" ) )
81 scene_add_model( &world.geo, mworld, sm, sm->pivot, 0.0f, 1.0f );
82
83 }
84 scene_copy_slice( &world.geo, &world.sm_road );
85
86 for( int i=0; i<mworld->layer_count; i++ )
87 {
88 submodel *sm = model_get_submodel( mworld, i );
89 if( !strcmp( sm->material, "terrain" ) )
90 scene_add_model( &world.geo, mworld, sm, sm->pivot, 0.0f, 1.0f );
91 }
92
93 scene_copy_slice( &world.geo, &world.sm_terrain );
94
95 vg_info( "BBX: %.3f %.3f %.3f -> %.3f %.3f %.3f\n",
96 world.geo.bbx[0][0], world.geo.bbx[0][1], world.geo.bbx[0][2],
97 world.geo.bbx[1][0], world.geo.bbx[1][1], world.geo.bbx[1][2] );
98
99 /*
100 * TODO: Parametric marker import
101 */
102 v3_copy( model_marker_get( mworld, "start" )->co, world.tutorial );
103
104 /*
105 * Initialize gates
106 */
107
108 world.gate_count = 0;
109 for( int i=0; i<mworld->marker_count; i++ )
110 {
111 model_marker *ga = model_get_marker( mworld, i );
112
113 if( ga->classtype == k_classtype_gate )
114 {
115 struct classtype_gate *data = get_entdata_raw( mworld, ga );
116
117 if( data->target )
118 {
119 model_marker *gb = model_get_marker( mworld, data->target );
120
121 teleport_gate *gate = &world.gates[ world.gate_count ++ ];
122
123 v3_copy( ga->co, gate->co[0] );
124 v3_copy( gb->co, gate->co[1] );
125 v4_copy( ga->q, gate->q[0] );
126 v4_copy( gb->q, gate->q[1] );
127 v2_copy( ga->s, gate->dims );
128
129 gate_transform_update( gate );
130 }
131 }
132 }
133
134 /*
135 * Load water mesh (1 per world)
136 */
137 for( int i=0; i<mworld->layer_count; i++ )
138 {
139 submodel *sm = model_get_submodel( mworld, i );
140 if( !strcmp( sm->material, "water" ) )
141 {
142 glmesh surf;
143 model_unpack_submodel( mworld, &surf, sm );
144
145 water_init();
146 water_set_surface( &surf, sm->pivot[1] );
147
148 vg_info( "%.3f\n", sm->pivot[1] );
149
150 break;
151 }
152 }
153
154 scene_upload( &world.geo );
155 scene_bh_create( &world.geo );
156
157 water_compute_depth( world.geo.bbx );
158
159 scene_init( &world.foliage );
160 model *mfoliage = vg_asset_read("models/rs_foliage.mdl");
161
162 /*
163 * TODO: Load any other meshes into the foliage scene, and create rbs for
164 * them.
165 *
166 * then compute bvh
167 */
168
169 for( int i=0; i<mworld->layer_count; i++ )
170 {
171 submodel *sm = model_get_submodel( mworld, i );
172 if( !strcmp( sm->material, "surf" ) ||
173 !strcmp( sm->material, "terrain" ) ||
174 !strcmp( sm->material, "water" ) )
175 continue;
176
177 m4x3f transform;
178 q_m3x3( sm->q, transform );
179 v3_copy( sm->pivot, transform[3] );
180 scene_add_foliage( &world.foliage, mworld, sm, transform );
181
182 rigidbody *rb = &world.temp_rbs[ world.rb_count ++ ];
183
184 box_copy( sm->bbx, rb->bbx );
185 v3_copy( sm->pivot, rb->co );
186 rb_init( rb );
187 v4_copy( sm->q, rb->q );
188 rb_update_transform( rb );
189 }
190
191 free( mworld );
192
193 v3f volume;
194 v3_sub( world.geo.bbx[1], world.geo.bbx[0], volume );
195 volume[1] = 1.0f;
196
197 m4x3f transform;
198
199 submodel *sm_blob = submodel_get( mfoliage, "blob" ),
200 *sm_tree = submodel_get( mfoliage, "tree" );
201
202 for( int i=0;i<100000;i++ )
203 {
204 v3f pos;
205 v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
206 pos[1] = 1000.0f;
207 v3_add( pos, world.geo.bbx[0], pos );
208
209 ray_hit hit;
210 hit.dist = INFINITY;
211
212 if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
213 {
214 if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) &&
215 hit.pos[1] > water_height()+10.0f )
216 {
217 v4f qsurface, qrandom;
218 v3f axis;
219
220 v3_cross( (v3f){0.0f,1.0f,0.0f}, hit.normal, axis );
221
222 float angle = v3_dot(hit.normal,(v3f){0.0f,1.0f,0.0f});
223 q_axis_angle( qsurface, axis, angle );
224 q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf()*VG_TAUf );
225 q_mul( qsurface, qrandom, qsurface );
226 q_m3x3( qsurface, transform );
227
228 v3_copy( hit.pos, transform[3] );
229
230 if( vg_randf() < 0.0006f )
231 {
232 m3x3_identity( transform );
233 scene_add_foliage( &world.foliage, mfoliage, sm_tree, transform);
234 }
235 else
236 scene_add_foliage( &world.foliage, mfoliage, sm_blob, transform);
237 }
238 }
239 }
240
241 free( mfoliage );
242 scene_upload( &world.foliage );
243
244 bh_create( &world.bhcubes,
245 &bh_system_rigidbodies, world.temp_rbs, world.rb_count );
246 }
247
248 #endif /* WORLD_H */