("pstr_name",c_uint32), #AKA Blender NLAStrip name
("pstr_internal_name",c_uint32), #AKA Blender action name
("instance_id",c_uint32),# 0 ... 0xfffffffe, or 0xffffffff
- ("object_id",c_uint32) ] # First class: SR entity ID,
+ ("object_id",c_uint32), # First class: SR entity ID,
# Second class: instance override index
+
+ ("timing_offset",c_float),]
#}
class ms_instance(Structure):
else: return False
#}
+def _sr_metascene_dryrun():
+#{
+ scene = bpy.context.scene
+ frame_prev = bpy.context.scene.frame_current
+
+ def m4_eq( a, b, e=0.0001 ):
+ #{
+ for y in range(4):
+ #{
+ for x in range(4):
+ #{
+ diff = abs( a[y][x] - b[y][x] )
+ if diff > e:
+ return False
+ #}
+ #}
+
+ return True
+ #}
+
+ armatures = [ o for o in bpy.context.scene.objects if o.type == 'ARMATURE' ]
+
+ for am in armatures:
+ #{
+ mtxs = [ Matrix.Identity(4) for _ in am.pose.bones ]
+ frame_start = scene.frame_start
+
+ for frame in range( scene.frame_start, scene.frame_end ):
+ #{
+ bpy.context.scene.frame_set(frame)
+
+ diff = False
+ for i, bone in enumerate(am.pose.bones):
+ #{
+ new_mtx = bone.matrix.copy()
+
+ if not diff:
+ #{
+ if not m4_eq( mtxs[i], new_mtx ):
+ diff = True
+ #}
+
+ mtxs[i] = new_mtx
+ #}
+
+ if diff and (frame != scene.frame_end-1):
+ #{
+ if frame_start == -1:
+ #{
+ frame_start = frame
+ #}
+ #}
+ else:
+ #{
+ if (frame_start != -1) or (diff and (frame == scene.frame_end-1)):
+ #{
+ start = frame_start
+ print( F"New clip ({am.name}): {start}->{frame}" )
+ frame_start = -1
+ #}
+ #}
+ #}
+ #}
+
+ bpy.context.scene.frame_set(frame_prev)
+#}
+
+def _metascene_comp_armature_range( obj, start, end, out_strip ):
+#{
+ bones = [_ for _ in sr_armature_bones( obj )]
+ out_strip.offset = math.floor( start )
+ out_strip.length = math.ceil( end - out_strip.offset )
+ out_strip.timing_offset = 0.0
+ out_strip.data_mode = 0
+ out_strip.data_start = len( _ms_compiler.keyframes )
+ out_strip.data_count = len( bones )
+
+ unfuck = Matrix([(1,0,0,0),(0,0,1,0),(0,-1,0,0),(0,0,0,1)])
+
+ i = 0
+ # Export the keyframes
+ for frame in range(start,end):
+ #{
+ bpy.context.scene.frame_set(frame)
+
+ for rb in bones:
+ #{
+ pb = obj.pose.bones[rb.name]
+
+ # relative bone matrix
+ if rb.parent is not None:
+ #{
+ # Sadly turns out blender bones are retarded...
+ #
+
+ # offset_mtx = rb.parent.matrix_local
+ # offset_mtx = offset_mtx.inverted_safe() @ rb.matrix_local
+ # inv_parent = pb.parent.matrix @ offset_mtx
+ # inv_parent.invert_safe()
+ # fpm = inv_parent @ pb.matrix
+
+ ref_parent_mtx = rb.parent.matrix_local
+ ref_mtx = rb.matrix_local @ unfuck
+ ref = pb.parent.matrix @ ref_parent_mtx.inverted_safe() @ ref_mtx
+ mtx = pb.matrix @ unfuck
+ fpm = ref.inverted_safe() @ mtx
+ #}
+ else:
+ #{
+ bone_mtx = rb.matrix.to_4x4()
+ local_inv = rb.matrix_local.inverted_safe()
+ fpm = bone_mtx @ local_inv @ pb.matrix
+ #}
+
+ loc, rot, sca = fpm.decompose()
+
+ # rotation
+ lc_m = pb.matrix_channel.to_3x3()
+ if pb.parent is not None:
+ #{
+ smtx = pb.parent.matrix_channel.to_3x3()
+ lc_m = smtx.inverted() @ lc_m
+ #}
+ rq = lc_m.to_quaternion()
+ q_normalize( rq )
+
+ kf = mdl_transform()
+ kf.co[0] = loc[0]
+ kf.co[1] = loc[2]
+ kf.co[2] = -loc[1]
+ kf.q[0] = rq[1]
+ kf.q[1] = rq[3]
+ kf.q[2] = -rq[2]
+ kf.q[3] = rq[0]
+ kf.s[0] = 1.0 #sca[0]
+ kf.s[1] = 1.0 #sca[1]
+ kf.s[2] = 1.0 #sca[2]
+
+ _ms_compiler.keyframes.append(kf)
+ #}
+ #}
+#}
+
+def m4_eq( a, b, e=0.0001 ):
+#{
+ for y in range(4):
+ #{
+ for x in range(4):
+ #{
+ diff = abs( a[y][x] - b[y][x] )
+ if diff > e:
+ return False
+ #}
+ #}
+
+ return True
+#}
+
def _metascene_armature_anims( obj, instance_id, override_id ):
#{
bones = [_ for _ in sr_armature_bones(obj)]
- bones_names = [None]+[_.name for _ in bones]
- # So we can restore later
- #
- previous_frame = bpy.context.scene.frame_current
+ scene = bpy.context.scene
+
+ previous_frame = scene.frame_current
previous_action = obj.animation_data.action
previous_pose_position = obj.data.pose_position
obj.data.pose_position = 'POSE'
- for NLALayer in obj.animation_data.nla_tracks:
+ if scene.SR_data.individual:
#{
- for NLAStrip in NLALayer.strips:
+ for NLALayer in obj.animation_data.nla_tracks:
#{
- # set active
- #
- action = NLAStrip.action
- obj.animation_data.action = action
-
- out_strip = ms_strip()
- out_strip.offset = math.floor( NLAStrip.frame_start )
- out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset )
- out_strip.pstr_name = _af_pack_string( NLAStrip.name )
- out_strip.instance_id = instance_id
- out_strip.object_id = override_id
-
- if _metascene_action_cache( out_strip, action ):
+ for NLAStrip in NLALayer.strips:
#{
+ # set active
+ #
+ action = NLAStrip.action
+ obj.animation_data.action = action
+
+ out_strip = ms_strip()
+ out_strip.pstr_name = _af_pack_string( NLAStrip.name )
+ out_strip.pstr_internal_name = _af_pack_string( action.name )
+ out_strip.instance_id = instance_id
+ out_strip.object_id = override_id
+
+ _metascene_comp_armature_range( obj, NLAStrip.frame_start, \
+ NLAStrip.frame_end, out_strip )
+
+ # Disabled because its shit
+ #
+ # if _metascene_action_cache( out_strip, action ):
+ # #{
+ # _ms_compiler.strips.append( out_strip )
+ # continue
+ # #}
+
_ms_compiler.strips.append( out_strip )
- continue
+ print( F"[MS] | anim( {NLAStrip.action.name} )" )
#}
+ #}
+ #}
+ else:
+ #{
+ mtxs = [ Matrix.Identity(4) for _ in obj.pose.bones ]
+ frame_start = scene.frame_start
- out_strip.data_mode = 0
- out_strip.data_start = len( _ms_compiler.keyframes )
- out_strip.data_count = len( bones )
- out_strip.pstr_internal_name = _af_pack_string( action.name )
-
- # Clip to NLA settings
- #
- anim_start = int(NLAStrip.action_frame_start)
- anim_end = int(NLAStrip.action_frame_end)
-
- i = 0
- # Export the keyframes
- for frame in range(anim_start,anim_end):
+ strip_count = 0
+
+ for frame in range( scene.frame_start, scene.frame_end ):
+ #{
+ scene.frame_set(frame)
+
+ diff = False
+ for i, bone in enumerate(obj.pose.bones):
#{
- bpy.context.scene.frame_set(frame)
-
- for rb in bones:
+ new_mtx = bone.matrix.copy()
+
+ if not diff:
#{
- pb = obj.pose.bones[rb.name]
-
- # relative bone matrix
- if rb.parent is not None:
- #{
- offset_mtx = rb.parent.matrix_local
- offset_mtx = offset_mtx.inverted_safe() @ rb.matrix_local
- inv_parent = pb.parent.matrix @ offset_mtx
- inv_parent.invert_safe()
- fpm = inv_parent @ pb.matrix
- #}
- else:
- #{
- bone_mtx = rb.matrix.to_4x4()
- local_inv = rb.matrix_local.inverted_safe()
- fpm = bone_mtx @ local_inv @ pb.matrix
- #}
-
- loc, rot, sca = fpm.decompose()
-
- # rotation
- lc_m = pb.matrix_channel.to_3x3()
- if pb.parent is not None:
- #{
- smtx = pb.parent.matrix_channel.to_3x3()
- lc_m = smtx.inverted() @ lc_m
- #}
- rq = lc_m.to_quaternion()
- q_normalize( rq )
-
- kf = mdl_transform()
- kf.co[0] = loc[0]
- kf.co[1] = loc[2]
- kf.co[2] = -loc[1]
- kf.q[0] = rq[1]
- kf.q[1] = rq[3]
- kf.q[2] = -rq[2]
- kf.q[3] = rq[0]
- kf.s[0] = sca[0]
- kf.s[1] = sca[1]
- kf.s[2] = sca[2]
-
- _ms_compiler.keyframes.append(kf)
+ if not m4_eq( mtxs[i], new_mtx ):
+ diff = True
+ #}
+
+ mtxs[i] = new_mtx
+ #}
+
+ if diff and (frame != scene.frame_end-1):
+ #{
+ if frame_start == -1:
+ #{
+ frame_start = frame
+ #}
+ #}
+ else:
+ #{
+ if (frame_start != -1) or (diff and (frame == scene.frame_end-1)):
+ #{
+ internal_name = F"{obj.name}.{strip_count}"
+
+ out_strip = ms_strip()
+ out_strip.pstr_name = _af_pack_string( F"{obj.name}(amalg)" )
+ out_strip.pstr_internal_name = _af_pack_string( internal_name )
+ out_strip.instance_id = instance_id
+ out_strip.object_id = override_id
+
+ _metascene_comp_armature_range( obj, frame_start, frame, \
+ out_strip )
+ _ms_compiler.strips.append( out_strip )
+
+ print( F"[MS] | anim( {internal_name} )" )
+
+ strip_count += 1
+ frame_start = -1
#}
#}
-
- # Add to animation buffer
- #
- _ms_compiler.strips.append( out_strip )
- print( F"[MS] | anim( {NLAStrip.action.name} )" )
- _ms_compiler.action_cache[ action.name ] = out_strip
#}
#}
-
- # Restore context to how it was before
- #
- bpy.context.scene.frame_set( previous_frame )
+
+ scene.frame_set( previous_frame )
obj.animation_data.action = previous_action
obj.data.pose_position = previous_pose_position
#}
_ms_compiler.curve_keyframes.append(out_keyframe)
out_track.keyframe_count += 1
#}
+
+ print( F" Added {out_track.keyframe_count} keyframes" )
_ms_compiler.tracks.append( out_track )
#}
#
def _metascene_camera_anims( obj, entity_id ):
#{
- if obj.animation_data == None: return
-
- for NLALayer in obj.animation_data.nla_tracks:
+ if obj.animation_data:
#{
- print( F" looking into {NLALayer.name}" )
- for NLAStrip in NLALayer.strips:
+ for NLALayer in obj.animation_data.nla_tracks:
#{
- print( F" have strip {NLAStrip.name}" )
+ print( F" looking into {NLALayer.name}" )
+ for NLAStrip in NLALayer.strips:
+ #{
+ print( F" have strip {NLAStrip.name}" )
- out_strip = ms_strip()
- _metascene_compile_action_curves( out_strip, NLAStrip.action )
- out_strip.instance_id = 0xffffffff
- out_strip.object_id = entity_id
- out_strip.offset = math.floor( NLAStrip.frame_start )
- out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset )
- out_strip.pstr_name = _af_pack_string( NLAStrip.name )
+ out_strip = ms_strip()
+ _metascene_compile_action_curves( out_strip, NLAStrip.action )
+ out_strip.instance_id = 0xffffffff
+ out_strip.object_id = entity_id
+ out_strip.offset = math.floor( NLAStrip.frame_start )
+ out_strip.timing_offset = NLAStrip.action_frame_start
+ out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset )
+ out_strip.pstr_name = _af_pack_string( NLAStrip.name )
- _ms_compiler.strips.append( out_strip )
+ _ms_compiler.strips.append( out_strip )
+ #}
#}
#}
- for NLALayer in obj.data.animation_data.nla_tracks:
+ if obj.data.animation_data:
#{
- print( F" looking into {NLALayer.name}" )
- for NLAStrip in NLALayer.strips:
+ for NLALayer in obj.data.animation_data.nla_tracks:
#{
- print( F" have strip {NLAStrip.name}" )
- out_strip = ms_strip()
- _metascene_compile_action_curves( out_strip, NLAStrip.action )
- out_strip.instance_id = 0xffffffff
- out_strip.object_id = entity_id
- out_strip.offset = math.floor( NLAStrip.frame_start )
- out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset )
- out_strip.pstr_name = _af_pack_string( NLAStrip.name )
- _ms_compiler.strips.append( out_strip )
+ print( F" looking into {NLALayer.name}" )
+ for NLAStrip in NLALayer.strips:
+ #{
+ print( F" have strip {NLAStrip.name}" )
+ out_strip = ms_strip()
+ _metascene_compile_action_curves( out_strip, NLAStrip.action )
+ out_strip.instance_id = 0xffffffff
+ out_strip.object_id = entity_id
+ out_strip.offset = math.floor( NLAStrip.frame_start )
+ out_strip.timing_offset = NLAStrip.action_frame_start
+ out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset )
+ out_strip.pstr_name = _af_pack_string( NLAStrip.name )
+ _ms_compiler.strips.append( out_strip )
+ #}
#}
#}
#}
ent_camera *cam = af_arritm( &_cutscene.meta.cameras, asoc->entity_index );
- vg_info( "Linking %d#%d:'%s'\n",
- asoc->entity_type, asoc->entity_index, datapath );
-
struct
{
const char *prefix;
i32 offset = atoi( datapath + len );
out_link->target = reference[i].arr + offset;
out_link->semantic_type = reference[i].semantic + offset;
+
+ vg_info( "Linked %d#%d:'%s'\n",
+ asoc->entity_type, asoc->entity_index, datapath );
return 1;
}
}
+ vg_warn( "Failed link %d#%d:'%s'\n",
+ asoc->entity_type, asoc->entity_index, datapath );
+
return 0;
}
}
else
_cutscene.active_camera = NULL;
+
+ const char *marker = af_str( &_cutscene.meta.af, strip->pstr_name );
+ _skaterift_script_marker( marker );
+ vg_info( "Cutscene marker: %s\n", marker );
}
else
{
if( strip->instance_id == 0xffffffff )
{
+ vg_info( "+ Strip: '%s' entity: %u\n",
+ af_str( &_cutscene.meta.af, strip->pstr_name ),
+ strip->object_id );
/* internal link */
struct cs_asoc asoc;
_cutscene_get_strip_asoc( strip, &asoc );
{
ms_track *track = af_arritm( &_cutscene.meta.tracks,
strip->data_start + j );
+
+ const char *datapath =
+ af_str( &_cutscene.meta.af, track->pstr_datapath );
+
+ struct cs_link_info link;
+ if( !link_internal_datapath( &asoc, datapath, &link ) )
+ continue;
VG_ASSERT( _cutscene.active_samplers <
VG_ARRAY_LEN(_cutscene.samplers) );
samp->strip = strip;
samp->curves.track = track;
- const char *datapath =
- af_str( &_cutscene.meta.af, track->pstr_datapath );
-
- struct cs_link_info link;
- VG_ASSERT( link_internal_datapath( &asoc, datapath, &link ) );
-
samp->curves.target = link.target;
samp->curves.semantic = link.semantic_type;
samp->curves.keyframe = 0;
m4x3f *final_mtx = samp->skeleton.skinning_data;
ms_keyframe pose[32];
- skeleton_sample_anim( ref_sk, &temp_anim, t, pose );
+ skeleton_sample_anim_clamped( ref_sk, &temp_anim, t, pose );
skeleton_apply_pose( ref_sk, pose,
k_anim_apply_defer_ik, final_mtx );
mdl_transform_m4x3( &samp->override->transform, mmdl );
skeleton_apply_transform( ref_sk, mmdl, final_mtx );
}
+
+ skeleton_debug( ref_sk, final_mtx );
}
else
{
f32 scene_t = _cutscene.time * _cutscene.meta.info.framerate,
- t = scene_t - samp->strip->offset;
+ t = (f32)(scene_t - samp->strip->offset) + samp->strip->timing_offset;
ms_curve_keyframe *kl = af_arritm( &_cutscene.meta.curves,
samp->curves.track->keyframe_start + samp->curves.keyframe ),
enum escript_event
{
k_escript_event_call = 0,
- k_escript_event_update = 1
+ k_escript_event_update = 1,
+ k_escript_event_cutscene_marker = 2
};
/* you can add anything you want to this. */
k_escript_state_end
};
+extern m4x3f *_TEMP_VAR;
+
/* This is the development one */
-static bool _skaterift_script_test( enum escript_event ev )
+static bool _skaterift_script_test( enum escript_event ev, const char *inf )
{
static u32 state;
static struct cs_instance *override_inst;
+ static m4x3f *action_cam;
+ static bool action_mode;
if( ev == k_escript_event_call )
{
state = k_escript_state_loading;
override_inst = NULL;
+ action_cam = NULL;
+ action_mode = 0;
vg_info( "test:state = loading\n" );
}
+ if( ev == k_escript_event_cutscene_marker )
+ {
+ if( vg_str_eq( inf, "action_cam" ) )
+ action_mode = 1;
+
+ return 0;
+ }
+
/* scene
* --------------------------------------------------------------- */
{
if( _cutscene.state == k_cutscene_state_ready )
{
- override_inst = _cutscene_get_first_model_instance(
- "playermodels/skaterift_john/ch_john" );
+ override_inst = _cutscene_get_first_model_instance( "models/ch_none" );
+
+ if( !override_inst )
+ {
+ vg_error( "test: Failed to find player target" );
+ return 1;
+ }
+
+ struct cs_instance *boogie_inst =
+ _cutscene_get_first_model_instance( "models/boogie_van" );
- if( override_inst )
+ if( boogie_inst )
{
- state = k_escript_state_playing;
- vg_info( "test:state = playing\n" );
- _cutscene.player_binding = override_inst;
- _cutscene_play();
+ struct model_ref *mref = &_cutscene.refs[ boogie_inst->ref_id ];
+ struct skeleton *sk = &mref->skeletons[0].sk;
+
+ for( u32 i=0; i<sk->bone_count; i ++ )
+ {
+ vg_info( "%s\n", sk->bones[i].name );
+ if( !strcmp( sk->bones[i].name, "action_cam" ) )
+ {
+ action_cam = boogie_inst->skinning_data + i;
+ break;
+ }
+ }
+
+ if( action_cam == NULL )
+ {
+ vg_error( "test: Failed to find action cam bone" );
+ return 1;
+ }
}
else
{
- vg_error( "test: Failed to find player target" );
+ vg_error( "test: Failed to find boogie van" );
return 1;
}
+
+ state = k_escript_state_playing;
+ vg_info( "test:state = playing\n" );
+ _cutscene.player_binding = override_inst;
+ _cutscene_play();
}
}
_cutscene_unload();
return 1;
}
+ else
+ {
+ if( action_mode )
+ _TEMP_VAR = action_cam;
+ }
}
return 0;
struct script_binding
{
const char *alias;
- bool( *jump )( enum escript_event ev );
+ bool( *jump )( enum escript_event ev, const char *inf );
}
_script_bindings[] =
{
if( vg_str_eq( argv[0], bind->alias ) )
{
_script.script_id = i;
- if( bind->jump( k_escript_event_call ) )
+ if( bind->jump( k_escript_event_call, NULL ) )
_script.script_id = k_escript_script_id_max;
return 1;
{
if( _script.script_id != k_escript_script_id_max )
{
- if( _script_bindings[ _script.script_id ].jump( k_escript_event_update ) )
+ if( _script_bindings[ _script.script_id ].jump( k_escript_event_update,
+ NULL ) )
+ _script.script_id = k_escript_script_id_max;
+ }
+}
+
+void _skaterift_script_marker( const char *marker )
+{
+ if( _script.script_id != k_escript_script_id_max )
+ {
+ if( _script_bindings[ _script.script_id ].jump(
+ k_escript_event_cutscene_marker, marker) )
_script.script_id = k_escript_script_id_max;
}
}