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

# MeshData.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/MeshData/MeshData.h"
    00027 #include "Graphics/MeshData/MeshDataManager.h"
    00028 #include "Graphics/Renderer/RenderingDevice.h"
    00029
    00030 namespace Lamp{
    00031
    00032 //------------------------------------------------------------------------------
    00033 // コンストラクタ
    00034 MeshData::MeshData(const String& name, Scene* scene) :
    00035     SceneObject(name, scene), boundingSphere_(Sphere::zero),
    00036     boundingBox_(AxisAlignedBox::zero), indexBuffer_(NULL),
    00037     vertexDeclaration_(NULL), vertexSize_(0), vertexBuffer_(NULL),
    00038     primitiveType_(Mesh::triangleList),
    00039     vertexIndexCount_(0), vertexIndexArray_(NULL), vertexCount_(0),
    00040     positions_(NULL), normals_(NULL), colors_(NULL),
    00041     texCoordSetCount_(0), normalFlag_(false), colorFlag_(false),
    00042     bonesPerVertex_(0), boneIndices_(NULL), weightsPerVertex_(0),
    00043     weights_(NULL), vertexBufferChanged_(true), indexBufferChanged_(true),
    00044     boundingChanged_(true){
    00045     for(int i = 0; i < TexCoord::maxSetCount; i++){
    00046         texCoordTypes_[i] = TexCoord::type2;
    00047         texCoords_[i] = NULL;
    00048     }
    00049 }
    00050 //------------------------------------------------------------------------------
    00051 // デストラクタ
    00052 MeshData::~MeshData(){
    00053     SafeArrayDelete(weights_);
    00054     SafeArrayDelete(boneIndices_);
    00055     for(int i = 0; i < texCoordSetCount_; i++){
    00056         SafeArrayDelete(texCoords_[i]);
    00057     }
    00058     SafeArrayDelete(colors_);
    00059     SafeArrayDelete(normals_);
    00060     SafeArrayDelete(positions_);
    00061     SafeArrayDelete(vertexIndexArray_);
    00062     SafeRelease(vertexBuffer_);
    00063     SafeRelease(vertexDeclaration_);
    00064     SafeRelease(indexBuffer_);
    00065 }
    00066 //------------------------------------------------------------------------------
    00067 // コピー
    00068 MeshData* MeshData::copy() const{
    00069     MeshDataManager* manager = scene_->getMeshDataManager();
    00070     MeshData* copyMeshData = manager->createMeshData(manager->rename(name_));
    00071     // メッシュデータの値コピー
    00072     copyMeshDataValue(copyMeshData);
    00073     return copyMeshData;
    00074 }
    00075 //------------------------------------------------------------------------------
    00076 // 破棄
    00077 int MeshData::destroy(MeshData* meshData){
    00078     Assert(meshData != NULL);
    00079     // 引数の破棄
    00080     MeshDataManager* manager = meshData->getScene()->getMeshDataManager();
    00081     if(manager->destroy(meshData) == 0){ return 1; }
    00082     return 0;
    00083 }
    00084 //------------------------------------------------------------------------------
    00085 // メッシュデータの値コピー
    00086 void MeshData::copyMeshDataValue(MeshData* destination) const{
    00087     destination->setBoundingBox(getBoundingBox());
    00088     destination->setBoundingSphere(getBoundingSphere());
    00089     // プリミティブタイプ設定
    00090     destination->setPrimitiveType(primitiveType_);
    00091     // インデックスデータのコピー
    00092     if(hasVertexIndices()){
    00093         destination->setVertexIndexCount(vertexIndexCount_);
    00094         std::memcpy(destination->vertexIndexArray_,
    00095             vertexIndexArray_, sizeof(u_short) * vertexIndexCount_);
    00096     }
    00097     // 位置データのコピー
    00098     destination->setVertexCount(vertexCount_);
    00099     std::memcpy(destination->positions_,
    00100         positions_, sizeof(Vector3) * vertexCount_);
    00101     // 法線データのコピー
    00102     destination->enableNormal(normalFlag_);
    00103     if(normalFlag_){
    00104         std::memcpy(destination->normals_,
    00105             normals_, sizeof(Vector3) * vertexCount_);
    00106     }
    00107     // 色データのコピー
    00108     destination->enableColor(colorFlag_);
    00109     if(colorFlag_){
    00110         std::memcpy(destination->colors_,
    00111             colors_, sizeof(Color4c) * vertexCount_);
    00112     }
    00113     // テクスチャ座標のコピー
    00114     destination->setTexCoordSetCount(texCoordSetCount_);
    00115     for(int i = 0; i < texCoordSetCount_; i++){
    00116         destination->setTexCoordType(i, texCoordTypes_[i]);
    00117         std::memcpy(destination->texCoords_[i], texCoords_[i],
    00118             sizeof(float) * texCoordTypes_[i] * vertexCount_);
    00119     }
    00120     // ボーンデータのコピー
    00121     if(hasBoneIndex()){
    00122         std::memcpy(destination->boneIndices_,
    00123             boneIndices_, sizeof(u_char) * vertexCount_ * bonesPerVertex_);
    00124     }
    00125     // ウェイトデータのコピー
    00126     if(hasWeight()){
    00127         std::memcpy(destination->weights_,
    00128             weights_, sizeof(float) * vertexCount_ * weightsPerVertex_);
    00129     }
    00130 }
    00131 //------------------------------------------------------------------------------
    00132 // プリミティブタイプ
    00133 //------------------------------------------------------------------------------
    00134 // プリミティブタイプの設定
    00135 void MeshData::setPrimitiveType(Mesh::PrimitiveType primitiveType){
    00136     primitiveType_ = primitiveType;
    00137     // インデックス情報をクリア
    00138     vertexIndexCount_ = 0;
    00139     SafeArrayDelete(vertexIndexArray_);
    00140     // インデックスバッファの解放
    00141     SafeRelease(indexBuffer_);
    00142 }
    00143 //------------------------------------------------------------------------------
    00144 // プリミティブカウントの取得
    00145 int MeshData::getPrimitiveCount() const{
    00146     if(primitiveType_ == Mesh::triangleList){
    00147         Assert((getVertexCount() % 3) == 0);
    00148         return (getVertexCount() / 3);
    00149     }else if(primitiveType_ == Mesh::indexedTriangleList){
    00150         Assert((getVertexIndexCount() % 3) == 0);
    00151         return (getVertexIndexCount() / 3);
    00152     }
    00153     ErrorOut("MeshData::getPrimitiveCount() "
    00154         "サポートされていないプリミティブタイプです");
    00155     return 0;
    00156 }
    00157 //------------------------------------------------------------------------------
    00158 // 三角の取得
    00159 Triangle MeshData::getTriangle(int index) const{
    00160     Triangle triangle;
    00161     int offset = index * 3;
    00162     if(primitiveType_ == Mesh::triangleList){
    00163         triangle.setVertex(0, getPosition(offset + 0));
    00164         triangle.setVertex(1, getPosition(offset + 1));
    00165         triangle.setVertex(2, getPosition(offset + 2));
    00166     }else if(primitiveType_ == Mesh::indexedTriangleList){
    00167         triangle.setVertex(0, getPosition(getVertexIndex(offset + 0)));
    00168         triangle.setVertex(1, getPosition(getVertexIndex(offset + 1)));
    00169         triangle.setVertex(2, getPosition(getVertexIndex(offset + 2)));
    00170     }else{
    00171         ErrorOut("MeshData::getTriangle() "
    00172             "サポートされていないプリミティブタイプです");
    00173     }
    00174     return triangle;
    00175 }
    00176 //------------------------------------------------------------------------------
    00177 // インデックス
    00178 //------------------------------------------------------------------------------
    00179 // 頂点インデックス数の設定
    00180 void MeshData::setVertexIndexCount(int vertexIndexCount){
    00181     Assert(hasVertexIndices());
    00182     if(vertexIndexCount_ == vertexIndexCount){ return; }
    00183     vertexIndexCount_ = vertexIndexCount;
    00184     SafeArrayDelete(vertexIndexArray_);
    00185     if(vertexIndexCount_ == 0){ return; }
    00186     vertexIndexArray_ = new u_short[vertexIndexCount_];
    00187     // インデックスバッファの解放
    00188     SafeRelease(indexBuffer_);
    00189 }
    00190 //------------------------------------------------------------------------------
    00191 // 頂点
    00192 //------------------------------------------------------------------------------
    00193 // 頂点数の設定
    00194 void MeshData::setVertexCount(int vertexCount){
    00195     Assert(vertexCount >= 0);
    00196     if(vertexCount_ == vertexCount){ return; }
    00197     vertexCount_ = vertexCount;
    00198     SafeArrayDelete(boneIndices_);
    00199     SafeArrayDelete(weights_);
    00200     for(int i = 0; i < texCoordSetCount_; i++){
    00201         SafeArrayDelete(texCoords_[i]);
    00202     }
    00203     SafeArrayDelete(colors_);
    00204     SafeArrayDelete(normals_);
    00205     SafeArrayDelete(positions_);
    00206     if(vertexCount_ == 0){ return; }
    00207     positions_ = new Vector3[vertexCount_];
    00208     if(normalFlag_){ normals_ = new Vector3[vertexCount_]; }
    00209     if(colorFlag_){ colors_ = new Color4c[vertexCount_]; }
    00210     for(int i = 0; i < texCoordSetCount_; i++){
    00211         texCoords_[i] = new float[vertexCount_ * texCoordTypes_[i]];
    00212     }
    00213     if(hasBoneIndex()){
    00214         boneIndices_ = new u_char[vertexCount_ * bonesPerVertex_];
    00215     }
    00216     if(hasWeight()){ weights_ = new float[vertexCount_ * weightsPerVertex_]; }
    00217     // 頂点バッファを解放する
    00218     SafeRelease(vertexBuffer_);
    00219 }
    00220 //------------------------------------------------------------------------------
    00221 // 法線を有効にするかどうか
    00222 void MeshData::enableNormal(bool normalFlag){
    00223     if(normalFlag_ == normalFlag){ return; }
    00224     normalFlag_ = normalFlag;
    00225     SafeArrayDelete(normals_);
    00226     if(normalFlag_ && (vertexCount_ != 0)){
    00227         normals_ = new Vector3[vertexCount_];
    00228     }
    00229     // 頂点バッファを解放する
    00230     SafeRelease(vertexBuffer_);
    00231     // 頂点記述を解放する
    00232     vertexSize_ = 0;
    00233     SafeRelease(vertexDeclaration_);
    00234 }
    00235 //------------------------------------------------------------------------------
    00236 // カラーを有効にするかどうか
    00237 void MeshData::enableColor(bool colorFlag){
    00238     if(colorFlag_ == colorFlag){ return; }
    00239     colorFlag_ = colorFlag;
    00240     SafeArrayDelete(colors_);
    00241     if(colorFlag_ && (vertexCount_ != 0)){
    00242         colors_ = new Color4c[vertexCount_];
    00243     }
    00244     // 頂点バッファを解放する
    00245     SafeRelease(vertexBuffer_);
    00246     // 頂点記述を解放する
    00247     vertexSize_ = 0;
    00248     SafeRelease(vertexDeclaration_);
    00249 }
    00250 //------------------------------------------------------------------------------
    00251 // テクスチャ座標セット数の設定
    00252 void MeshData::setTexCoordSetCount(int texCoordSetCount){
    00253     if(texCoordSetCount_ == texCoordSetCount){ return; }
    00254     for(int i = 0; i < texCoordSetCount; i++){ SafeArrayDelete(texCoords_[i]); }
    00255     texCoordSetCount_ = texCoordSetCount;
    00256     if(vertexCount_ == 0){ return; }
    00257     for(int i = 0; i < texCoordSetCount_; i++){
    00258         texCoords_[i] = new float[vertexCount_ * texCoordTypes_[i]];
    00259     }
    00260     // 頂点バッファを解放する
    00261     SafeRelease(vertexBuffer_);
    00262     // 頂点記述を解放する
    00263     vertexSize_ = 0;
    00264     SafeRelease(vertexDeclaration_);
    00265 }
    00266 //------------------------------------------------------------------------------
    00267 // テクスチャ座標タイプの設定
    00268 void MeshData::setTexCoordType(int texCoordSet, TexCoord::Type texCoordType){
    00269     Assert((texCoordSet >= 0) && (texCoordSet < texCoordSetCount_));
    00270     if(texCoordTypes_[texCoordSet] == texCoordType){ return; }
    00271     texCoordTypes_[texCoordSet] = texCoordType;
    00272     SafeArrayDelete(texCoords_[texCoordSet]);
    00273     if(vertexCount_ == 0){ return; }
    00274     texCoords_[texCoordSet] =
    00275         new float[vertexCount_ * texCoordTypes_[texCoordSet]];
    00276     // 頂点バッファを解放する
    00277     SafeRelease(vertexBuffer_);
    00278     // 頂点記述を解放する
    00279     vertexSize_ = 0;
    00280     SafeRelease(vertexDeclaration_);
    00281 }
    00282 //------------------------------------------------------------------------------
    00283 // 頂点あたりボーン数の設定
    00284 void MeshData::setBonesPerVertex(int bonesPerVertex){
    00285     Assert(bonesPerVertex >= 0);
    00286     Assert(bonesPerVertex <= 4);
    00287     if(bonesPerVertex_ == bonesPerVertex){ return; }
    00288     bonesPerVertex_ = bonesPerVertex;
    00289     weightsPerVertex_ = (bonesPerVertex_ - 1);
    00290     if(weightsPerVertex_ < 0){ weightsPerVertex_ = 0; }
    00291     // 以前のデータを削除
    00292     SafeArrayDelete(weights_);
    00293     SafeArrayDelete(boneIndices_);
    00294     if(vertexCount_ == 0){ return; }
    00295     if(hasBoneIndex()){
    00296         boneIndices_ = new u_char[vertexCount_ * bonesPerVertex_];
    00297     }
    00298     if(hasWeight()){
    00299         weights_ = new float[vertexCount_ * weightsPerVertex_];
    00300     }
    00301     // 頂点バッファを解放する
    00302     SafeRelease(vertexBuffer_);
    00303     // 頂点記述を解放する
    00304     vertexSize_ = 0;
    00305     SafeRelease(vertexDeclaration_);
    00306 }
    00307 //------------------------------------------------------------------------------
    00308 // グラフィックスバッファ
    00309 //------------------------------------------------------------------------------
    00310 // インデックスバッファの取得
    00311 Direct3DIndexBuffer* MeshData::getIndexBuffer(){
    00312     // インデックスバッファを作成する
    00313     if(indexBuffer_ == NULL){
    00314         Assert(hasVertexIndices());
    00315         Assert(getVertexIndexCount() != 0);
    00316         RenderingDevice* device = RenderingDevice::getInstance();
    00317         int bufferSize = getVertexIndexCount() * sizeof(u_short);
    00318         indexBuffer_ = device->createDynamicIndexBuffer(bufferSize);
    00319         indexBufferChanged_ = true;
    00320     }
    00321     // インデックスバッファに書き込む
    00322     if(indexBufferChanged_){
    00323         RenderingDevice* device = RenderingDevice::getInstance();
    00324         int bufferSize = getVertexIndexCount() * sizeof(u_short);
    00325         device->writeDynamicIndexBuffer(
    00326             indexBuffer_, getVertexIndexArray(), bufferSize);
    00327         indexBufferChanged_ = false;
    00328     }
    00329     return indexBuffer_;
    00330 }
    00331 //------------------------------------------------------------------------------
    00332 // 頂点記述の取得
    00333 Direct3DVertexDeclaration* MeshData::getVertexDeclaration(){
    00334     // 頂点記述を作成する
    00335     if(vertexDeclaration_ == NULL){
    00336         Assert(vertexSize_ == 0);
    00337         vertexSize_ = RenderingDevice::getInstance()->createVertexDeclaration(
    00338             &vertexDeclaration_, true, getWeightsPerVertex(),
    00339             getBonesPerVertex(), hasNormal(), hasColor(), getTexCoordSetCount(),
    00340             getTexCoordTypeArray());
    00341     }
    00342     return vertexDeclaration_;
    00343 }
    00344 //------------------------------------------------------------------------------
    00345 // 頂点サイズの取得
    00346 int MeshData::getVertexSize(){
    00347     getVertexDeclaration();
    00348     return vertexSize_;
    00349 }
    00350 //------------------------------------------------------------------------------
    00351 // 頂点バッファの構築
    00352 Direct3DVertexBuffer* MeshData::getVertexBuffer(){
    00353     RenderingDevice* device = RenderingDevice::getInstance();
    00354     int vertexCount = getVertexCount();
    00355     int bufferSize = getVertexSize() * vertexCount;
    00356     // 頂点バッファを作成する
    00357     if(vertexBuffer_ == NULL){
    00358         vertexBuffer_ = device->createDynamicVertexBuffer(bufferSize);
    00359         vertexBufferChanged_ = true;
    00360     }
    00361     // 頂点バッファに書き込む
    00362     if(vertexBufferChanged_){
    00363         device->writeDynamicVertexBuffer(vertexBuffer_, bufferSize, vertexCount,
    00364             getPositionArray(), getWeightsPerVertex(), getWeightArray(),
    00365             getBonesPerVertex(), getBoneIndexArray(), getNormalArray(),
    00366             getColorArray(), getTexCoordSetCount(), getTexCoordTypeArray(),
    00367             getTexCoordArray());
    00368         vertexBufferChanged_ = false;
    00369     }
    00370     return vertexBuffer_;
    00371 }
    00372 //------------------------------------------------------------------------------
    00373 } // End of namespace Lamp
    00374 //------------------------------------------------------------------------------