Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# CharacterModel.cpp

Go to the documentation of this file.

    00001 //------------------------------------------------------------------------------
    00002 // Lamp : Open source game middleware
    00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
    00004 //
    00005 // This library is free software; you can redistribute it and/or
    00006 // modify it under the terms of the GNU Lesser General Public
    00007 // License as published by the Free Software Foundation; either
    00008 // version 2.1 of the License, or (at your option) any later version.
    00009 //
    00010 // This library is distributed in the hope that it will be useful,
    00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013 // Lesser General Public License for more details.
    00014 //
    00015 // You should have received a copy of the GNU Lesser General Public
    00016 // License along with this library; if not, write to the Free Software
    00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00018 //------------------------------------------------------------------------------
    00019
    00020 /** @file
    00021  * キャラクタモデル実装
    00022  * @author Junpee
    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 } // End of namespace Lamp
    00184 //------------------------------------------------------------------------------