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 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:33 2005 for Lamp by doxygen 1.3.2