00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Animation/Model/CharacterModelAnimation.h"
00027 #include "Animation/System/AnimationManager.h"
00028 #include "Graphics/Scene/Scene.h"
00029 #include "Graphics/Model/ModelManager.h"
00030
00031 namespace Lamp{
00032
00033
00034
00035 CharacterModelAnimation::CharacterModelAnimation(
00036 String name, AnimationManager* manager) : ObjectAnimation(name, manager),
00037 animationData_(NULL), target_(NULL),
00038 boneCount_(0), boneNames_(NULL), targetBones_(NULL){
00039 }
00040
00041
00042 CharacterModelAnimation::~CharacterModelAnimation(){
00043 SafeArrayDelete(targetBones_);
00044 SafeArrayDelete(boneNames_);
00045 }
00046
00047
00048 bool CharacterModelAnimation::bind(Scene* scene){
00049
00050 if(getTargetName().getSize() == 0){ return false; }
00051
00052 Model* model = scene->getModelManager()->search(getTargetName());
00053 if(model == NULL){ return false; }
00054 CharacterModel* characterModel = model->castCharacterModel();
00055 if(characterModel == NULL){ return false; }
00056 target_ = characterModel;
00057
00058 for(int i = 0; i < boneCount_; i++){
00059 Assert(boneNames_[i].getSize() > 0);
00060 Bone* bone = target_->searchBone(boneNames_[i]);
00061 Assert(bone != NULL);
00062 if(bone == NULL){ return false; }
00063 targetBones_[i] = bone;
00064 }
00065 return true;
00066 }
00067
00068
00069 bool CharacterModelAnimation::bind(CharacterModel* model){
00070 if(model == NULL){ return false; }
00071 setTargetName(model->getName());
00072 target_ = model;
00073
00074 for(int i = 0; i < boneCount_; i++){
00075 Assert(boneNames_[i].getSize() > 0);
00076 Bone* bone = target_->searchBone(boneNames_[i]);
00077 Assert(bone != NULL);
00078 if(bone == NULL){ return false; }
00079 targetBones_[i] = bone;
00080 }
00081 return true;
00082 }
00083
00084
00085 bool CharacterModelAnimation::animate(float deltaTime, AnimationMask mask){
00086
00087 if((mask & maskCharacterModel) == 0){ return true; }
00088 if(!isEnabled()){ return true; }
00089 if(animationData_ == NULL){ return true; }
00090 if(target_ == NULL){ return true; }
00091
00092 if(!target_->isGlobalEnabled()){
00093 setTime(getTime() + deltaTime);
00094 return true;
00095 }
00096
00097 int sequence = getSequence();
00098 float correctTime = increasesTime(deltaTime);
00099 CharacterModelAnimationData* data = getCharacterModelAnimationData();
00100 Assert(boneCount_ == data->getBoneCount());
00101 for(int i = 0; i < boneCount_; i++){
00102 Bone* bone = targetBones_[i];
00103
00104 VectorInterpolator* scale = data->getScale(sequence, i);
00105 if(scale != NULL){ bone->setScale(scale->interpolate(correctTime)); }
00106
00107 RotationInterpolator* rotation = data->getRotation(sequence, i);
00108 if(rotation != NULL){
00109 if(rotation->isQuaternionInterpolator()){
00110 bone->setRotationQuaternion(
00111 rotation->quaternionInterpolate(correctTime));
00112 }else if(rotation->isEulerInterpolator()){
00113 bone->setRotationXYZ(rotation->eulerInterpolate(correctTime));
00114 }else{
00115 ErrorOut("CharacterModelAnimation::animate() "
00116 "Unsupported Rotation type");
00117 }
00118 }
00119
00120 VectorInterpolator* translation = data->getTranslation(sequence, i);
00121 if(translation != NULL){
00122 bone->setTranslation(translation->interpolate(correctTime));
00123 }
00124 }
00125 return isFinished();
00126 }
00127
00128
00129 CharacterModelAnimation* CharacterModelAnimation::copyCharacterModelAnimation(
00130 DataCopyMask dataCopyMask) const{
00131 CharacterModelAnimation* animation =
00132 getManager()->createCharacterModel(getName());
00133 copyObjectAnimationValue(animation);
00134
00135 animation->setBoneCount(boneCount_);
00136 for(int i = 0; i < boneCount_; i++){
00137 animation->setBoneName(i, getBoneName(i));
00138 }
00139
00140 if((dataCopyMask & copyCharacterModel) == copyCharacterModel){
00141 animation->animationData_ =
00142 animationData_->copyCharacterModelAnimationData();
00143 }else{
00144 animation->animationData_ = animationData_;
00145 }
00146 animation->animationData_->addReference();
00147 animation->bind(target_);
00148 return animation;
00149 }
00150
00151 }
00152