stuff
[carveJwlIkooP6JGAAIwe30JlM.git] / scene.h
1 #ifndef SCENE_H
2 #define SCENE_H
3
4 #include "common.h"
5 #include "model.h"
6 #include "bvh.h"
7
8 typedef struct scene scene;
9
10 struct scene
11 {
12 glmesh mesh;
13
14 model_vert *verts;
15 u32 *indices;
16
17 bh_tree bhtris;
18 u32 vertex_count,
19 indice_count,
20 vertex_cap,
21 indice_cap;
22
23 boxf bbx;
24
25 u32 shadower_count,
26 shadower_cap;
27
28 submodel submesh;
29 };
30
31 GLuint tex_dual_noise;
32
33 static void scene_init( scene *pscene )
34 {
35 pscene->verts = NULL;
36 pscene->indices = NULL;
37 pscene->vertex_count = 0;
38 pscene->indice_count = 0;
39 pscene->shadower_count = 0;
40 pscene->shadower_cap = 0;
41 pscene->submesh.indice_start = 0;
42 pscene->submesh.indice_count = 0;
43
44 v3_fill( pscene->bbx[0], 999999.9f );
45 v3_fill( pscene->bbx[1], -999999.9f );
46
47 static int noise_ready = 0;
48 if( !noise_ready )
49 {
50 noise_ready = 1;
51
52 u8 *buf = malloc( 256*256*2 );
53
54 for( int i=0; i<256*256; i++ )
55 {
56 u8 val = rand()&0xff;
57 buf[i*2] = val;
58 }
59
60 for( int y=0; y<256; y++ )
61 {
62 for( int x=0; x<256; x++ )
63 {
64 u8 *pr = &buf[(y*256+x)*2],
65 *pg = &buf[(((y+17)&0xff)*256+((x+37)&0xff))*2+1];
66 *pg = *pr;
67 }
68 }
69
70 /* TODO: This texture should be delted somewhere */
71 glGenTextures( 1, &tex_dual_noise );
72 glBindTexture( GL_TEXTURE_2D, tex_dual_noise );
73 glTexImage2D( GL_TEXTURE_2D, 0, GL_RG, 256, 256, 0, GL_RG,
74 GL_UNSIGNED_BYTE, buf );
75
76 vg_tex2d_linear();
77 vg_tex2d_repeat();
78
79 free( buf );
80 }
81 }
82
83 static void *buffer_reserve( void *buffer, u32 count, u32 *cap, u32 amount,
84 size_t emsize )
85 {
86 if( count+amount > *cap )
87 {
88 *cap = VG_MAX( (*cap)*2, (*cap)+amount );
89
90 return realloc( buffer, (*cap) * emsize );
91 }
92
93 return buffer;
94 }
95
96 /*
97 * Append a model into the scene with a given transform
98 */
99 static void scene_add_model( scene *pscene, model *mdl, submodel *submodel,
100 v3f pos, float yaw, float scale )
101 {
102 pscene->verts = buffer_reserve( pscene->verts, pscene->vertex_count,
103 &pscene->vertex_cap, submodel->vertex_count, sizeof(model_vert) );
104 pscene->indices = buffer_reserve( pscene->indices, pscene->indice_count,
105 &pscene->indice_cap, submodel->indice_count, sizeof(u32) );
106
107 /* Transform and place vertices */
108 model_vert *src_verts = submodel_vert_data( mdl, submodel );
109 u32 *src_indices = submodel_indice_data( mdl, submodel );
110
111 m4x3f mtx;
112 m4x3_identity( mtx );
113 m4x3_translate( mtx, pos );
114 m4x3_rotate_y( mtx, yaw );
115 m4x3_scale( mtx, scale );
116
117 boxf bbxnew;
118 box_copy( submodel->bbx, bbxnew );
119 m4x3_transform_aabb( mtx, bbxnew );
120 box_concat( pscene->bbx, bbxnew );
121
122 m3x3f rotation;
123 m4x3_to_3x3( mtx, rotation );
124
125 float rand_hue = vg_randf();
126
127 for( u32 i=0; i<submodel->vertex_count; i++ )
128 {
129 model_vert *pvert = &pscene->verts[ pscene->vertex_count+i ],
130 *src = &src_verts[ i ];
131
132 m4x3_mulv( mtx, src->co, pvert->co );
133 m3x3_mulv( rotation, src->norm, pvert->norm );
134
135 v4_copy( src->colour, pvert->colour );
136 v2_copy( src->uv, pvert->uv );
137
138 float rel_y = src->co[1] / submodel->bbx[1][1];
139 pvert->colour[0] = rel_y;
140 pvert->colour[2] = rand_hue;
141 }
142
143 for( u32 i=0; i<submodel->indice_count; i++ )
144 {
145 u32 *pidx = &pscene->indices[ pscene->indice_count+i ];
146 *pidx = src_indices[i] + pscene->vertex_count;
147 }
148
149 pscene->vertex_count += submodel->vertex_count;
150 pscene->indice_count += submodel->indice_count;
151 }
152
153 static void scene_add_foliage( scene *pscene, model *mdl, submodel *submodel,
154 m4x3f transform )
155 {
156 pscene->verts = buffer_reserve( pscene->verts, pscene->vertex_count,
157 &pscene->vertex_cap, submodel->vertex_count, sizeof(model_vert) );
158 pscene->indices = buffer_reserve( pscene->indices, pscene->indice_count,
159 &pscene->indice_cap, submodel->indice_count, sizeof(u32) );
160
161 /* Transform and place vertices */
162 model_vert *src_verts = submodel_vert_data( mdl, submodel );
163 u32 *src_indices = submodel_indice_data( mdl, submodel );
164
165 boxf bbxnew;
166 box_copy( submodel->bbx, bbxnew );
167 m4x3_transform_aabb( transform, bbxnew );
168 box_concat( pscene->bbx, bbxnew );
169
170 float rand_hue = vg_randf();
171 for( u32 i=0; i<submodel->vertex_count; i++ )
172 {
173 model_vert *pvert = &pscene->verts[ pscene->vertex_count+i ],
174 *src = &src_verts[ i ];
175
176 m4x3_mulv( transform, src->co, pvert->co );
177 m3x3_mulv( transform, src->norm, pvert->norm );
178
179 v4_copy( src->colour, pvert->colour );
180 v2_copy( src->uv, pvert->uv );
181
182 float rel_y = src->co[1] / submodel->bbx[1][1];
183 pvert->colour[0] = rel_y;
184 pvert->colour[2] = rand_hue;
185 }
186
187 for( u32 i=0; i<submodel->indice_count; i++ )
188 {
189 u32 *pidx = &pscene->indices[ pscene->indice_count+i ];
190 *pidx = src_indices[i] + pscene->vertex_count;
191 }
192
193 pscene->vertex_count += submodel->vertex_count;
194 pscene->indice_count += submodel->indice_count;
195 }
196
197 static void scene_copy_slice( scene *pscene, submodel *sm )
198 {
199 sm->indice_start = pscene->submesh.indice_start;
200 sm->indice_count = pscene->indice_count - sm->indice_start;
201
202 sm->vertex_start = pscene->submesh.vertex_start;
203 sm->vertex_count = pscene->vertex_count - sm->vertex_start;
204
205 pscene->submesh.indice_start = pscene->indice_count;
206 pscene->submesh.vertex_start = pscene->vertex_count;
207 }
208
209 static void scene_upload( scene *pscene )
210 {
211 mesh_upload( &pscene->mesh,
212 pscene->verts, pscene->vertex_count,
213 pscene->indices, pscene->indice_count );
214
215 vg_info( "Scene upload\n" );
216 vg_info( " indices:%u\n", pscene->indice_count );
217 vg_info( " verts:%u\n", pscene->vertex_count );
218 }
219
220 static void scene_bind( scene *pscene )
221 {
222 mesh_bind( &pscene->mesh );
223 }
224
225 static void scene_draw( scene *pscene )
226 {
227 mesh_drawn( 0, pscene->indice_count );
228 }
229
230 static void scene_register(void)
231 {
232 }
233
234 /*
235 * BVH implementation
236 */
237
238 static void scene_bh_expand_bound( void *user, boxf bound, u32 item_index )
239 {
240 scene *s = user;
241 model_vert *pa = &s->verts[ s->indices[item_index*3+0] ],
242 *pb = &s->verts[ s->indices[item_index*3+1] ],
243 *pc = &s->verts[ s->indices[item_index*3+2] ];
244
245 box_addpt( bound, pa->co );
246 box_addpt( bound, pb->co );
247 box_addpt( bound, pc->co );
248 }
249
250 static float scene_bh_centroid( void *user, u32 item_index, int axis )
251 {
252 scene *s = user;
253 model_vert *pa = &s->verts[ s->indices[item_index*3+0] ],
254 *pb = &s->verts[ s->indices[item_index*3+1] ],
255 *pc = &s->verts[ s->indices[item_index*3+2] ];
256
257 return (pa->co[axis] + pb->co[axis] + pc->co[axis]) * (1.0f/3.0f);
258 }
259
260 static void scene_bh_swap( void *user, u32 ia, u32 ib )
261 {
262 scene *s = user;
263
264 u32 *ti = &s->indices[ia*3];
265 u32 *tj = &s->indices[ib*3];
266
267 u32 temp[3];
268 temp[0] = ti[0];
269 temp[1] = ti[1];
270 temp[2] = ti[2];
271
272 ti[0] = tj[0];
273 ti[1] = tj[1];
274 ti[2] = tj[2];
275
276 tj[0] = temp[0];
277 tj[1] = temp[1];
278 tj[2] = temp[2];
279 }
280
281 static void scene_bh_debug( void *user, u32 item_index )
282 {
283 scene *s = user;
284 u32 idx = item_index*3;
285 model_vert *pa = &s->verts[ s->indices[ idx+0 ] ],
286 *pb = &s->verts[ s->indices[ idx+1 ] ],
287 *pc = &s->verts[ s->indices[ idx+2 ] ];
288
289 vg_line( pa->co, pb->co, 0xff0000ff );
290 vg_line( pb->co, pc->co, 0xff0000ff );
291 vg_line( pc->co, pa->co, 0xff0000ff );
292 }
293
294 static int scene_bh_ray( void *user, u32 index, v3f co, v3f dir, ray_hit *hit )
295 {
296 scene *s = user;
297 v3f positions[3];
298
299 u32 *tri = &s->indices[ index*3 ];
300
301 for( int i=0; i<3; i++ )
302 v3_copy( s->verts[tri[i]].co, positions[i] );
303
304 float t;
305 if(ray_tri( positions, co, dir, &t ))
306 {
307 if( t < hit->dist )
308 {
309 hit->dist = t;
310 hit->tri = tri;
311 return 1;
312 }
313 }
314
315 return 0;
316 }
317
318 static bh_system bh_system_scene =
319 {
320 .expand_bound = scene_bh_expand_bound,
321 .item_centroid = scene_bh_centroid,
322 .item_swap = scene_bh_swap,
323 .item_debug = scene_bh_debug,
324 .cast_ray = scene_bh_ray
325 };
326
327 /*
328 * An extra step is added onto the end to calculate the hit normal
329 */
330 static int scene_raycast( scene *s, v3f co, v3f dir, ray_hit *hit )
331 {
332 int count = bh_ray( &s->bhtris, 0, co, dir, hit );
333
334 if( count )
335 {
336 v3f v0, v1;
337
338 float *pa = s->verts[hit->tri[0]].co,
339 *pb = s->verts[hit->tri[1]].co,
340 *pc = s->verts[hit->tri[2]].co;
341
342 v3_sub( pa, pb, v0 );
343 v3_sub( pc, pb, v1 );
344 v3_cross( v1, v0, hit->normal );
345 v3_normalize( hit->normal );
346 v3_muladds( co, dir, hit->dist, hit->pos );
347 }
348
349 return count;
350 }
351
352 static void scene_bh_create( scene *s )
353 {
354 u32 triangle_count = s->indice_count / 3;
355 bh_create( &s->bhtris, &bh_system_scene, s, triangle_count );
356 }
357
358 #endif