everything
[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 #include "rigidbody.h"
12 #include "gate.h"
13
14 #include "shaders/standard.h"
15
16 static struct gworld
17 {
18 scene geo, foliage;
19 submodel sm_road, sm_terrain;
20 glmesh skybox;
21
22 v3f tutorial;
23
24 #if 0
25 rigidbody box;
26 #endif
27
28 teleport_gate gates[16];
29 u32 gate_count;
30
31 rigidbody temp_rbs[32];
32 u32 rb_count;
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 bvh_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 bvh_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 #if 0
161 scene_add_foliage( &world.foliage, mworld, boxtest, world.box.to_world );
162 #endif
163
164
165 #if 0
166 submodel *boxtest = submodel_get( mworld, "cubey" );
167
168 #endif
169
170 for( int i=0; i<mworld->layer_count; i++ )
171 {
172 submodel *sm = model_get_submodel( mworld, i );
173 if( !strcmp( sm->material, "surf" ) ||
174 !strcmp( sm->material, "terrain" ) ||
175 !strcmp( sm->material, "water" ) )
176 continue;
177
178 m4x3f transform;
179 q_m3x3( sm->q, transform );
180 v3_copy( sm->pivot, transform[3] );
181 scene_add_foliage( &world.foliage, mworld, sm, transform );
182
183 rigidbody *rb = &world.temp_rbs[ world.rb_count ++ ];
184
185 box_copy( sm->bbx, rb->bbx );
186 v3_copy( sm->pivot, rb->co );
187 rb_init( rb );
188 v4_copy( sm->q, rb->q );
189 rb_update_transform( rb );
190 }
191
192
193 free( mworld );
194
195 v3f volume;
196 v3_sub( world.geo.bbx[1], world.geo.bbx[0], volume );
197 volume[1] = 1.0f;
198
199 m4x3f transform;
200
201 submodel *sm_blob = submodel_get( mfoliage, "blob" ),
202 *sm_tree = submodel_get( mfoliage, "tree" );
203
204 for( int i=0;i<100000;i++ )
205 {
206 v3f pos;
207 v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
208 v3_add( pos, world.geo.bbx[0], pos );
209
210 ray_hit hit;
211 hit.dist = INFINITY;
212
213 if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
214 {
215 if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) &&
216 hit.pos[1] > wrender.height )
217 {
218 v4f qsurface, qrandom;
219 v3f axis;
220
221 v3_cross( (v3f){0.0f,1.0f,0.0f}, hit.normal, axis );
222
223 float angle = v3_dot(hit.normal,(v3f){0.0f,1.0f,0.0f});
224 q_axis_angle( qsurface, axis, angle );
225 q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf()*VG_TAUf );
226 q_mul( qsurface, qrandom, qsurface );
227 q_m3x3( qsurface, transform );
228
229 v3_copy( hit.pos, transform[3] );
230
231 if( vg_randf() < 0.00000006f )
232 {
233 m3x3_identity( transform );
234 scene_add_foliage( &world.foliage, mfoliage, sm_tree, transform);
235 }
236 else
237 scene_add_foliage( &world.foliage, mfoliage, sm_blob, transform);
238 }
239 }
240 }
241
242 free( mfoliage );
243 scene_upload( &world.foliage );
244 }
245
246 #endif /* WORLD_H */