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 "Graphics/Model/CharacterModel.h"
00027 #include "Graphics/Scene/Scene.h"
00028 #include "Graphics/Model/ModelManager.h"
00029 #include "Graphics/Mesh/Mesh.h"
00030
00031 namespace Lamp{
00032
00033
00034
00035 CharacterModel::CharacterModel(const String& name, Scene* scene) :
00036 Model(name, scene), boneHash_(maxBoneCount, 1.f), boneArray_(maxBoneCount),
00037 positionDeformMatrixArray_(NULL), normalDeformMatrixArray_(NULL),
00038 deformMatrixArraySize_(0), boneScaled_(false){
00039 buildBoneMatrixTick_ = scene_->getTick() - 1;
00040 deformMatrixArrayTick_ = scene_->getTick() - 1;
00041 }
00042
00043
00044 CharacterModel::~CharacterModel(){
00045 SafeArrayDelete(normalDeformMatrixArray_);
00046 SafeArrayDelete(positionDeformMatrixArray_);
00047 clearBone();
00048 }
00049
00050
00051 CharacterModel* CharacterModel::copyCharacterModel(u_int copyMask) const{
00052 ModelManager* manager = scene_->getModelManager();
00053 CharacterModel* copyModel =
00054 manager->createCharacterModel(manager->rename(name_));
00055
00056 copyModelValue(copyModel, copyMask);
00057
00058 int boneCount = getBoneCount();
00059 for(int i = 0; i < boneCount; i++){
00060 Bone* sourceBone = getBone(i);
00061 Bone* destinationBone = copyModel->createBone(sourceBone->getName());
00062 sourceBone->copyBoneValue(destinationBone);
00063 }
00064
00065 for(int i = 0; i < boneCount; i++){
00066 Bone* sourceBone = getBone(i);
00067 Bone* destinationBone = copyModel->getBone(i);
00068 int childCount = sourceBone->getBoneCount();
00069 for(int j = 0; j < childCount; j++){
00070 Bone* childBone = copyModel->searchBone(
00071 sourceBone->getBone(j)->getName());
00072 destinationBone->addBone(childBone);
00073 }
00074 }
00075 return copyModel;
00076 }
00077
00078
00079 void CharacterModel::buildBoneMatrix(bool forceCalculation){
00080
00081 u_int sceneTick = scene_->getTick();
00082 if((!forceCalculation) && (buildBoneMatrixTick_ == sceneTick)){ return; }
00083 buildBoneMatrixTick_ = sceneTick;
00084 boneScaled_ = getBone(0)->buildBoneMatrix(Matrix34::unit);
00085 }
00086
00087
00088 const Matrix34* CharacterModel::getPositionDeformMatrixArray(
00089 bool forceCalculation){
00090
00091 if((!forceCalculation) && (deformMatrixArrayTick_ == scene_->getTick())){
00092 return positionDeformMatrixArray_;
00093 }
00094
00095 buildDeformMatrixArray();
00096 return positionDeformMatrixArray_;
00097 }
00098
00099
00100 const Matrix33* CharacterModel::getNormalDeformMatrixArray(
00101 bool forceCalculation){
00102 Assert(boneScaled_);
00103
00104 if((!forceCalculation) && (deformMatrixArrayTick_ == scene_->getTick())){
00105 return normalDeformMatrixArray_;
00106 }
00107
00108 buildDeformMatrixArray();
00109 return normalDeformMatrixArray_;
00110 }
00111
00112
00113 void CharacterModel::buildDeformMatrixArray(){
00114
00115 int boneCount = getBoneCount();
00116 if((positionDeformMatrixArray_ == NULL) ||
00117 (deformMatrixArraySize_ != boneCount)){
00118 SafeArrayDelete(positionDeformMatrixArray_);
00119 deformMatrixArraySize_ = boneCount;
00120 positionDeformMatrixArray_ = new Matrix34[deformMatrixArraySize_];
00121 if(boneScaled_){
00122 normalDeformMatrixArray_ = new Matrix33[deformMatrixArraySize_];
00123 }
00124 }
00125
00126 for(int i = 0; i < boneCount; i++){
00127 positionDeformMatrixArray_[i] = getBone(i)->getDeformMatrix();
00128 }
00129 if(boneScaled_){
00130 for(int i = 0; i < boneCount; i++){
00131 normalDeformMatrixArray_[i].set(positionDeformMatrixArray_[i]);
00132 normalDeformMatrixArray_[i].invert();
00133 normalDeformMatrixArray_[i].transpose();
00134 }
00135 }
00136 deformMatrixArrayTick_ = scene_->getTick();
00137 }
00138
00139
00140 Bone* CharacterModel::createBone(const String& boneName){
00141 Assert(boneArray_.getCount() < maxBoneCount);
00142
00143 if(boneName.getSize() == 0){
00144 ErrorOut("CharacterModel::createBone() boneName.getSize() == 0");
00145 }
00146 Bone* bone = new Bone(boneName);
00147 if(!boneHash_.put(boneName, bone)){
00148
00149 ErrorOut("CharacterModel::createBone() repetition name %s",
00150 boneName.getBytes());
00151 delete bone;
00152 return NULL;
00153 }
00154 boneArray_.add(bone);
00155 return bone;
00156 }
00157
00158
00159 void CharacterModel::destroyBone(Bone* bone){
00160 if(boneHash_.remove(bone->getName()) == NULL){
00161 ErrorOut("CharacterModel::destroyBone() not found %s",
00162 bone->getName().getBytes());
00163 }
00164 boneArray_.removeByValue(bone);
00165 delete bone;
00166 }
00167
00168
00169 int CharacterModel::clearBone(){
00170 int result = getBoneCount();
00171 for(int i = 0; i < result; i++){ delete getBone(i); }
00172 boneHash_.clear();
00173 boneArray_.clear();
00174 return result;
00175 }
00176
00177
00178 void CharacterModel::addMesh(Mesh* mesh){
00179 Assert(mesh->isCharacterMesh());
00180 Model::addMesh(mesh);
00181 }
00182
00183 }
00184