2015-12-12 17:52:06 +00:00
# include "keyframemanager.hpp"
# include <components/vfs/manager.hpp>
2020-11-18 23:11:56 +00:00
# include <osgAnimation/Animation>
# include <osgAnimation/BasicAnimationManager>
# include <osgAnimation/Channel>
2020-11-18 20:48:47 +00:00
# include <components/nifosg/nifloader.hpp>
2020-11-18 23:11:56 +00:00
# include <components/sceneutil/keyframe.hpp>
# include <components/sceneutil/osgacontroller.hpp>
2020-11-18 20:48:47 +00:00
2020-11-18 23:11:56 +00:00
# include "animation.hpp"
2015-12-12 17:52:06 +00:00
# include "objectcache.hpp"
2020-11-18 20:48:47 +00:00
# include "scenemanager.hpp"
2020-11-28 13:03:10 +00:00
namespace Resource
2020-11-18 20:48:47 +00:00
{
2020-11-18 23:11:56 +00:00
RetrieveAnimationsVisitor : : RetrieveAnimationsVisitor ( SceneUtil : : KeyframeHolder & target , osg : : ref_ptr < osgAnimation : : BasicAnimationManager > animationManager ) : osg : : NodeVisitor ( TRAVERSE_ALL_CHILDREN ) , mTarget ( target ) , mAnimationManager ( animationManager ) { }
2020-11-18 20:48:47 +00:00
2020-11-18 23:11:56 +00:00
void RetrieveAnimationsVisitor : : apply ( osg : : Node & node )
{
2020-12-15 11:51:49 +00:00
if ( node . libraryName ( ) = = std : : string ( " osgAnimation " ) & & node . className ( ) = = std : : string ( " Bone " ) & & node . getName ( ) = = std : : string ( " bip01 " ) )
2020-11-18 23:11:56 +00:00
{
2020-11-28 13:03:10 +00:00
osg : : ref_ptr < SceneUtil : : OsgAnimationController > callback = new SceneUtil : : OsgAnimationController ( ) ;
2020-11-18 23:11:56 +00:00
2020-11-28 13:03:10 +00:00
std : : vector < SceneUtil : : EmulatedAnimation > emulatedAnimations ;
2020-11-18 23:11:56 +00:00
for ( auto animation : mAnimationManager - > getAnimationList ( ) )
{
if ( animation )
{
if ( animation - > getName ( ) = = " Default " ) //"Default" is osg dae plugin's default naming scheme for unnamed animations
{
animation - > setName ( std : : string ( " idle " ) ) ; // animation naming scheme "idle: start" and "idle: stop" is the default idle animation that OpenMW seems to want to play
}
osg : : ref_ptr < Resource : : Animation > mergedAnimationTrack = new Resource : : Animation ;
std : : string animationName = animation - > getName ( ) ;
std : : string start = animationName + std : : string ( " : start " ) ;
std : : string stop = animationName + std : : string ( " : stop " ) ;
const osgAnimation : : ChannelList & channels = animation - > getChannels ( ) ;
2020-12-12 20:23:20 +00:00
for ( const auto & channel : channels )
2020-11-18 23:11:56 +00:00
{
mergedAnimationTrack - > addChannel ( channel . get ( ) - > clone ( ) ) ; // is ->clone needed?
}
mergedAnimationTrack - > setName ( animation - > getName ( ) ) ;
callback - > addMergedAnimationTrack ( mergedAnimationTrack ) ;
float startTime = animation - > getStartTime ( ) ;
float stopTime = startTime + animation - > getDuration ( ) ;
// mTextKeys is a nif-thing, used by OpenMW's animation system
// Format is likely "AnimationName: [Keyword_optional] [Start OR Stop]"
// AnimationNames are keywords like idle2, idle3... AiPackages and various mechanics control which animations are played
// Keywords can be stuff like Loop, Equip, Unequip, Block, InventoryHandtoHand, InventoryWeaponOneHand, PickProbe, Slash, Thrust, Chop... even "Slash Small Follow"
mTarget . mTextKeys . emplace ( startTime , std : : move ( start ) ) ;
mTarget . mTextKeys . emplace ( stopTime , std : : move ( stop ) ) ;
2020-11-28 13:03:10 +00:00
SceneUtil : : EmulatedAnimation emulatedAnimation ;
2020-11-18 23:11:56 +00:00
emulatedAnimation . mStartTime = startTime ;
emulatedAnimation . mStopTime = stopTime ;
emulatedAnimation . mName = animationName ;
emulatedAnimations . emplace_back ( emulatedAnimation ) ;
}
}
callback - > setEmulatedAnimations ( emulatedAnimations ) ;
mTarget . mKeyframeControllers . emplace ( node . getName ( ) , callback ) ;
}
2020-11-18 20:48:47 +00:00
2020-11-18 23:11:56 +00:00
traverse ( node ) ;
}
2020-11-18 20:48:47 +00:00
}
2015-12-12 17:52:06 +00:00
namespace Resource
{
2020-11-18 20:48:47 +00:00
KeyframeManager : : KeyframeManager ( const VFS : : Manager * vfs , SceneManager * sceneManager )
2016-02-06 15:57:54 +00:00
: ResourceManager ( vfs )
2020-11-18 20:48:47 +00:00
, mSceneManager ( sceneManager )
2015-12-12 17:52:06 +00:00
{
}
KeyframeManager : : ~ KeyframeManager ( )
{
}
2020-11-18 20:48:47 +00:00
osg : : ref_ptr < const SceneUtil : : KeyframeHolder > KeyframeManager : : get ( const std : : string & name )
2015-12-12 17:52:06 +00:00
{
std : : string normalized = name ;
mVFS - > normalizeFilename ( normalized ) ;
osg : : ref_ptr < osg : : Object > obj = mCache - > getRefFromObjectCache ( normalized ) ;
if ( obj )
2020-11-18 20:48:47 +00:00
return osg : : ref_ptr < const SceneUtil : : KeyframeHolder > ( static_cast < SceneUtil : : KeyframeHolder * > ( obj . get ( ) ) ) ;
2015-12-12 17:52:06 +00:00
else
{
2020-11-18 20:48:47 +00:00
osg : : ref_ptr < SceneUtil : : KeyframeHolder > loaded ( new SceneUtil : : KeyframeHolder ) ;
2020-11-28 13:03:10 +00:00
std : : string ext = Resource : : getFileExtension ( normalized ) ;
2020-11-18 20:48:47 +00:00
if ( ext = = " kf " )
{
NifOsg : : Loader : : loadKf ( Nif : : NIFFilePtr ( new Nif : : NIFFile ( mVFS - > getNormalized ( normalized ) , normalized ) ) , * loaded . get ( ) ) ;
}
else
{
2020-11-18 23:11:56 +00:00
osg : : ref_ptr < osg : : Node > scene = const_cast < osg : : Node * > ( mSceneManager - > getTemplate ( normalized ) . get ( ) ) ;
osg : : ref_ptr < osgAnimation : : BasicAnimationManager > bam = dynamic_cast < osgAnimation : : BasicAnimationManager * > ( scene - > getUpdateCallback ( ) ) ;
2020-11-20 17:46:08 +00:00
if ( bam )
{
2020-11-28 13:03:10 +00:00
Resource : : RetrieveAnimationsVisitor rav ( * loaded . get ( ) , bam ) ;
2020-11-20 17:46:08 +00:00
scene - > accept ( rav ) ;
}
2020-11-18 20:48:47 +00:00
}
2015-12-14 14:11:06 +00:00
mCache - > addEntryToObjectCache ( normalized , loaded ) ;
2015-12-12 17:52:06 +00:00
return loaded ;
}
}
2017-03-07 03:02:06 +00:00
void KeyframeManager : : reportStats ( unsigned int frameNumber , osg : : Stats * stats ) const
2017-02-22 01:18:18 +00:00
{
stats - > setAttribute ( frameNumber , " Keyframe " , mCache - > getCacheSize ( ) ) ;
}
2015-12-12 17:52:06 +00:00
}