7 typedef struct scene scene
;
8 typedef struct bvh_node bvh_node
;
37 GLuint tex_dual_noise
;
39 static void scene_init( scene
*pscene
)
42 pscene
->indices
= NULL
;
43 pscene
->vertex_count
= 0;
44 pscene
->indice_count
= 0;
45 pscene
->shadower_count
= 0;
46 pscene
->shadower_cap
= 0;
47 pscene
->submesh
.indice_start
= 0;
48 pscene
->submesh
.indice_count
= 0;
50 v3_fill( pscene
->bbx
[0], 999999.9f
);
51 v3_fill( pscene
->bbx
[1], -999999.9f
);
53 static int noise_ready
= 0;
58 u8
*buf
= malloc( 256*256*2 );
60 for( int i
=0; i
<256*256; i
++ )
66 for( int y
=0; y
<256; y
++ )
68 for( int x
=0; x
<256; x
++ )
70 u8
*pr
= &buf
[(y
*256+x
)*2],
71 *pg
= &buf
[(((y
+17)&0xff)*256+((x
+37)&0xff))*2+1];
76 /* TODO: This texture should be delted somewhere */
77 glGenTextures( 1, &tex_dual_noise
);
78 glBindTexture( GL_TEXTURE_2D
, tex_dual_noise
);
79 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RG
, 256, 256, 0, GL_RG
,
80 GL_UNSIGNED_BYTE
, buf
);
89 static void *buffer_reserve( void *buffer
, u32 count
, u32
*cap
, u32 amount
,
92 if( count
+amount
> *cap
)
94 *cap
= VG_MAX( (*cap
)*2, (*cap
)+amount
);
96 return realloc( buffer
, (*cap
) * emsize
);
103 * Append a model into the scene with a given transform
105 static void scene_add_model( scene
*pscene
, model
*mdl
, submodel
*submodel
,
106 v3f pos
, float yaw
, float scale
)
108 pscene
->verts
= buffer_reserve( pscene
->verts
, pscene
->vertex_count
,
109 &pscene
->vertex_cap
, submodel
->vertex_count
, sizeof(model_vert
) );
110 pscene
->indices
= buffer_reserve( pscene
->indices
, pscene
->indice_count
,
111 &pscene
->indice_cap
, submodel
->indice_count
, sizeof(u32
) );
113 /* Transform and place vertices */
114 model_vert
*src_verts
= submodel_vert_data( mdl
, submodel
);
115 u32
*src_indices
= submodel_indice_data( mdl
, submodel
);
118 m4x3_identity( mtx
);
119 m4x3_translate( mtx
, pos
);
120 m4x3_rotate_y( mtx
, yaw
);
121 m4x3_scale( mtx
, scale
);
124 box_copy( submodel
->bbx
, bbxnew
);
125 m4x3_transform_aabb( mtx
, bbxnew
);
126 box_concat( pscene
->bbx
, bbxnew
);
129 m4x3_to_3x3( mtx
, rotation
);
131 float rand_hue
= vg_randf();
133 for( u32 i
=0; i
<submodel
->vertex_count
; i
++ )
135 model_vert
*pvert
= &pscene
->verts
[ pscene
->vertex_count
+i
],
136 *src
= &src_verts
[ i
];
138 m4x3_mulv( mtx
, src
->co
, pvert
->co
);
139 m3x3_mulv( rotation
, src
->norm
, pvert
->norm
);
141 v4_copy( src
->colour
, pvert
->colour
);
142 v2_copy( src
->uv
, pvert
->uv
);
144 float rel_y
= src
->co
[1] / submodel
->bbx
[1][1];
145 pvert
->colour
[0] = rel_y
;
146 pvert
->colour
[2] = rand_hue
;
149 for( u32 i
=0; i
<submodel
->indice_count
; i
++ )
151 u32
*pidx
= &pscene
->indices
[ pscene
->indice_count
+i
];
152 *pidx
= src_indices
[i
] + pscene
->vertex_count
;
155 pscene
->vertex_count
+= submodel
->vertex_count
;
156 pscene
->indice_count
+= submodel
->indice_count
;
159 static void scene_add_foliage( scene
*pscene
, model
*mdl
, submodel
*submodel
,
162 pscene
->verts
= buffer_reserve( pscene
->verts
, pscene
->vertex_count
,
163 &pscene
->vertex_cap
, submodel
->vertex_count
, sizeof(model_vert
) );
164 pscene
->indices
= buffer_reserve( pscene
->indices
, pscene
->indice_count
,
165 &pscene
->indice_cap
, submodel
->indice_count
, sizeof(u32
) );
167 /* Transform and place vertices */
168 model_vert
*src_verts
= submodel_vert_data( mdl
, submodel
);
169 u32
*src_indices
= submodel_indice_data( mdl
, submodel
);
172 box_copy( submodel
->bbx
, bbxnew
);
173 m4x3_transform_aabb( transform
, bbxnew
);
174 box_concat( pscene
->bbx
, bbxnew
);
176 float rand_hue
= vg_randf();
177 for( u32 i
=0; i
<submodel
->vertex_count
; i
++ )
179 model_vert
*pvert
= &pscene
->verts
[ pscene
->vertex_count
+i
],
180 *src
= &src_verts
[ i
];
182 m4x3_mulv( transform
, src
->co
, pvert
->co
);
183 m3x3_mulv( transform
, src
->norm
, pvert
->norm
);
185 v4_copy( src
->colour
, pvert
->colour
);
186 v2_copy( src
->uv
, pvert
->uv
);
188 float rel_y
= src
->co
[1] / submodel
->bbx
[1][1];
189 pvert
->colour
[0] = rel_y
;
190 pvert
->colour
[2] = rand_hue
;
193 for( u32 i
=0; i
<submodel
->indice_count
; i
++ )
195 u32
*pidx
= &pscene
->indices
[ pscene
->indice_count
+i
];
196 *pidx
= src_indices
[i
] + pscene
->vertex_count
;
199 pscene
->vertex_count
+= submodel
->vertex_count
;
200 pscene
->indice_count
+= submodel
->indice_count
;
203 static void scene_copy_slice( scene
*pscene
, submodel
*sm
)
205 sm
->indice_start
= pscene
->submesh
.indice_start
;
206 sm
->indice_count
= pscene
->indice_count
- sm
->indice_start
;
208 sm
->vertex_start
= pscene
->submesh
.vertex_start
;
209 sm
->vertex_count
= pscene
->vertex_count
- sm
->vertex_start
;
211 pscene
->submesh
.indice_start
= pscene
->indice_count
;
212 pscene
->submesh
.vertex_start
= pscene
->vertex_count
;
215 static void scene_upload( scene
*pscene
)
217 mesh_upload( &pscene
->mesh
,
218 pscene
->verts
, pscene
->vertex_count
,
219 pscene
->indices
, pscene
->indice_count
);
221 vg_info( "Scene upload\n" );
222 vg_info( " indices:%u\n", pscene
->indice_count
);
223 vg_info( " verts:%u\n", pscene
->vertex_count
);
226 float scene_tree_sway
= 0.1f
;
229 static void scene_foliage_shader_use(void)
231 SHADER_USE( shader_debug_vcol
);
233 glUniformMatrix4fv( SHADER_UNIFORM( shader_debug_vcol
, "uPv" ),
234 1, GL_FALSE
, (float *)vg_pv
);
236 glUniform1i( SHADER_UNIFORM( shader_debug_vcol
, "uMode" ), debugview
);
237 glUniform1i( SHADER_UNIFORM( shader_debug_vcol
, "uTexMain" ), 0 );
239 glUniform1i( SHADER_UNIFORM( shader_debug_vcol
, "uTexGradients" ), 1 );
240 vg_tex2d_bind( &tex_gradients
, 1 );
242 glUniform1i( SHADER_UNIFORM( shader_debug_vcol
, "uTexNoise" ), 2 );
243 glActiveTexture( GL_TEXTURE2
);
244 glBindTexture( GL_TEXTURE_2D
, tex_dual_noise
);
246 glUniform1f( SHADER_UNIFORM( shader_debug_vcol
, "uTime" ), vg_time
);
247 glUniform1f( SHADER_UNIFORM( shader_debug_vcol
, "uSwayAmt" ),
252 static void scene_bind( scene
*pscene
)
254 mesh_bind( &pscene
->mesh
);
257 static void scene_draw( scene
*pscene
)
259 mesh_drawn( 0, pscene
->indice_count
);
262 static void scene_register(void)
267 /* Physics segment */
269 static int triangle_raycast2d( v3f pA
, v3f pB
, v3f pC
, v3f ray
, float *height
)
271 v2f v0
, v1
, v2
, vp
, vp2
;
272 float d
, bca
= 0.f
, bcb
= 0.f
, bcc
= 0.f
;
274 v0
[0] = pB
[0] - pA
[0];
275 v0
[1] = pB
[2] - pA
[2];
276 v1
[0] = pC
[0] - pA
[0];
277 v1
[1] = pC
[2] - pA
[2];
278 v2
[0] = pB
[0] - pC
[0];
279 v2
[1] = pB
[2] - pC
[2];
281 d
= 1.f
/ (v0
[0]*v1
[1] - v1
[0]*v0
[1]);
284 /* Backface culling */
285 if( v2_cross( v0
, v1
) > 0.f
)
289 vp
[0] = ray
[0] - pA
[0];
290 vp
[1] = ray
[2] - pA
[2];
292 if( v2_cross( v0
, vp
) > 0.f
) return 0;
293 if( v2_cross( vp
, v1
) > 0.f
) return 0;
295 vp2
[0] = ray
[0] - pB
[0];
296 vp2
[1] = ray
[2] - pB
[2];
298 if( v2_cross( vp2
, v2
) > 0.f
) return 0;
300 bcb
= (vp
[0]*v1
[1] - v1
[0]*vp
[1]) * d
;
301 bcc
= (v0
[0]*vp
[1] - vp
[0]*v0
[1]) * d
;
302 bca
= 1.f
- bcb
- bcc
;
304 *height
= pA
[1]*bca
+ pB
[1]*bcb
+ pC
[1]*bcc
;
309 static int sample_scene_height( scene
*pscene
, v3f pos
, v3f norm
)
311 for( int i
=0; i
<pscene
->indice_count
/3; i
++ )
313 u32
*tri
= &pscene
->indices
[i
*3];
315 float *pA
= pscene
->verts
[tri
[0]].co
,
316 *pB
= pscene
->verts
[tri
[1]].co
,
317 *pC
= pscene
->verts
[tri
[2]].co
;
320 if( triangle_raycast2d( pA
, pB
, pC
, pos
, &height
))
327 v3_sub( pA
, pB
, v0
);
328 v3_sub( pC
, pB
, v1
);
329 v3_cross( v1
, v0
, norm
);
330 v3_normalize( norm
);
339 static void sample_scene_normal( scene
*pscene
, v3f pos
, v3f normal
)
341 for( int i
=0; i
<pscene
->indice_count
/3; i
++ )
343 u32
*tri
= &pscene
->indices
[i
*3];
346 if( triangle_raycast2d(
347 pscene
->verts
[ tri
[0] ].co
,
348 pscene
->verts
[ tri
[1] ].co
,
349 pscene
->verts
[ tri
[2] ].co
, pos
, &height
))
353 v3_sub( pscene
->verts
[ tri
[1] ].co
,
354 pscene
->verts
[ tri
[0] ].co
,
357 v3_sub( pscene
->verts
[ tri
[2] ].co
,
358 pscene
->verts
[ tri
[0] ].co
,
361 v3_cross( v0
, v1
, normal
);
362 v3_normalize( normal
);
376 /* if il is 0, this is a leaf */
378 union{ u32 ir
, start
; };
381 static void bvh_update_bounds( scene
*s
, u32 inode
)
383 bvh_node
*node
= &s
->bvh
.nodes
[ inode
];
385 box_init_inf( node
->bbx
);
386 for( u32 i
=0; i
<node
->count
; i
++ )
388 u32 idx
= node
->start
+i
;
389 model_vert
*pa
= &s
->verts
[ s
->indices
[idx
*3+0] ],
390 *pb
= &s
->verts
[ s
->indices
[idx
*3+1] ],
391 *pc
= &s
->verts
[ s
->indices
[idx
*3+2] ];
393 box_addpt( node
->bbx
, pa
->co
);
394 box_addpt( node
->bbx
, pb
->co
);
395 box_addpt( node
->bbx
, pc
->co
);
399 static void bvh_subdiv( scene
*s
, u32 inode
)
401 bvh_node
*node
= &s
->bvh
.nodes
[ inode
];
404 v3_sub( node
->bbx
[1], node
->bbx
[0], extent
);
407 if( extent
[1] > extent
[0] ) axis
= 1;
408 if( extent
[2] > extent
[axis
] ) axis
= 2;
410 float split
= node
->bbx
[0][axis
] + extent
[axis
]*0.5f
;
412 /* To beat: 121,687 / 136,579
417 for( u32 t
=0; t
<node
->count
; t
++ )
419 u32
*ti
= &s
->indices
[(node
->start
+t
)*3];
420 float a
= s
->verts
[ti
[0]].co
[axis
],
421 b
= s
->verts
[ti
[1]].co
[axis
],
422 c
= s
->verts
[ti
[2]].co
[axis
];
425 avg
/= (float)node
->count
;
430 j
= i
+ node
->count
-1;
434 u32
*ti
= &s
->indices
[i
*3];
436 float a
= s
->verts
[ti
[0]].co
[axis
],
437 b
= s
->verts
[ti
[1]].co
[axis
],
438 c
= s
->verts
[ti
[2]].co
[axis
];
440 if( ((a
+b
+c
) / 3.0f
) < split
)
444 /* Swap triangle indices */
445 u32
*tj
= &s
->indices
[j
*3];
463 u32 left_count
= i
- node
->start
;
464 if( left_count
== 0 || left_count
== node
->count
) return;
466 u32 il
= s
->bvh
.node_count
++,
467 ir
= s
->bvh
.node_count
++;
469 struct bvh_node
*lnode
= &s
->bvh
.nodes
[il
],
470 *rnode
= &s
->bvh
.nodes
[ir
];
472 lnode
->start
= node
->start
;
473 lnode
->count
= left_count
;
475 rnode
->count
= node
->count
- left_count
;
481 bvh_update_bounds( s
, il
);
482 bvh_update_bounds( s
, ir
);
487 static void bvh_create( scene
*s
)
489 u32 triangle_count
= s
->indice_count
/ 3;
490 s
->bvh
.nodes
= malloc( sizeof(struct bvh_node
) * (triangle_count
*2-1) );
492 bvh_node
*root
= &s
->bvh
.nodes
[0];
493 s
->bvh
.node_count
= 1;
497 root
->count
= triangle_count
;
500 bvh_update_bounds( s
, 0 );
504 realloc( s
->bvh
.nodes
, sizeof(struct bvh_node
) * s
->bvh
.node_count
);
506 vg_success( "BVH done, size: %u/%u\n", s
->bvh
.node_count
,
507 (triangle_count
*2-1) );
510 static void bvh_debug_node( scene
*s
, u32 inode
, v3f pos
, u32 colour
)
512 struct bvh_node
*node
= &s
->bvh
.nodes
[ inode
];
514 if( (pos
[0] >= node
->bbx
[0][0] && pos
[0] <= node
->bbx
[1][0]) &&
515 (pos
[2] >= node
->bbx
[0][2] && pos
[2] <= node
->bbx
[1][2]) )
519 vg_line_boxf( node
->bbx
, colour
);
521 bvh_debug_node( s
, node
->il
, pos
, colour
);
522 bvh_debug_node( s
, node
->ir
, pos
, colour
);
526 vg_line_boxf( node
->bbx
, 0xff00ff00 );
527 for( u32 i
=0; i
<node
->count
; i
++ )
529 u32 idx
= (node
->start
+i
)*3;
531 model_vert
*pa
= &s
->verts
[ s
->indices
[ idx
+0 ] ],
532 *pb
= &s
->verts
[ s
->indices
[ idx
+1 ] ],
533 *pc
= &s
->verts
[ s
->indices
[ idx
+2 ] ];
535 vg_line( pa
->co
, pb
->co
, 0xff0000ff );
536 vg_line( pb
->co
, pc
->co
, 0xff0000ff );
537 vg_line( pc
->co
, pa
->co
, 0xff0000ff );
543 static void bvh_debug( scene
*s
, v3f pos
)
545 bvh_debug_node( s
, 0, pos
, 0x4000ffa8 );
548 typedef struct ray_hit ray_hit
;
556 int ray_aabb( boxf box
, v3f co
, v3f dir
, float dist
)
561 v3_sub( box
[0], co
, v0
);
562 v3_sub( box
[1], co
, v1
);
563 v3_div( v0
, dir
, v0
);
564 v3_div( v1
, dir
, v1
);
566 tmin
= vg_minf( v0
[0], v1
[0] );
567 tmax
= vg_maxf( v0
[0], v1
[0] );
568 tmin
= vg_maxf( tmin
, vg_minf( v0
[1], v1
[1] ));
569 tmax
= vg_minf( tmax
, vg_maxf( v0
[1], v1
[1] ));
570 tmin
= vg_maxf( tmin
, vg_minf( v0
[2], v1
[2] ));
571 tmax
= vg_minf( tmax
, vg_maxf( v0
[2], v1
[2] ));
573 return tmax
>= tmin
&& tmin
< dist
&& tmax
> 0;
576 static int bvh_ray_tri( scene
*sc
, u32
*tri
, v3f co
, v3f dir
, ray_hit
*hit
)
579 for( int i
=0; i
<3; i
++ )
580 v3_copy( sc
->verts
[tri
[i
]].co
, positions
[i
] );
583 if(ray_tri( positions
, co
, dir
, &t
))
596 static int bvh_ray( scene
*s
, u32 inode
, v3f co
, v3f dir
, ray_hit
*hit
)
598 bvh_node
*node
= &s
->bvh
.nodes
[ inode
];
600 if( !ray_aabb( node
->bbx
, co
, dir
, hit
->dist
))
607 for( u32 i
=0; i
<node
->count
; i
++ )
609 u32
*indices
= &s
->indices
[ (node
->start
+i
)*3 ];
610 count
+= bvh_ray_tri( s
, indices
, co
, dir
, hit
);
615 count
+= bvh_ray( s
, node
->il
, co
, dir
, hit
);
616 count
+= bvh_ray( s
, node
->ir
, co
, dir
, hit
);
622 static int bvh_raycast( scene
*s
, v3f co
, v3f dir
, ray_hit
*hit
)
625 v3_muladds( co
, dir
, hit
->dist
, pb
);
627 int count
= bvh_ray( s
, 0, co
, dir
, hit
);
631 //vg_line( co, pb, 0xff00ffff );
635 float *pa
= s
->verts
[hit
->tri
[0]].co
,
636 *pb
= s
->verts
[hit
->tri
[1]].co
,
637 *pc
= s
->verts
[hit
->tri
[2]].co
;
639 v3_sub( pa
, pb
, v0
);
640 v3_sub( pc
, pb
, v1
);
641 v3_cross( v1
, v0
, hit
->normal
);
642 v3_normalize( hit
->normal
);
643 v3_muladds( co
, dir
, hit
->dist
, hit
->pos
);
647 //vg_line( co, pb, 0xff0000ff );
653 static int bvh_select_triangles( scene
*s
, boxf box
, u32
*triangles
, int len
)
655 /* TODO: use this stack system on the raycast function */
661 stack
[1] = s
->bvh
.nodes
[0].il
;
662 stack
[2] = s
->bvh
.nodes
[0].ir
;
666 bvh_node
*inode
= &s
->bvh
.nodes
[ stack
[depth
] ];
667 if( box_overlap( inode
->bbx
, box
) )
671 if( count
+ inode
->count
>= len
)
673 vg_error( "Maximum buffer reached!\n" );
677 for( u32 i
=0; i
<inode
->count
; i
++ )
678 triangles
[ count
++ ] = (inode
->start
+i
)*3;
684 if( depth
+1 >= vg_list_size(stack
) )
686 vg_error( "Maximum stack reached!\n" );
690 stack
[depth
] = inode
->il
;
691 stack
[depth
+1] = inode
->ir
;
704 static int bvh_scene_sample_node_h( scene
*s
, u32 inode
, v3f pos
, v3f norm
)
706 bvh_node
*node
= &s
->bvh
.nodes
[ inode
];
708 if( (pos
[0] >= node
->bbx
[0][0] && pos
[0] <= node
->bbx
[1][0]) &&
709 (pos
[2] >= node
->bbx
[0][2] && pos
[2] <= node
->bbx
[1][2]) )
713 if( bvh_scene_sample_node_h( s
, node
->il
, pos
, norm
)) return 1;
714 if( bvh_scene_sample_node_h( s
, node
->ir
, pos
, norm
)) return 1;
718 for( u32 i
=0; i
<node
->count
; i
++ )
720 u32 idx
= (node
->start
+i
)*3;
721 model_vert
*pa
= &s
->verts
[ s
->indices
[ idx
+0 ] ],
722 *pb
= &s
->verts
[ s
->indices
[ idx
+1 ] ],
723 *pc
= &s
->verts
[ s
->indices
[ idx
+2 ] ];
726 if( triangle_raycast2d( pa
->co
, pb
->co
, pc
->co
, pos
, &height
))
733 v3_sub( pa
->co
, pb
->co
, v0
);
734 v3_sub( pc
->co
, pb
->co
, v1
);
735 v3_cross( v1
, v0
, norm
);
736 v3_normalize( norm
);
748 static int bvh_scene_sample_h( scene
*s
, v3f pos
, v3f norm
)
750 return bvh_scene_sample_node_h( s
, 0, pos
, norm
);
753 static int bvh_scene_sample( scene
*s
, v3f pos
, ray_hit
*hit
)
755 hit
->dist
= INFINITY
;
758 v3_add( pos
, (v3f
){0.0f
,4.0f
,0.0f
}, ray_pos
);
760 if( bvh_raycast( s
, ray_pos
, (v3f
){0.0f
,-1.0f
,0.0f
}, hit
))
762 pos
[1] = hit
->pos
[1];