bvh interface and high perf gate
[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 #include "bvh.h"
14
15 #include "shaders/standard.h"
16
17 static struct gworld
18 {
19 scene geo, foliage;
20 submodel sm_road, sm_terrain;
21 glmesh skybox;
22
23 v3f tutorial;
24
25 #if 0
26 rigidbody box;
27 #endif
28
29 teleport_gate gates[16];
30 u32 gate_count;
31
32 rigidbody temp_rbs[32];
33 u32 rb_count;
34
35 bh_tree bhcubes;
36 }
37 world;
38
39
40
41 static void render_world( m4x4f projection, m4x3f camera )
42 {
43 render_sky( camera );
44
45 m4x3f identity_matrix;
46 m4x3_identity( identity_matrix );
47
48 render_terrain( projection, camera[3] );
49 scene_bind( &world.geo );
50 scene_draw( &world.geo );
51
52 glDisable(GL_CULL_FACE);
53 scene_bind( &world.foliage );
54 scene_draw( &world.foliage );
55 glEnable(GL_CULL_FACE);
56 }
57
58 static void ray_world_get_tri( ray_hit *hit, v3f tri[3] )
59 {
60 for( int i=0; i<3; i++ )
61 v3_copy( world.geo.verts[ hit->tri[i] ].co, tri[i] );
62 }
63
64 static int ray_world( v3f pos, v3f dir, ray_hit *hit )
65 {
66 return bvh_raycast( &world.geo, pos, dir, hit );
67 }
68
69 static int ray_hit_is_ramp( ray_hit *hit )
70 {
71 return hit->tri[0] < world.sm_road.vertex_count;
72 }
73
74 static bh_system bh_system_rigidbodies;
75 static void world_load(void)
76 {
77 /* Setup scene */
78 scene_init( &world.geo );
79 model *mworld = vg_asset_read( "models/mp_dev.mdl" );
80
81 for( int i=0; i<mworld->layer_count; i++ )
82 {
83 submodel *sm = model_get_submodel( mworld, i );
84 if( !strcmp( sm->material, "surf" ) )
85 scene_add_model( &world.geo, mworld, sm, sm->pivot, 0.0f, 1.0f );
86
87 }
88 scene_copy_slice( &world.geo, &world.sm_road );
89
90 for( int i=0; i<mworld->layer_count; i++ )
91 {
92 submodel *sm = model_get_submodel( mworld, i );
93 if( !strcmp( sm->material, "terrain" ) )
94 scene_add_model( &world.geo, mworld, sm, sm->pivot, 0.0f, 1.0f );
95 }
96
97 scene_copy_slice( &world.geo, &world.sm_terrain );
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 break;
149 }
150 }
151
152 scene_upload( &world.geo );
153 bvh_create( &world.geo );
154
155 water_compute_depth( world.geo.bbx );
156
157 scene_init( &world.foliage );
158 model *mfoliage = vg_asset_read("models/rs_foliage.mdl");
159
160 /*
161 * TODO: Load any other meshes into the foliage scene, and create rbs for
162 * them.
163 *
164 * then compute bvh
165 */
166
167 for( int i=0; i<mworld->layer_count; i++ )
168 {
169 submodel *sm = model_get_submodel( mworld, i );
170 if( !strcmp( sm->material, "surf" ) ||
171 !strcmp( sm->material, "terrain" ) ||
172 !strcmp( sm->material, "water" ) )
173 continue;
174
175 m4x3f transform;
176 q_m3x3( sm->q, transform );
177 v3_copy( sm->pivot, transform[3] );
178 scene_add_foliage( &world.foliage, mworld, sm, transform );
179
180 rigidbody *rb = &world.temp_rbs[ world.rb_count ++ ];
181
182 box_copy( sm->bbx, rb->bbx );
183 v3_copy( sm->pivot, rb->co );
184 rb_init( rb );
185 v4_copy( sm->q, rb->q );
186 rb_update_transform( rb );
187 }
188
189 free( mworld );
190
191 v3f volume;
192 v3_sub( world.geo.bbx[1], world.geo.bbx[0], volume );
193 volume[1] = 1.0f;
194
195 m4x3f transform;
196
197 submodel *sm_blob = submodel_get( mfoliage, "blob" ),
198 *sm_tree = submodel_get( mfoliage, "tree" );
199
200 for( int i=0;i<100000;i++ )
201 {
202 v3f pos;
203 v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
204 v3_add( pos, world.geo.bbx[0], pos );
205
206 ray_hit hit;
207 hit.dist = INFINITY;
208
209 if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
210 {
211 if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) &&
212 hit.pos[1] > wrender.height )
213 {
214 v4f qsurface, qrandom;
215 v3f axis;
216
217 v3_cross( (v3f){0.0f,1.0f,0.0f}, hit.normal, axis );
218
219 float angle = v3_dot(hit.normal,(v3f){0.0f,1.0f,0.0f});
220 q_axis_angle( qsurface, axis, angle );
221 q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf()*VG_TAUf );
222 q_mul( qsurface, qrandom, qsurface );
223 q_m3x3( qsurface, transform );
224
225 v3_copy( hit.pos, transform[3] );
226
227 if( vg_randf() < 0.00000006f )
228 {
229 m3x3_identity( transform );
230 scene_add_foliage( &world.foliage, mfoliage, sm_tree, transform);
231 }
232 else
233 scene_add_foliage( &world.foliage, mfoliage, sm_blob, transform);
234 }
235 }
236 }
237
238 free( mfoliage );
239 scene_upload( &world.foliage );
240
241 world.bhcubes.user = world.temp_rbs;
242 bh_create( &world.bhcubes, &bh_system_rigidbodies, world.rb_count );
243 }
244
245 #endif /* WORLD_H */