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