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