void ProceduralAnimApp::update() { mLightPos.x = mRotationRadius * math<float>::sin( float( app::getElapsedSeconds() ) ); mLightPos.z = mRotationRadius * math<float>::cos( float( app::getElapsedSeconds() ) ); mFlapAngle += 0.01f * mFlapIncrement; float h = mAmplitude * 0.5f * math<float>::sin( mFlapAngle ); float t = mAmplitude * 0.5f * math<float>::sin( mFlapAngle - M_PI / 2 ); SkeletonRef skeleton = mSkinnedVboBird->getSkeleton(); NodeRef midL = skeleton->getBone("Gannet_Lwing_mid"); NodeRef midR = skeleton->getBone("Gannet_Rwing_mid"); NodeRef tipL = skeleton->getBone("Gannet_Lwing_tip"); NodeRef tipR = skeleton->getBone("Gannet_Rwing_tip"); midL->setRelativeRotation( midL->getInitialRelativeRotation() * Quatf( Vec3f::xAxis(), t ) * Quatf( Vec3f::zAxis(), mShoulderAngle ) ); midR->setRelativeRotation( midR->getInitialRelativeRotation() * Quatf( Vec3f::xAxis(), t ) * Quatf( Vec3f::zAxis(), mShoulderAngle ) ); tipL->setRelativeRotation( Quatf( Vec3f::yAxis(), h ) ); tipR->setRelativeRotation( Quatf( Vec3f::yAxis(), h ) ); NodeRef head = skeleton->getBone("Gannet_head"); head->setRelativeRotation( head->getInitialRelativeRotation().slerp(0.5f, mMayaCam.getCamera().getOrientation() ) ); skeleton->getBone("Gannet_body")->setRelativePosition( Vec3f(0, -t, 0) ); /* The mesh isn't automatically updated when the skeleton it contained is modified, so * an update call is necessary (for now). This may change since I don't find it very * intuitive... */ mSkinnedVboBird->update(); for( auto& d : mDust ) { d.z -= 0.75f; d.z = ( d.z < -SCENE_SIZE/2 ) ? SCENE_SIZE/2 : d.z; } }