commit 46ad1520f80035840cdf42d20177f1c1008361f8
parent 31a0be67772c682574bf832e4fa0e31ad9b97bda
Author: Michael Savage <mikejsavage@gmail.com>
Date: Thu, 30 May 2019 02:14:25 +0300
Don't use std::map
Diffstat:
M | gltf.cc | | | 142 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
1 file changed, 69 insertions(+), 73 deletions(-)
diff --git a/gltf.cc b/gltf.cc
@@ -7,8 +7,6 @@
#include "renderer.h"
#include "shaders.h"
-#include <map>
-
#include "platform_time.h"
#define CGLTF_IMPLEMENTATION
@@ -173,11 +171,23 @@ static bool LoadBinaryBuffers( cgltf_data * data ) {
static AnimationReel::Clip CLIP;
static GLTFModel model;
-static void LoadSkin( const cgltf_skin * skin, std::map< const cgltf_node *, size_t > & node_to_joint ) {
+static void LoadSkin( const cgltf_skin * skin ) {
printf( "skeleton %p\n", skin->skeleton );
model.animation.joints = ( AnimationReel::Joint * ) malloc( sizeof( AnimationReel::Joint ) * skin->joints_count );
+ // we want to find the root of the subtree representing the skeleton
+ // mark all subtree nodes and then walk up the tree to find the root
+ for( size_t i = 0; i < skin->joints_count; i++ ) {
+ ASSERT( skin->joints[ i ]->camera == NULL );
+ skin->joints[ i ]->camera = ( cgltf_camera * ) 1;
+ }
+
+ const cgltf_node * root = skin->joints[ 0 ];
+ while( root->parent != NULL && root->parent->camera == NULL ) {
+ root = root->parent;
+ }
+
// todo1;
// find root of skeleton, not necessarily root of hierarchy
// bake transforms from root of skeleton to root of hierarchy into root joint
@@ -185,13 +195,13 @@ static void LoadSkin( const cgltf_skin * skin, std::map< const cgltf_node *, siz
for( size_t i = 0; i < skin->joints_count; i++ ) {
printf( "joint %zu: %p\n", i, skin->joints[ i ] );
- node_to_joint[ skin->joints[ i ] ] = i;
+ skin->joints[ i ]->camera = ( cgltf_camera * ) ( i + 1 );
if( i == 0 ) {
model.animation.joints[ i ].parent = 0;
}
else {
- model.animation.joints[ i ].parent = node_to_joint[ skin->joints[ i ]->parent ];
+ model.animation.joints[ i ].parent = u8( uintptr_t( skin->joints[ i ]->parent->camera ) - 1 );
ASSERT( model.animation.joints[ i ].parent < i );
}
cgltf_node_transform_local( skin->joints[ i ], &model.animation.joints[ i ].node_transform.col0.x );
@@ -210,7 +220,7 @@ const char * pathtype( cgltf_animation_path_type type ) {
return "invalid";
}
-static void LoadAnimationReel( MemoryArena * arena, const cgltf_animation * animation, const std::map< const cgltf_node *, size_t > & node_to_joint ) {
+static void LoadAnimationReel( MemoryArena * arena, const cgltf_animation * animation ) {
ggprint( "LoadAnimationReel\n" );
for( size_t i = 0; i < animation->channels_count; i++ ) {
const cgltf_animation_channel * chan = &animation->channels[ i ];
@@ -218,8 +228,8 @@ static void LoadAnimationReel( MemoryArena * arena, const cgltf_animation * anim
ggprint( "channel {} {}\n", i, pathtype( chan->target_path ) );
- ASSERT( node_to_joint.find( chan->target_node ) != node_to_joint.end() );
- size_t joint_idx = node_to_joint.find( chan->target_node )->second;
+ ASSERT( chan->target_node->camera != NULL );
+ u8 joint_idx = u8( uintptr_t( chan->target_node->camera ) - 1 );
ggprint( "interpolation {}\n", sampler->interpolation );
const cgltf_accessor * samples = sampler->output;
@@ -275,7 +285,7 @@ array< const u8 > AccessorToSpan( const cgltf_accessor * accessor ) {
return array< const u8 >( ( const u8 * ) accessor->buffer_view->buffer->data + offset, accessor->count * accessor->stride );
}
-static void LoadNode( MemoryArena * arena, const cgltf_node * node, std::map< const cgltf_node *, size_t > & node_to_joint, int depth ) {
+static void LoadNode( MemoryArena * arena, const cgltf_node * node, bool animated, int depth ) {
MEMARENA_SCOPED_CHECKPOINT( arena );
Mat4 transform;
@@ -290,83 +300,70 @@ static void LoadNode( MemoryArena * arena, const cgltf_node * node, std::map< co
cgltf_node_transform_local( node, &transform.col0.x );
// transform = y_up_to_z_up * transform;
}
- for( int i = 0; i < depth; i++ ) {
- printf( " " );
- }
- printf( "node %p ", node );
- ggprint( "{}\n", transform );
-
- if( node->mesh != NULL ) {
- for( int i = 0; i < depth; i++ ) {
- printf( " " );
- }
- printf( "- mesh\n" );
-
- if( node->skin != NULL ) {
- for( int i = 0; i < depth; i++ ) {
- printf( " " );
- }
- printf( "- skin\n" );
- LoadSkin( node->skin, node_to_joint );
- }
+ for( size_t i = 0; i < node->children_count; i++ ) {
+ LoadNode( arena, node->children[ i ], animated, depth + 1 );
+ }
- ASSERT( node->mesh->primitives_count == 1 );
+ if( node->mesh == NULL )
+ return;
- const cgltf_primitive & prim = node->mesh->primitives[ 0 ];
- ASSERT( prim.indices->component_type == cgltf_component_type_r_16u );
+ if( node->skin != NULL ) {
+ LoadSkin( node->skin );
+ }
- MeshConfig mesh_config;
+ ASSERT( node->mesh->primitives_count == 1 );
- for( size_t j = 0; j < prim.attributes_count; j++ ) {
- const cgltf_attribute & attr = prim.attributes[ j ];
+ const cgltf_primitive & prim = node->mesh->primitives[ 0 ];
- if( attr.type == cgltf_attribute_type_position ) {
- mesh_config.positions = renderer_new_vb( AccessorToSpan( attr.data ) );
+ MeshConfig mesh_config;
- // XXX
- array< v3 > colours = alloc_array< v3 >( arena, attr.data->count );
- for( size_t k = 0; k < attr.data->count; k++ ) {
- colours[ k ] = v3( 1, 1, 1 );
- }
- mesh_config.colours = renderer_new_vb( colours );
- }
+ // TODO: handle packed attributes
+ for( size_t i = 0; i < prim.attributes_count; i++ ) {
+ const cgltf_attribute & attr = prim.attributes[ i ];
- if( attr.type == cgltf_attribute_type_normal ) {
- mesh_config.normals = renderer_new_vb( AccessorToSpan( attr.data ) );
- }
+ if( attr.type == cgltf_attribute_type_position ) {
+ // TODO: if not animated, bake transform into mesh
+ mesh_config.positions = renderer_new_vb( AccessorToSpan( attr.data ) );
- if( attr.type == cgltf_attribute_type_texcoord ) {
- mesh_config.tex_coords0 = renderer_new_vb( AccessorToSpan( attr.data ) );
+ // XXX
+ array< v3 > colours = alloc_array< v3 >( arena, attr.data->count );
+ for( size_t k = 0; k < attr.data->count; k++ ) {
+ colours[ k ] = v3( 1, 1, 1 );
}
+ mesh_config.colours = renderer_new_vb( colours );
+ }
- if( attr.type == cgltf_attribute_type_color ) {
- mesh_config.colours = renderer_new_vb( AccessorToSpan( attr.data ) );
- }
+ if( attr.type == cgltf_attribute_type_normal ) {
+ mesh_config.normals = renderer_new_vb( AccessorToSpan( attr.data ) );
+ }
- // TODO: drop lanes that are never used?
- // TODO: convert to u8
- if( attr.type == cgltf_attribute_type_joints ) {
- mesh_config.joints = renderer_new_vb( AccessorToSpan( attr.data ) );
- }
+ if( attr.type == cgltf_attribute_type_texcoord ) {
+ mesh_config.tex_coords0 = renderer_new_vb( AccessorToSpan( attr.data ) );
+ }
- // TODO: convert to float3 and compute the last weight in the shader
- if( attr.type == cgltf_attribute_type_weights ) {
- mesh_config.weights = renderer_new_vb( AccessorToSpan( attr.data ) );
- }
+ if( attr.type == cgltf_attribute_type_color ) {
+ mesh_config.colours = renderer_new_vb( AccessorToSpan( attr.data ) );
}
- mesh_config.indices = renderer_new_ib( AccessorToSpan( prim.indices ) );
- mesh_config.indices_format = prim.indices->component_type == cgltf_component_type_r_16u ? INDEXFMT_U16 : INDEXFMT_U32;
- mesh_config.num_vertices = prim.indices->count;
+ // TODO: drop lanes that are never used?
+ // TODO: convert to u8
+ if( attr.type == cgltf_attribute_type_joints ) {
+ mesh_config.joints = renderer_new_vb( AccessorToSpan( attr.data ) );
+ }
- model.meshes[ model.num_meshes ] = renderer_new_mesh( mesh_config );
- model.num_meshes++;
+ // TODO: convert to float3 and compute the last weight in the shader
+ if( attr.type == cgltf_attribute_type_weights ) {
+ mesh_config.weights = renderer_new_vb( AccessorToSpan( attr.data ) );
+ }
}
- for( size_t i = 0; i < node->children_count; i++ ) {
- LoadNode( arena, node->children[ i ], node_to_joint, depth + 1 );
- }
+ mesh_config.indices = renderer_new_ib( AccessorToSpan( prim.indices ) );
+ mesh_config.indices_format = prim.indices->component_type == cgltf_component_type_r_16u ? INDEXFMT_U16 : INDEXFMT_U32;
+ mesh_config.num_vertices = prim.indices->count;
+
+ model.meshes[ model.num_meshes ] = renderer_new_mesh( mesh_config );
+ model.num_meshes++;
}
GAME_INIT( game_init ) {
@@ -386,17 +383,16 @@ GAME_INIT( game_init ) {
if( cgltf_validate( data ) != cgltf_result_success )
FATAL( "cgltf_validate" );
- model.num_meshes = 0;
+ ASSERT( data->animations_count <= 1 );
- std::map< const cgltf_node *, size_t > node_to_joint;
+ model.num_meshes = 0;
for( size_t i = 0; i < data->scene->nodes_count; i++ ) {
- LoadNode( &mem->persistent_arena, data->scene->nodes[ i ], node_to_joint, 0 );
+ LoadNode( &mem->persistent_arena, data->scene->nodes[ i ], data->animations_count > 0, 0 );
}
- ASSERT( data->animations_count <= 1 );
if( data->animations_count > 0 ) {
- LoadAnimationReel( &mem->persistent_arena, &data->animations[ 0 ], node_to_joint );
+ LoadAnimationReel( &mem->persistent_arena, &data->animations[ 0 ] );
}
cgltf_free( data );