@ -48,7 +48,53 @@ float ControllerFunction::calculate(float value)
return value ;
}
osg : : Quat KeyframeControllerValue : : interpKey ( const Nif : : QuaternionKeyMap : : MapType & keys , float time )
FrameTimeSource : : FrameTimeSource ( )
: mLastTime ( 0.0 )
{
}
float FrameTimeSource : : getValue ( osg : : NodeVisitor * nv )
{
// TODO: dt could be computed globally instead of once per instance
double time = nv - > getFrameStamp ( ) - > getReferenceTime ( ) ;
float dt = static_cast < float > ( time - mLastTime ) ;
mLastTime = time ;
return dt ;
}
KeyframeController : : KeyframeController ( )
{
}
KeyframeController : : KeyframeController ( const KeyframeController & copy , const osg : : CopyOp & copyop )
: osg : : NodeCallback ( copy , copyop )
, Controller ( copy )
, mRotations ( copy . mRotations )
, mXRotations ( copy . mXRotations )
, mYRotations ( copy . mYRotations )
, mZRotations ( copy . mZRotations )
, mTranslations ( copy . mTranslations )
, mScales ( copy . mScales )
, mNif ( copy . mNif )
, mInitialQuat ( copy . mInitialQuat )
, mInitialScale ( copy . mInitialScale )
{
}
KeyframeController : : KeyframeController ( const Nif : : NIFFilePtr & nif , const Nif : : NiKeyframeData * data ,
osg : : Quat initialQuat , float initialScale )
: mRotations ( & data - > mRotations )
, mXRotations ( & data - > mXRotations )
, mYRotations ( & data - > mYRotations )
, mZRotations ( & data - > mZRotations )
, mTranslations ( & data - > mTranslations )
, mScales ( & data - > mScales )
, mNif ( nif )
, mInitialQuat ( initialQuat )
, mInitialScale ( initialScale )
{ }
osg : : Quat KeyframeController : : interpKey ( const Nif : : QuaternionKeyMap : : MapType & keys , float time )
{
if ( time < = keys . begin ( ) - > first )
return keys . begin ( ) - > second . mValue ;
@ -81,7 +127,7 @@ osg::Quat KeyframeControllerValue::interpKey(const Nif::QuaternionKeyMap::MapTyp
return keys . rbegin ( ) - > second . mValue ;
}
osg : : Quat KeyframeController Value : : getXYZRotation ( float time ) const
osg : : Quat KeyframeController : : getXYZRotation ( float time ) const
{
float xrot = interpKey ( mXRotations - > mKeys , time ) ;
float yrot = interpKey ( mYRotations - > mKeys , time ) ;
@ -92,96 +138,108 @@ osg::Quat KeyframeControllerValue::getXYZRotation(float time) const
return ( zr * yr * xr ) ;
}
KeyframeControllerValue : : KeyframeControllerValue ( osg : : Node * target , const Nif : : NIFFilePtr & nif , const Nif : : NiKeyframeData * data ,
osg : : Quat initialQuat , float initialScale )
: NodeTargetValue ( target )
, mRotations ( & data - > mRotations )
, mXRotations ( & data - > mXRotations )
, mYRotations ( & data - > mYRotations )
, mZRotations ( & data - > mZRotations )
, mTranslations ( & data - > mTranslations )
, mScales ( & data - > mScales )
, mNif ( nif )
, mInitialQuat ( initialQuat )
, mInitialScale ( initialScale )
{ }
osg : : Vec3f KeyframeControllerValue : : getTranslation ( float time ) const
osg : : Vec3f KeyframeController : : getTranslation ( float time ) const
{
if ( mTranslations - > mKeys . size ( ) > 0 )
return interpKey ( mTranslations - > mKeys , time ) ;
osg : : MatrixTransform * trans = static_cast < osg : : MatrixTransform * > ( mNode ) ;
return trans - > getMatrix ( ) . getTrans ( ) ;
return osg : : Vec3f ( ) ;
}
void KeyframeController Value: : setValue ( float time )
void KeyframeController : : operator ( ) ( osg : : Node * node , osg : : NodeVisitor * nv )
{
osg : : MatrixTransform * trans = static_cast < osg : : MatrixTransform * > ( mNode ) ;
osg : : Matrix mat = trans - > getMatrix ( ) ;
if ( mRotations - > mKeys . size ( ) > 0 )
mat . setRotate ( interpKey ( mRotations - > mKeys , time ) ) ;
else if ( ! mXRotations - > mKeys . empty ( ) | | ! mYRotations - > mKeys . empty ( ) | | ! mZRotations - > mKeys . empty ( ) )
mat . setRotate ( getXYZRotation ( time ) ) ;
else
mat . setRotate ( mInitialQuat ) ;
// let's hope no one's using multiple KeyframeControllers on the same node (not that would make any sense...)
float scale = mInitialScale ;
if ( mScales - > mKeys . size ( ) > 0 )
scale = interpKey ( mScales - > mKeys , time ) ;
if ( hasInput ( ) )
{
osg : : MatrixTransform * trans = static_cast < osg : : MatrixTransform * > ( node ) ;
osg : : Matrix mat = trans - > getMatrix ( ) ;
float time = getInputValue ( nv ) ;
if ( mRotations - > mKeys . size ( ) > 0 )
mat . setRotate ( interpKey ( mRotations - > mKeys , time ) ) ;
else if ( ! mXRotations - > mKeys . empty ( ) | | ! mYRotations - > mKeys . empty ( ) | | ! mZRotations - > mKeys . empty ( ) )
mat . setRotate ( getXYZRotation ( time ) ) ;
else
mat . setRotate ( mInitialQuat ) ;
// let's hope no one's using multiple KeyframeControllers on the same node (not that would make any sense...)
float scale = mInitialScale ;
if ( mScales - > mKeys . size ( ) > 0 )
scale = interpKey ( mScales - > mKeys , time ) ;
for ( int i = 0 ; i < 3 ; + + i )
for ( int j = 0 ; j < 3 ; + + j )
mat ( i , j ) * = scale ;
if ( mTranslations - > mKeys . size ( ) > 0 )
mat . setTrans ( interpKey ( mTranslations - > mKeys , time ) ) ;
trans - > setMatrix ( mat ) ;
}
for ( int i = 0 ; i < 3 ; + + i )
for ( int j = 0 ; j < 3 ; + + j )
mat ( i , j ) * = scale ;
traverse ( node , nv ) ;
}
if ( mTranslations - > mKeys . size ( ) > 0 )
mat . setTrans ( interpKey ( mTranslations - > mKeys , time ) ) ;
trans - > setMatrix ( mat ) ;
Controller : : Controller ( )
{
}
Controller : : Controller ( boost : : shared_ptr < ControllerSource > src , boost : : shared_ptr < ControllerValue > dest , boost : : shared_ptr < ControllerFunction > function )
: mSource ( src )
, mDestValue ( dest )
, mFunction ( function )
bool Controller : : hasInput ( ) const
{
return mSource . get ( ) ! = NULL ;
}
float Controller : : getInputValue ( osg : : NodeVisitor * nv )
{
return mFunction - > calculate ( mSource - > getValue ( nv ) ) ;
}
void Controller : : update ( )
GeomMorpherController : : GeomMorpherController ( )
{
if ( mSource . get ( ) )
{
mDestValue - > setValue ( mFunction - > calculate ( mSource - > getValue ( ) ) ) ;
}
}
GeomMorpherControllerValue : : GeomMorpherControllerValue ( osgAnimation : : MorphGeometry * geom , const Nif : : NiMorphData * morphData )
: mGeom ( geom )
, mMorphs ( morphData - > mMorphs )
GeomMorpherController : : GeomMorpherController ( const GeomMorpherController & copy , const osg : : CopyOp & copyop )
: osg : : Drawable : : UpdateCallback ( copy , copyop )
, Controller ( copy )
, mMorphs ( copy . mMorphs )
{
}
GeomMorpherController : : GeomMorpherController ( const Nif : : NiMorphData * data )
: mMorphs ( data - > mMorphs )
{
}
void GeomMorpherControllerValue : : setValue ( float time )
void GeomMorpherController : : update ( osg : : NodeVisitor * nv , osg : : Drawable * drawabl e)
{
if ( mMorphs . size ( ) < = 1 )
return ;
int i = 0 ;
for ( std : : vector < Nif : : NiMorphData : : MorphData > : : iterator it = mMorphs . begin ( ) + 1 ; it ! = mMorphs . end ( ) ; + + it , + + i )
osgAnimation : : MorphGeometry * morphGeom = dynamic_cast < osgAnimation : : MorphGeometry * > ( drawable ) ;
if ( morphGeom )
{
float val = 0 ;
if ( ! it - > mData . mKeys . empty ( ) )
val = interpKey ( it - > mData . mKeys , time ) ;
val = std : : max ( 0.f , std : : min ( 1.f , val ) ) ;
mGeom - > setWeight ( i , val ) ;
if ( hasInput ( ) )
{
if ( mMorphs . size ( ) < = 1 )
return ;
float input = getInputValue ( nv ) ;
int i = 0 ;
for ( std : : vector < Nif : : NiMorphData : : MorphData > : : iterator it = mMorphs . begin ( ) + 1 ; it ! = mMorphs . end ( ) ; + + it , + + i )
{
float val = 0 ;
if ( ! it - > mData . mKeys . empty ( ) )
val = interpKey ( it - > mData . mKeys , input ) ;
val = std : : max ( 0.f , std : : min ( 1.f , val ) ) ;
morphGeom - > setWeight ( i , val ) ;
}
}
morphGeom - > transformSoftwareMethod ( ) ;
}
}
UVControllerValue : : UVControllerValue ( osg : : StateSet * target , const Nif : : NiUVData * data , std : : set < int > textureUnits )
: mStateSet ( target )
, mUTrans ( data - > mKeyList [ 0 ] )
UVController : : UVController ( )
{
}
UVController : : UVController ( const Nif : : NiUVData * data , std : : set < int > textureUnits )
: mUTrans ( data - > mKeyList [ 0 ] )
, mVTrans ( data - > mKeyList [ 1 ] )
, mUScale ( data - > mKeyList [ 2 ] )
, mVScale ( data - > mKeyList [ 3 ] )
@ -189,26 +247,58 @@ UVControllerValue::UVControllerValue(osg::StateSet *target, const Nif::NiUVData
{
}
void UVControllerValue : : setValue ( float value )
UVController : : UVController ( const UVController & copy , const osg : : CopyOp & copyop )
: osg : : Object ( copy , copyop ) , osg : : NodeCallback ( copy , copyop ) , Controller ( copy )
, mUTrans ( copy . mUTrans )
, mVTrans ( copy . mVTrans )
, mUScale ( copy . mUScale )
, mVScale ( copy . mVScale )
, mTextureUnits ( copy . mTextureUnits )
{
float uTrans = interpKey ( mUTrans . mKeys , value , 0.0f ) ;
float vTrans = interpKey ( mVTrans . mKeys , value , 0.0f ) ;
float uScale = interpKey ( mUScale . mKeys , value , 1.0f ) ;
float vScale = interpKey ( mVScale . mKeys , value , 1.0f ) ;
osg : : Matrixf mat = osg : : Matrixf : : scale ( uScale , vScale , 1 ) ;
mat . setTrans ( uTrans , vTrans , 0 ) ;
osg : : TexMat * texMat = new osg : : TexMat ;
texMat - > setMatrix ( mat ) ;
}
for ( std : : set < int > : : const_iterator it = mTextureUnits . begin ( ) ; it ! = mTextureUnits . end ( ) ; + + it )
void UVController : : operator ( ) ( osg : : Node * node , osg : : NodeVisitor * nv )
{
if ( hasInput ( ) )
{
mStateSet - > setTextureAttributeAndModes ( * it , texMat , osg : : StateAttribute : : ON ) ;
osg : : StateSet * stateset = node - > getStateSet ( ) ;
float value = getInputValue ( nv ) ;
float uTrans = interpKey ( mUTrans . mKeys , value , 0.0f ) ;
float vTrans = interpKey ( mVTrans . mKeys , value , 0.0f ) ;
float uScale = interpKey ( mUScale . mKeys , value , 1.0f ) ;
float vScale = interpKey ( mVScale . mKeys , value , 1.0f ) ;
osg : : Matrixf mat = osg : : Matrixf : : scale ( uScale , vScale , 1 ) ;
mat . setTrans ( uTrans , vTrans , 0 ) ;
osg : : TexMat * texMat = new osg : : TexMat ;
texMat - > setMatrix ( mat ) ;
for ( std : : set < int > : : const_iterator it = mTextureUnits . begin ( ) ; it ! = mTextureUnits . end ( ) ; + + it )
{
stateset - > setTextureAttributeAndModes ( * it , texMat , osg : : StateAttribute : : ON ) ;
}
}
traverse ( node , nv ) ;
}
VisController : : VisController ( const Nif : : NiVisData * data )
: mData ( data - > mVis )
{
}
VisController : : VisController ( )
{
}
VisController : : VisController ( const VisController & copy , const osg : : CopyOp & copyop )
: osg : : NodeCallback ( copy , copyop )
, Controller ( copy )
, mData ( copy . mData )
{
}
bool VisControllerValue : : calculate ( float time ) const
bool VisController : : calculate ( float time ) const
{
if ( mData . size ( ) = = 0 )
return true ;
@ -221,77 +311,140 @@ bool VisControllerValue::calculate(float time) const
return mData . back ( ) . isSet ;
}
void VisControllerValue : : setValue ( float time )
void VisController : : operator ( ) ( osg : : Node * node , osg : : NodeVisitor * nv )
{
if ( hasInput ( ) )
{
bool vis = calculate ( getInputValue ( nv ) ) ;
node - > setNodeMask ( vis ? ~ 0 : 0 ) ;
}
traverse ( node , nv ) ;
}
AlphaController : : AlphaController ( const Nif : : NiFloatData * data )
: mData ( data - > mKeyList )
{
bool vis = calculate ( time ) ;
mNode - > setNodeMask ( vis ? ~ 0 : 0 ) ;
}
AlphaControllerValue : : AlphaControllerValue ( osg : : StateSet * target , const Nif : : NiFloatData * data )
: mTarget ( target )
, mData ( data - > mKeyList )
AlphaController : : AlphaController ( )
{
}
void AlphaControllerValue : : setValue ( float time )
AlphaController : : AlphaController ( const AlphaController & copy , const osg : : CopyOp & copyop )
: osg : : NodeCallback ( copy , copyop ) , ValueInterpolator ( ) , Controller ( copy )
{
float value = interpKey ( mData . mKeys , time ) ;
osg : : Material * mat = dynamic_cast < osg : : Material * > ( mTarget - > getAttribute ( osg : : StateAttribute : : MATERIAL ) ) ;
if ( ! mat )
return ;
}
osg : : Vec4f diffuse = mat - > getDiffuse ( osg : : Material : : FRONT_AND_BACK ) ;
diffuse . a ( ) = value ;
mat - > setDiffuse ( osg : : Material : : FRONT_AND_BACK , diffuse ) ;
void AlphaController : : operator ( ) ( osg : : Node * node , osg : : NodeVisitor * nv )
{
if ( hasInput ( ) )
{
osg : : StateSet * stateset = node - > getStateSet ( ) ;
float value = interpKey ( mData . mKeys , getInputValue ( nv ) ) ;
osg : : Material * mat = dynamic_cast < osg : : Material * > ( stateset - > getAttribute ( osg : : StateAttribute : : MATERIAL ) ) ;
if ( mat )
{
osg : : Vec4f diffuse = mat - > getDiffuse ( osg : : Material : : FRONT_AND_BACK ) ;
diffuse . a ( ) = value ;
mat - > setDiffuse ( osg : : Material : : FRONT_AND_BACK , diffuse ) ;
}
}
traverse ( node , nv ) ;
}
MaterialColorControllerValue : : MaterialColorControllerValue ( osg : : StateSet * target , const Nif : : NiPosData * data )
: mTarget ( target ) , mData ( data - > mKeyList )
MaterialColorController : : MaterialColorController ( const Nif : : NiPosData * data )
: m Data( data - > mKeyList )
{
}
MaterialColorController : : MaterialColorController ( )
{
}
void MaterialColorControllerValue : : setValue ( float time )
MaterialColorController : : MaterialColorController ( const MaterialColorController & copy , const osg : : CopyOp & copyop )
: osg : : NodeCallback ( copy , copyop ) , Controller ( copy )
, mData ( copy . mData )
{
osg : : Vec3f value = interpKey ( mData . mKeys , time ) ;
osg : : Material * mat = dynamic_cast < osg : : Material * > ( mTarget - > getAttribute ( osg : : StateAttribute : : MATERIAL ) ) ;
if ( ! mat )
return ;
}
osg : : Vec4f diffuse = mat - > getDiffuse ( osg : : Material : : FRONT_AND_BACK ) ;
diffuse . set ( value . x ( ) , value . y ( ) , value . z ( ) , diffuse . a ( ) ) ;
mat - > setDiffuse ( osg : : Material : : FRONT_AND_BACK , diffuse ) ;
void MaterialColorController : : operator ( ) ( osg : : Node * node , osg : : NodeVisitor * nv )
{
if ( hasInput ( ) )
{
osg : : StateSet * stateset = node - > getStateSet ( ) ;
osg : : Vec3f value = interpKey ( mData . mKeys , getInputValue ( nv ) ) ;
osg : : Material * mat = dynamic_cast < osg : : Material * > ( stateset - > getAttribute ( osg : : StateAttribute : : MATERIAL ) ) ;
if ( mat )
{
osg : : Vec4f diffuse = mat - > getDiffuse ( osg : : Material : : FRONT_AND_BACK ) ;
diffuse . set ( value . x ( ) , value . y ( ) , value . z ( ) , diffuse . a ( ) ) ;
mat - > setDiffuse ( osg : : Material : : FRONT_AND_BACK , diffuse ) ;
}
}
traverse ( node , nv ) ;
}
FlipControllerValue : : FlipControllerValue ( osg : : StateSet * target , const Nif : : NiFlipController * ctrl ,
std : : vector < osg : : ref_ptr < osg : : Image > > textures )
FlipController : : FlipController ( const Nif : : NiFlipController * ctrl , std : : vector < osg : : ref_ptr < osg : : Image > > textures )
: mTexSlot ( ctrl - > mTexSlot )
, mDelta ( ctrl - > mDelta )
, mTextures ( textures )
, mTarget ( target )
{
}
void FlipControllerValue : : setValue ( float time )
FlipController : : FlipController ( )
{
}
FlipController : : FlipController ( const FlipController & copy , const osg : : CopyOp & copyop )
: osg : : NodeCallback ( copy , copyop )
, Controller ( copy )
, mTexSlot ( copy . mTexSlot )
, mDelta ( copy . mDelta )
, mTextures ( copy . mTextures )
{
if ( mDelta = = 0 )
return ;
int curTexture = int ( time / mDelta ) % mTextures . size ( ) ;
osg : : Texture2D * tex = dynamic_cast < osg : : Texture2D * > ( mTarget - > getAttribute ( osg : : StateAttribute : : TEXTURE ) ) ;
if ( ! tex )
return ;
tex - > setImage ( mTextures [ curTexture ] . get ( ) ) ;
}
ParticleSystemControllerValue : : ParticleSystemControllerValue ( osgParticle : : Emitter * emitter , const Nif : : NiParticleSystemController * ctrl )
: mEmitter ( emitter ) , mEmitStart ( ctrl - > startTime ) , mEmitStop ( ctrl - > stopTime )
void FlipController : : operator ( ) ( osg : : Node * node , osg : : NodeVisitor * nv )
{
if ( hasInput ( ) & & mDelta ! = 0 )
{
osg : : StateSet * stateset = node - > getStateSet ( ) ;
int curTexture = int ( getInputValue ( nv ) / mDelta ) % mTextures . size ( ) ;
osg : : Texture2D * tex = dynamic_cast < osg : : Texture2D * > ( stateset - > getAttribute ( osg : : StateAttribute : : TEXTURE ) ) ;
if ( tex )
tex - > setImage ( mTextures [ curTexture ] . get ( ) ) ;
}
traverse ( node , nv ) ;
}
ParticleSystemController : : ParticleSystemController ( const Nif : : NiParticleSystemController * ctrl )
: mEmitStart ( ctrl - > startTime ) , mEmitStop ( ctrl - > stopTime )
{
}
ParticleSystemController : : ParticleSystemController ( )
{
}
void ParticleSystemControllerValue : : setValue ( float time )
ParticleSystemController : : ParticleSystemController ( const ParticleSystemController & copy , const osg : : CopyOp & copyop )
: osg : : NodeCallback ( copy , copyop )
, Controller ( copy )
, mEmitStart ( copy . mEmitStart )
, mEmitStop ( copy . mEmitStop )
{
mEmitter - > setEnabled ( time > = mEmitStart & & time < mEmitStop ) ;
}
void ParticleSystemController : : operator ( ) ( osg : : Node * node , osg : : NodeVisitor * nv )
{
if ( hasInput ( ) )
{
osgParticle : : ParticleProcessor * emitter = dynamic_cast < osgParticle : : ParticleProcessor * > ( node ) ;
float time = getInputValue ( nv ) ;
if ( emitter )
emitter - > setEnabled ( time > = mEmitStart & & time < mEmitStop ) ;
}
traverse ( node , nv ) ;
}
}