3 #include "shaders/model_character_view.h"
8 struct npc npc_gumpa
, npc_slowmo
, npc_volc_flight
;
9 static struct skeleton_anim
*gumpa_idle
;
10 static struct skeleton_anim
*slowmo_momentum
, *slowmo_slide
, *slowmo_rewind
,
12 static float slowmo_opacity
= 0.0f
;
13 static f64 volc_start_preview
= 0.0;
15 void npc_load_model( struct npc
*npc
, const char *path
)
17 vg_linear_clear( vg_mem
.scratch
);
19 mdl_context
*meta
= &npc
->meta
;
20 mdl_open( meta
, path
, vg_mem
.rtmemory
);
21 mdl_load_metadata_block( meta
, vg_mem
.rtmemory
);
22 mdl_load_animation_block( meta
, vg_mem
.rtmemory
);
24 struct skeleton
*sk
= &npc
->skeleton
;
25 skeleton_setup( sk
, vg_mem
.rtmemory
, meta
);
27 u32 mtx_size
= sizeof(m4x3f
)*sk
->bone_count
;
28 npc
->final_mtx
= vg_linear_alloc( vg_mem
.rtmemory
, mtx_size
);
30 if( mdl_arrcount( &meta
->textures
) )
32 mdl_texture
*tex0
= mdl_arritm( &meta
->textures
, 0 );
33 void *data
= vg_linear_alloc( vg_mem
.scratch
, tex0
->file
.pack_size
);
34 mdl_fread_pack_file( meta
, &tex0
->file
, data
);
36 vg_tex2d_load_qoi_async( data
, tex0
->file
.pack_size
,
37 VG_TEX2D_NEAREST
|VG_TEX2D_CLAMP
,
42 npc
->texture
= vg
.tex_missing
;
45 mdl_async_load_glmesh( meta
, &npc
->mesh
, NULL
);
51 npc_load_model( &npc_gumpa
, "models/gumpa.mdl" );
52 gumpa_idle
= skeleton_get_anim( &npc_gumpa
.skeleton
, "gumpa_idle" );
54 npc_load_model( &npc_slowmo
, "models/slowmos.mdl" );
56 skeleton_get_anim( &npc_slowmo
.skeleton
, "slowmo_momentum" );
57 slowmo_slide
= skeleton_get_anim( &npc_slowmo
.skeleton
, "slowmo_slide" );
58 slowmo_rewind
= skeleton_get_anim( &npc_slowmo
.skeleton
, "slowmo_rewind" );
60 npc_load_model( &npc_volc_flight
, "models/volc_flight.mdl" );
62 skeleton_get_anim( &npc_volc_flight
.skeleton
, "tutorial" );
65 static struct npc
*npc_resolve( u32 id
)
67 if( id
== 1 ) return &npc_gumpa
;
68 else if( id
== 2 ) return &npc_slowmo
;
69 else if( id
== 3 ) return &npc_volc_flight
;
73 static void npc_slowmo_call( ent_npc
*npc
, ent_call
*call
)
75 if( call
->function
== 0 )
80 if( npc
->context
== 2 )
82 if( gui_new_helper( input_axis_list
[k_sraxis_grab
], &text
))
83 vg_strcat( &text
, "Crouch (store energy)" );
84 if( gui_new_helper( input_joy_list
[k_srjoystick_steer
], &text
))
85 vg_strcat( &text
, "Slide" );
87 else if( npc
->context
== 1 )
89 if( gui_new_helper( input_axis_list
[k_sraxis_grab
], &text
))
90 vg_strcat( &text
, "Crouch (store energy)" );
92 else if( npc
->context
== 3 )
94 if( gui_new_helper( input_button_list
[k_srbind_reset
], &text
))
95 vg_strcat( &text
, "Rewind time" );
96 if( gui_new_helper( input_button_list
[k_srbind_replay_resume
], &text
))
97 vg_strcat( &text
, "Resume" );
100 else if( call
->function
== -1 )
102 world_entity_clear_focus();
107 void ent_npc_call( world_instance
*world
, ent_call
*call
)
109 u32 index
= mdl_entity_id_id( call
->id
);
110 ent_npc
*npc
= mdl_arritm( &world
->ent_npc
, index
);
114 npc_slowmo_call( npc
, call
);
116 else if( npc
->id
== 3 )
118 if( call
->function
== 0 )
120 world_entity_set_focus( call
->id
);
123 if( gui_new_helper( input_button_list
[k_srbind_maccept
], &text
))
124 vg_strcat( &text
, "Preview course" );
126 else if( call
->function
== -1 )
128 world_entity_clear_focus();
134 if( call
->function
== 0 )
136 world_entity_set_focus( call
->id
);
139 if( gui_new_helper( input_button_list
[k_srbind_maccept
], &text
))
140 vg_strcat( &text
, "Talk to ???" );
142 else if( call
->function
== -1 )
144 world_entity_clear_focus();
149 vg_print_backtrace();
150 vg_error( "Unhandled function id: %i\n", call
->function
);
155 void ent_npc_preupdate( ent_npc
*ent
, int active
)
157 world_instance
*world
= world_current_instance();
161 if( button_down(k_srbind_maccept
) )
163 world_entity_focus_modal();
166 if( gui_new_helper( input_button_list
[k_srbind_mback
], &text
))
167 vg_strcat( &text
, "leave" );
169 volc_start_preview
= vg
.time
;
178 struct skeleton
*sk
= &npc_volc_flight
.skeleton
;
180 f64 t
= (vg
.time
- volc_start_preview
) * 0.5;
181 skeleton_sample_anim_clamped( sk
, anim_tutorial_cam
, t
, pose
.keyframes
);
183 ent_camera
*cam
= mdl_arritm( &world
->ent_camera
,
184 mdl_entity_id_id(ent
->camera
) );
185 v3_copy( pose
.keyframes
[0].co
, cam
->transform
.co
);
188 q_axis_angle( qp
, (v3f
){1,0,0}, VG_TAUf
*0.25f
);
189 q_mul( pose
.keyframes
[0].q
, qp
, cam
->transform
.q
);
190 q_normalize( cam
->transform
.q
);
192 v3_add( ent
->transform
.co
, cam
->transform
.co
, cam
->transform
.co
);
195 world_entity_focus_camera( world
, ent
->camera
);
197 if( button_down( k_srbind_mback
) )
199 world_entity_exit_modal();
200 world_entity_clear_focus();
205 void npc_update( ent_npc
*ent
)
207 if( ent
->id
== 3 ) return;
209 struct npc
*npc_def
= npc_resolve( ent
->id
);
210 VG_ASSERT( npc_def
);
213 struct skeleton
*sk
= &npc_def
->skeleton
;
214 pose
.type
= k_player_pose_type_ik
;
215 pose
.board
.lean
= 0.0f
;
219 skeleton_sample_anim( sk
, gumpa_idle
, vg
.time
, pose
.keyframes
);
221 else if( ent
->id
== 2 )
223 struct skeleton_anim
*anim
= NULL
;
224 if( ent
->context
== 1 ) anim
= slowmo_momentum
;
225 else if( ent
->context
== 2 ) anim
= slowmo_slide
;
226 else if( ent
->context
== 3 ) anim
= slowmo_rewind
;
230 f32 t
= vg
.time
*0.5f
,
231 animtime
= fmodf( t
*anim
->rate
, anim
->length
),
232 lt
= animtime
/ (f32
)anim
->length
;
233 skeleton_sample_anim( sk
, anim
, t
, pose
.keyframes
);
234 slowmo_opacity
= vg_clampf(fabsf(lt
-0.5f
)*9.0f
-3.0f
,0,1);
237 v3_copy( ent
->transform
.co
, pose
.root_co
);
238 v4_copy( ent
->transform
.q
, pose
.root_q
);
239 apply_full_skeleton_pose( &npc_def
->skeleton
, &pose
, npc_def
->final_mtx
);
242 void npc_render( ent_npc
*ent
, world_instance
*world
, vg_camera
*cam
)
244 if( ent
->id
== 3 ) return;
246 struct npc
*npc_def
= npc_resolve( ent
->id
);
247 VG_ASSERT( npc_def
);
249 shader_model_character_view_use();
251 glActiveTexture( GL_TEXTURE0
);
252 glBindTexture( GL_TEXTURE_2D
, npc_def
->texture
);
253 shader_model_character_view_uTexMain( 0 );
254 shader_model_character_view_uCamera( cam
->transform
[3] );
255 shader_model_character_view_uPv( cam
->mtx
.pv
);
259 shader_model_character_view_uDepthMode( 2 );
260 shader_model_character_view_uDitherCutoff( slowmo_opacity
);
264 shader_model_character_view_uDepthMode( 0 );
267 WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world
, model_character_view
);
269 glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms
,
270 npc_def
->skeleton
.bone_count
,
272 (const GLfloat
*)npc_def
->final_mtx
);
274 mesh_bind( &npc_def
->mesh
);
275 mesh_draw( &npc_def
->mesh
);