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

BuildIndexedTriangleFilter.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/SceneFilter/BuildIndexedTriangleFilter/\
00027 BuildIndexedTriangleFilter.h"
00028 #include "Core/Utility/StringTokenizer.h"
00029 #include "Graphics/MeshData/MeshDataManager.h"
00030 
00031 namespace Lamp{
00032 
00033 //------------------------------------------------------------------------------
00034 // コンストラクタ
00035 BuildIndexedTriangleFilter::BuildIndexedTriangleFilter(Scene* scene) :
00036     SceneFilterInterface(scene){
00037 }
00038 //------------------------------------------------------------------------------
00039 // デストラクタ
00040 BuildIndexedTriangleFilter::~BuildIndexedTriangleFilter(){
00041 }
00042 //------------------------------------------------------------------------------
00043 // フィルタ
00044 bool BuildIndexedTriangleFilter::filter(const String& command){
00045     StringTokenizer tokenizer_(command);
00046     if(!tokenizer_.hasMoreTokens()){
00047         ErrorOut("BuildIndexedTriangleFilter::filter() "
00048             "Not found filter name");
00049         return false;
00050     }
00051     String filterName = tokenizer_.getNextToken();
00052     if(filterName != "BuildIndexedTriangle"){
00053         ErrorOut("BuildIndexedTriangleFilter::filter() "
00054             "Invalid filter name %s",
00055             filterName.getBytes());
00056         return false;
00057     }
00058     return filterScene();
00059 }
00060 //------------------------------------------------------------------------------
00061 // シーンのフィルタ
00062 bool BuildIndexedTriangleFilter::filterScene(){
00063     if(!filterMeshData()){ return false; }
00064     return true;
00065 }
00066 //------------------------------------------------------------------------------
00067 // メッシュデータのフィルタ
00068 bool BuildIndexedTriangleFilter::filterMeshData(){
00069     int count = meshDataManager_->getCount();
00070     // 各メッシュデータのチェック
00071     for(int i = 0; i < count; i++){
00072         if(!filterMeshData(meshDataManager_->get(i))){ return false; }
00073     }
00074     return true;
00075 }
00076 //------------------------------------------------------------------------------
00077 // メッシュデータのフィルタ
00078 bool BuildIndexedTriangleFilter::filterMeshData(MeshData* meshData){
00079     if(meshData->getPrimitiveType() != Mesh::triangleList){ return true; }
00080     clear();
00081     // 元データの読み出し
00082     sourceVertexCount_ = meshData->getVertexCount();
00083     if(sourceVertexCount_ <= 0){ return true; }
00084     texCoordSetCount_ = meshData->getTexCoordSetCount();
00085     texCoordTypeArray_ = meshData->getTexCoordTypeArray();
00086     weightsPerVertex_ = meshData->getWeightsPerVertex();
00087     bonesPerVertex_ = meshData->getBonesPerVertex();
00088     sourcePosition_ = meshData->getPositionArray();
00089     sourceNormal_ = meshData->getNormalArray();
00090     sourceColor_ = meshData->getColorArray();
00091     sourceTexCoord_ = meshData->getTexCoordArray();
00092     sourceBoneIndex_ = meshData->getBoneIndexArray();
00093     sourceWeight_ = meshData->getWeightArray();
00094     // バッファの確保
00095     allocateBuffer();
00096     // インデックストライアングルの構築
00097     if(!buildIndexedTriangle()){
00098         freeBuffer();
00099         return false;
00100     }
00101     // データの設定
00102     meshData->setPrimitiveType(Mesh::indexedTriangleList);
00103     meshData->setVertexIndexCount(sourceVertexCount_);
00104     for(int i = 0; i < sourceVertexCount_; i++){
00105         meshData->setVertexIndex(i, indices_[i]);
00106     }
00107     meshData->setVertexCount(vertexCount_);
00108     meshData->setTexCoordSetCount(texCoordSetCount_);
00109     for(int i = 0; i < texCoordSetCount_; i++){
00110         meshData->setTexCoordType(i, texCoordTypeArray_[i]);
00111     }
00112     meshData->setBonesPerVertex(bonesPerVertex_);
00113     for(int i = 0; i < vertexCount_; i++){
00114         meshData->setPosition(i, positions_[i]);
00115         if(sourceNormal_ != NULL){ meshData->setNormal(i, normals_[i]); }
00116         if(sourceColor_ != NULL){ meshData->setColor(i, colors_[i]); }
00117         for(int j = 0; j < texCoordSetCount_; j++){
00118             meshData->setTexCoord(i, j,
00119                 &(texCoords_[j][texCoordTypeArray_[j] * i]),
00120                 texCoordTypeArray_[j]);
00121         }
00122         for(int j = 0; j < bonesPerVertex_; j++){
00123             int offset = i * bonesPerVertex_;
00124             if(sourceBoneIndex_ != NULL){
00125                 meshData->setBoneIndex(i, j, boneIndices_[offset + j]);
00126             }
00127         }
00128         for(int j = 0; j < weightsPerVertex_; j++){
00129             int offset = i * weightsPerVertex_;
00130             if(sourceWeight_ != NULL){
00131                 meshData->setWeight(i, j, weights_[offset + j]);
00132             }
00133         }
00134     }
00135     // バッファの解放
00136     freeBuffer();
00137     return true;
00138 }
00139 //------------------------------------------------------------------------------
00140 // クリア
00141 void BuildIndexedTriangleFilter::clear(){
00142     sourceVertexCount_ = 0;
00143     sourcePosition_ = NULL;
00144     sourceNormal_ = NULL;
00145     sourceColor_ = NULL;
00146     sourceTexCoord_ = NULL;
00147     sourceBoneIndex_ = NULL;
00148     sourceWeight_ = NULL;
00149     vertexCount_ = 0;
00150     texCoordSetCount_ = 0;
00151     texCoordTypeArray_ = NULL;
00152     bonesPerVertex_ = 0;
00153     weightsPerVertex_ = 0;
00154     positions_ = NULL;
00155     normals_ = NULL;
00156     colors_ = NULL;
00157     for(int i = 0; i < TexCoord::maxSetCount; i++){ texCoords_[i] = NULL; }
00158     boneIndices_ = NULL;
00159     weights_ = NULL;
00160     indices_ = NULL;
00161 }
00162 //------------------------------------------------------------------------------
00163 // インデックストライアングルの構築
00164 bool BuildIndexedTriangleFilter::buildIndexedTriangle(){
00165     for(int i = 0; i < sourceVertexCount_; i++){
00166         // すでに頂点が無いか探す
00167         int index = findIndex(i);
00168         // 頂点の追加
00169         if(index == -1){
00170             index = vertexCount_;
00171             vertexCount_++;
00172             if(index >= maxIndex){
00173                 ErrorOut("BuildIndexedTriangleFilter::buildIndexedTriangle() "
00174                     "Index overflow");
00175                 return false;
00176             }
00177             positions_[index] = sourcePosition_[i];
00178             if(sourceNormal_ != NULL){ normals_[index] = sourceNormal_[i]; }
00179             if(sourceColor_ != NULL){ colors_[index] = sourceColor_[i]; }
00180             for(int j = 0; j < texCoordSetCount_; j++){
00181                 int numFloat = texCoordTypeArray_[j];
00182                 for(int k = 0; k < numFloat; k++){
00183                     texCoords_[j][index * numFloat + k] =
00184                         sourceTexCoord_[j][i * numFloat + k];
00185                 }
00186             }
00187             for(int j = 0; j < bonesPerVertex_; j++){
00188                 int offset = index * bonesPerVertex_;
00189                 int sourceOffset = i * bonesPerVertex_;
00190                 if(sourceBoneIndex_ != NULL){
00191                     boneIndices_[offset + j] =
00192                         sourceBoneIndex_[sourceOffset + j];
00193                 }
00194             }
00195             for(int j = 0; j < weightsPerVertex_; j++){
00196                 int offset = index * weightsPerVertex_;
00197                 int sourceOffset = i * weightsPerVertex_;
00198                 if(sourceWeight_ != NULL){
00199                     weights_[offset + j] =
00200                         sourceWeight_[sourceOffset + j];
00201                 }
00202             }
00203         }
00204         indices_[i] = index;
00205     }
00206     return true;
00207 }
00208 //------------------------------------------------------------------------------
00209 // すでに頂点が無いか探す
00210 int BuildIndexedTriangleFilter::findIndex(int source){
00211     for(int i = 0; i < vertexCount_; i++){
00212         // 位置の比較
00213         if(positions_[i].notEpsilonEquals(
00214             sourcePosition_[source], Math::epsilon)){ continue; }
00215         // 法線の比較
00216         if((sourceNormal_ != NULL) &&
00217             (normals_[i].notEpsilonEquals(
00218             sourceNormal_[source], Math::epsilon))){ continue; }
00219         // 頂点カラーの比較
00220         if((sourceColor_ != NULL) && (colors_[i] != sourceColor_[source])){
00221             continue;
00222         }
00223         // テクスチャ座標の比較
00224         bool result = false;
00225         for(int j = 0; j < texCoordSetCount_; j++){
00226             int numFloat = texCoordTypeArray_[j];
00227             for(int k = 0; k < numFloat; k++){
00228                 if(Math::abs(texCoords_[j][i * numFloat + k] -
00229                     sourceTexCoord_[j][source * numFloat + k]) >
00230                     Math::epsilon){
00231                     result = true;
00232                 }
00233             }
00234         }
00235         if(result){ continue; }
00236         // ボーンインデックスの比較
00237         for(int j = 0; j < bonesPerVertex_; j++){
00238             int offset = i * bonesPerVertex_;
00239             int sourceOffset = source * bonesPerVertex_;
00240             if((sourceBoneIndex_ != NULL) &&
00241                 (boneIndices_[offset + j] !=
00242                 sourceBoneIndex_[sourceOffset+ j])){ result = true; }
00243         }
00244         if(result){ continue; }
00245         // ウェイトの比較
00246         for(int j = 0; j < weightsPerVertex_; j++){
00247             int offset = i * weightsPerVertex_;
00248             int sourceOffset = source * weightsPerVertex_;
00249             if((sourceWeight_ != NULL) &&
00250                 (Math::abs(weights_[offset + j] -
00251                 sourceWeight_[sourceOffset+ j]) > Math::epsilon)){
00252                 result = true;
00253             }
00254         }
00255         if(result){ continue; }
00256         return i;
00257     }
00258     return -1;
00259 }
00260 //------------------------------------------------------------------------------
00261 // バッファのアロケート
00262 void BuildIndexedTriangleFilter::allocateBuffer(){
00263     positions_ = new Vector3[sourceVertexCount_];
00264     if(sourceNormal_ != NULL){ normals_ = new Vector3[sourceVertexCount_]; }
00265     if(sourceColor_ != NULL){ colors_ = new Color4c[sourceVertexCount_]; }
00266     for(int i = 0; i < texCoordSetCount_; i++){
00267         texCoords_[i] = new float[texCoordTypeArray_[i] * sourceVertexCount_];
00268     }
00269     if(sourceBoneIndex_ != NULL){
00270         boneIndices_ = new u_char[sourceVertexCount_ * bonesPerVertex_];
00271     }
00272     if(sourceWeight_ != NULL){
00273         weights_ = new float[sourceVertexCount_ * weightsPerVertex_];
00274     }
00275     indices_ = new u_short[sourceVertexCount_];
00276 }
00277 //------------------------------------------------------------------------------
00278 // バッファの解放
00279 void BuildIndexedTriangleFilter::freeBuffer(){
00280     SafeArrayDelete(indices_);
00281     SafeArrayDelete(weights_);
00282     SafeArrayDelete(boneIndices_);
00283 //  SafeArrayDelete(uvs_);
00284     for(int i = 0; i < texCoordSetCount_; i++){
00285         SafeArrayDelete(texCoords_[i]);
00286     }
00287     SafeArrayDelete(colors_);
00288     SafeArrayDelete(normals_);
00289     SafeArrayDelete(positions_);
00290 }
00291 //------------------------------------------------------------------------------
00292 } // End of namespace Lamp
00293 //------------------------------------------------------------------------------

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