00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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 }
00293