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();
132 else if( npc
->id
== 4 )
134 if( call
->function
== 0 )
138 if( gui_new_helper( input_button_list
[k_srbind_camera
], &text
))
139 vg_strcat( &text
, "First/Thirdperson" );
141 else if( call
->function
== -1 )
148 if( call
->function
== 0 )
150 world_entity_set_focus( call
->id
);
153 if( gui_new_helper( input_button_list
[k_srbind_maccept
], &text
))
154 vg_strcat( &text
, "Talk to ???" );
156 else if( call
->function
== -1 )
158 world_entity_clear_focus();
163 vg_print_backtrace();
164 vg_error( "Unhandled function id: %i\n", call
->function
);
169 void ent_npc_preupdate( ent_npc
*ent
, int active
)
171 world_instance
*world
= world_current_instance();
175 if( button_down(k_srbind_maccept
) )
177 world_entity_focus_modal();
180 if( gui_new_helper( input_button_list
[k_srbind_mback
], &text
))
181 vg_strcat( &text
, "leave" );
183 volc_start_preview
= vg
.time
;
192 struct skeleton
*sk
= &npc_volc_flight
.skeleton
;
194 f64 t
= (vg
.time
- volc_start_preview
) * 0.5;
195 skeleton_sample_anim_clamped( sk
, anim_tutorial_cam
, t
, pose
.keyframes
);
197 ent_camera
*cam
= mdl_arritm( &world
->ent_camera
,
198 mdl_entity_id_id(ent
->camera
) );
199 v3_copy( pose
.keyframes
[0].co
, cam
->transform
.co
);
202 q_axis_angle( qp
, (v3f
){1,0,0}, VG_TAUf
*0.25f
);
203 q_mul( pose
.keyframes
[0].q
, qp
, cam
->transform
.q
);
204 q_normalize( cam
->transform
.q
);
206 v3_add( ent
->transform
.co
, cam
->transform
.co
, cam
->transform
.co
);
209 world_entity_focus_camera( world
, ent
->camera
);
211 if( button_down( k_srbind_mback
) )
213 world_entity_exit_modal();
214 world_entity_clear_focus();
219 void npc_update( ent_npc
*ent
)
221 if( ent
->id
== 3 ) return;
222 if( ent
->id
== 4 ) return;
224 struct npc
*npc_def
= npc_resolve( ent
->id
);
225 VG_ASSERT( npc_def
);
228 struct skeleton
*sk
= &npc_def
->skeleton
;
229 pose
.type
= k_player_pose_type_ik
;
230 pose
.board
.lean
= 0.0f
;
234 skeleton_sample_anim( sk
, gumpa_idle
, vg
.time
, pose
.keyframes
);
236 else if( ent
->id
== 2 )
238 struct skeleton_anim
*anim
= NULL
;
239 if( ent
->context
== 1 ) anim
= slowmo_momentum
;
240 else if( ent
->context
== 2 ) anim
= slowmo_slide
;
241 else if( ent
->context
== 3 ) anim
= slowmo_rewind
;
245 f32 t
= vg
.time
*0.5f
,
246 animtime
= fmodf( t
*anim
->rate
, anim
->length
),
247 lt
= animtime
/ (f32
)anim
->length
;
248 skeleton_sample_anim( sk
, anim
, t
, pose
.keyframes
);
249 slowmo_opacity
= vg_clampf(fabsf(lt
-0.5f
)*9.0f
-3.0f
,0,1);
252 v3_copy( ent
->transform
.co
, pose
.root_co
);
253 v4_copy( ent
->transform
.q
, pose
.root_q
);
254 apply_full_skeleton_pose( &npc_def
->skeleton
, &pose
, npc_def
->final_mtx
);
257 void npc_render( ent_npc
*ent
, world_instance
*world
, vg_camera
*cam
)
259 if( ent
->id
== 3 ) return;
260 if( ent
->id
== 4 ) return;
262 struct npc
*npc_def
= npc_resolve( ent
->id
);
263 VG_ASSERT( npc_def
);
265 shader_model_character_view_use();
267 glActiveTexture( GL_TEXTURE0
);
268 glBindTexture( GL_TEXTURE_2D
, npc_def
->texture
);
269 shader_model_character_view_uTexMain( 0 );
270 shader_model_character_view_uCamera( cam
->transform
[3] );
271 shader_model_character_view_uPv( cam
->mtx
.pv
);
275 shader_model_character_view_uDepthMode( 2 );
276 shader_model_character_view_uDitherCutoff( slowmo_opacity
);
280 shader_model_character_view_uDepthMode( 0 );
283 WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world
, model_character_view
);
285 glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms
,
286 npc_def
->skeleton
.bone_count
,
288 (const GLfloat
*)npc_def
->final_mtx
);
290 mesh_bind( &npc_def
->mesh
);
291 mesh_draw( &npc_def
->mesh
);