8 typedef struct scene scene
;
31 static void scene_init( scene
*pscene
)
34 pscene
->indices
= NULL
;
35 pscene
->vertex_count
= 0;
36 pscene
->indice_count
= 0;
37 pscene
->shadower_count
= 0;
38 pscene
->shadower_cap
= 0;
39 pscene
->submesh
.indice_start
= 0;
40 pscene
->submesh
.indice_count
= 0;
42 v3_fill( pscene
->bbx
[0], 999999.9f
);
43 v3_fill( pscene
->bbx
[1], -999999.9f
);
47 * Append a model into the scene with a given transform
49 static void scene_add_submesh( scene
*pscene
, mdl_header
*mdl
,
50 mdl_submesh
*sm
, m4x3f transform
)
52 pscene
->verts
= buffer_reserve( pscene
->verts
, pscene
->vertex_count
,
53 &pscene
->vertex_cap
, sm
->vertex_count
, sizeof(mdl_vert
) );
55 pscene
->indices
= buffer_reserve( pscene
->indices
, pscene
->indice_count
,
56 &pscene
->indice_cap
, sm
->indice_count
, sizeof(u32
) );
59 m3x3_copy( transform
, normal_matrix
);
60 v3_normalize( normal_matrix
[0] );
61 v3_normalize( normal_matrix
[1] );
62 v3_normalize( normal_matrix
[2] );
64 /* Transform and place vertices */
65 mdl_vert
*src_verts
= mdl_submesh_vertices( mdl
, sm
);
66 u32
*src_indices
= mdl_submesh_indices( mdl
, sm
);
69 box_copy( sm
->bbx
, bbxnew
);
70 m4x3_transform_aabb( transform
, bbxnew
);
71 box_concat( pscene
->bbx
, bbxnew
);
73 for( u32 i
=0; i
<sm
->vertex_count
; i
++ )
75 mdl_vert
*pvert
= &pscene
->verts
[ pscene
->vertex_count
+i
],
76 *src
= &src_verts
[ i
];
78 m4x3_mulv( transform
, src
->co
, pvert
->co
);
79 m3x3_mulv( normal_matrix
, src
->norm
, pvert
->norm
);
81 pvert
->colour
[0] = src
->colour
[0];
82 pvert
->colour
[1] = src
->colour
[1];
83 pvert
->colour
[2] = src
->colour
[2];
84 pvert
->colour
[3] = src
->colour
[3];
85 v2_copy( src
->uv
, pvert
->uv
);
88 for( u32 i
=0; i
<sm
->indice_count
; i
++ )
90 u32
*pidx
= &pscene
->indices
[ pscene
->indice_count
+i
];
91 *pidx
= src_indices
[i
] + pscene
->vertex_count
;
94 pscene
->vertex_count
+= sm
->vertex_count
;
95 pscene
->indice_count
+= sm
->indice_count
;
99 * One by one adders for simplified access (mostly procedural stuff)
101 static void scene_push_tri( scene
*pscene
, u32 tri
[3] )
103 pscene
->indices
= buffer_reserve( pscene
->indices
, pscene
->indice_count
,
104 &pscene
->indice_cap
, 3, sizeof(u32
) );
106 u32
*dst
= &pscene
->indices
[pscene
->indice_count
];
111 pscene
->indice_count
+= 3;
114 static void scene_push_vert( scene
*pscene
, mdl_vert
*v
)
116 pscene
->verts
= buffer_reserve( pscene
->verts
, pscene
->vertex_count
,
117 &pscene
->vertex_cap
, 1, sizeof(mdl_vert
) );
118 pscene
->verts
[pscene
->vertex_count
++] = *v
;
121 static void scene_copy_slice( scene
*pscene
, mdl_submesh
*sm
)
123 sm
->indice_start
= pscene
->submesh
.indice_start
;
124 sm
->indice_count
= pscene
->indice_count
- sm
->indice_start
;
126 sm
->vertex_start
= pscene
->submesh
.vertex_start
;
127 sm
->vertex_count
= pscene
->vertex_count
- sm
->vertex_start
;
129 pscene
->submesh
.indice_start
= pscene
->indice_count
;
130 pscene
->submesh
.vertex_start
= pscene
->vertex_count
;
133 static void scene_fix( scene
*pscene
)
135 buffer_fix( pscene
->verts
, pscene
->vertex_count
,
136 &pscene
->vertex_cap
, sizeof( mdl_vert
));
138 buffer_fix( pscene
->indices
, pscene
->indice_count
,
139 &pscene
->indice_cap
, sizeof( mdl_vert
));
142 static void scene_upload( scene
*pscene
)
144 mesh_upload( &pscene
->mesh
,
145 pscene
->verts
, pscene
->vertex_count
,
146 pscene
->indices
, pscene
->indice_count
);
148 vg_info( "Scene upload\n" );
149 vg_info( " indices:%u\n", pscene
->indice_count
);
150 vg_info( " verts:%u\n", pscene
->vertex_count
);
153 static void scene_bind( scene
*pscene
)
155 mesh_bind( &pscene
->mesh
);
158 static void scene_draw( scene
*pscene
)
160 mesh_drawn( 0, pscene
->indice_count
);
163 static void scene_free_offline_buffers( scene
*pscene
)
165 vg_free( pscene
->verts
);
166 vg_free( pscene
->indices
);
169 static void scene_free( scene
*pscene
)
171 scene_free_offline_buffers( pscene
);
178 static void scene_bh_expand_bound( void *user
, boxf bound
, u32 item_index
)
181 mdl_vert
*pa
= &s
->verts
[ s
->indices
[item_index
*3+0] ],
182 *pb
= &s
->verts
[ s
->indices
[item_index
*3+1] ],
183 *pc
= &s
->verts
[ s
->indices
[item_index
*3+2] ];
185 box_addpt( bound
, pa
->co
);
186 box_addpt( bound
, pb
->co
);
187 box_addpt( bound
, pc
->co
);
190 static float scene_bh_centroid( void *user
, u32 item_index
, int axis
)
193 mdl_vert
*pa
= &s
->verts
[ s
->indices
[item_index
*3+0] ],
194 *pb
= &s
->verts
[ s
->indices
[item_index
*3+1] ],
195 *pc
= &s
->verts
[ s
->indices
[item_index
*3+2] ];
197 return (pa
->co
[axis
] + pb
->co
[axis
] + pc
->co
[axis
]) * (1.0f
/3.0f
);
200 static void scene_bh_swap( void *user
, u32 ia
, u32 ib
)
204 u32
*ti
= &s
->indices
[ia
*3];
205 u32
*tj
= &s
->indices
[ib
*3];
221 static void scene_bh_debug( void *user
, u32 item_index
)
224 u32 idx
= item_index
*3;
225 mdl_vert
*pa
= &s
->verts
[ s
->indices
[ idx
+0 ] ],
226 *pb
= &s
->verts
[ s
->indices
[ idx
+1 ] ],
227 *pc
= &s
->verts
[ s
->indices
[ idx
+2 ] ];
229 vg_line( pa
->co
, pb
->co
, 0xff0000ff );
230 vg_line( pb
->co
, pc
->co
, 0xff0000ff );
231 vg_line( pc
->co
, pa
->co
, 0xff0000ff );
234 static int scene_bh_ray( void *user
, u32 index
, v3f co
, v3f dir
, ray_hit
*hit
)
239 u32
*tri
= &s
->indices
[ index
*3 ];
241 for( int i
=0; i
<3; i
++ )
242 v3_copy( s
->verts
[tri
[i
]].co
, positions
[i
] );
245 if(ray_tri( positions
, co
, dir
, &t
))
258 static bh_system bh_system_scene
=
260 .expand_bound
= scene_bh_expand_bound
,
261 .item_centroid
= scene_bh_centroid
,
262 .item_swap
= scene_bh_swap
,
263 .item_debug
= scene_bh_debug
,
264 .cast_ray
= scene_bh_ray
268 * An extra step is added onto the end to calculate the hit normal
270 static int scene_raycast( scene
*s
, v3f co
, v3f dir
, ray_hit
*hit
)
272 int count
= bh_ray( &s
->bhtris
, 0, co
, dir
, hit
);
278 float *pa
= s
->verts
[hit
->tri
[0]].co
,
279 *pb
= s
->verts
[hit
->tri
[1]].co
,
280 *pc
= s
->verts
[hit
->tri
[2]].co
;
282 v3_sub( pa
, pb
, v0
);
283 v3_sub( pc
, pb
, v1
);
284 v3_cross( v1
, v0
, hit
->normal
);
285 v3_normalize( hit
->normal
);
286 v3_muladds( co
, dir
, hit
->dist
, hit
->pos
);
292 static void scene_bh_create( scene
*s
)
294 u32 triangle_count
= s
->indice_count
/ 3;
295 bh_create( &s
->bhtris
, &bh_system_scene
, s
, triangle_count
);