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
00026
00027
00028
00029
00030
00031
00032 #include <vlGraphics/Geometry.hpp>
00033 #include <vlGraphics/OpenGLContext.hpp>
00034 #include <vlGraphics/DoubleVertexRemover.hpp>
00035 #include <cmath>
00036
00037 using namespace vl;
00038
00039
00040
00041
00042 Geometry::Geometry()
00043 {
00044 VL_DEBUG_SET_OBJECT_NAME()
00045 mVertexAttribArrays.setAutomaticDelete(false);
00046 mTexCoordArrays.setAutomaticDelete(false);
00047 mDrawCalls.setAutomaticDelete(false);
00048 mColor = vl::white;
00049 mSecondaryColor = vl::white;
00050 mNormal = fvec3(0,0,1);
00051 }
00052
00053 Geometry::~Geometry()
00054 {
00055 }
00056
00057 void Geometry::computeBounds_Implementation()
00058 {
00059 const ArrayAbstract* coords = vertexArray();
00060 if (!coords && vertexAttribInfo(0))
00061 coords = vertexAttribInfo(0)->data();
00062
00063 AABB aabb;
00064
00065 for(int i=0; i<drawCalls()->size(); ++i)
00066 {
00067 for(IndexIterator iit = drawCalls()->at(i)->indexIterator(); !iit.isEnd(); iit.next())
00068 {
00069 aabb += coords->vectorAsVec3( iit.index() );
00070 }
00071 }
00072
00073 Real radius = 0, r = 0;
00074 vec3 center = aabb.center();
00075 for(int i=0; i<drawCalls()->size(); ++i)
00076 {
00077 for(IndexIterator iit = drawCalls()->at(i)->indexIterator(); !iit.isEnd(); iit.next())
00078 {
00079 r = (coords->vectorAsVec3(iit.index()) - center).lengthSquared();
00080 if (r > radius)
00081 radius = r;
00082 }
00083 }
00084
00085 setBoundingBox( aabb );
00086 setBoundingSphere( Sphere(center, radius) );
00087 }
00088
00089 ref<Geometry> Geometry::deepCopy() const
00090 {
00091 ref<Geometry> geom = new Geometry;
00092 deepCopy(geom.get());
00093 return geom;
00094 }
00095
00096 void Geometry::deepCopy(Geometry* geom) const
00097 {
00098
00099 geom->Renderable::operator=(*this);
00100
00101 geom->mVertexArray = mVertexArray ? mVertexArray->clone().get() : NULL;
00102 geom->mNormalArray = mNormalArray ? mNormalArray->clone().get() : NULL;
00103 geom->mColorArray = mColorArray ? mColorArray->clone().get() : NULL;
00104 geom->mSecondaryColorArray = mSecondaryColorArray ? mSecondaryColorArray->clone().get() : NULL;
00105 geom->mFogCoordArray = mFogCoordArray ? mFogCoordArray->clone().get() : NULL;
00106 geom->mTexCoordArrays.resize(mTexCoordArrays.size());
00107 for(int i=0; i<mTexCoordArrays.size(); ++i)
00108 geom->mTexCoordArrays[i] = new TextureArray(mTexCoordArrays[i]->mTextureUnit, mTexCoordArrays[i]->mTexCoordArray ? mTexCoordArrays[i]->mTexCoordArray->clone().get() : NULL);
00109
00110 geom->mVertexAttribArrays.resize(mVertexAttribArrays.size());
00111 for(int i=0; i<mVertexAttribArrays.size(); ++i)
00112 {
00113 geom->mVertexAttribArrays[i] = new VertexAttribInfo;
00114 geom->mVertexAttribArrays[i]->setNormalize( mVertexAttribArrays[i]->normalize() );
00115 geom->mVertexAttribArrays[i]->setDataBehavior( mVertexAttribArrays[i]->dataBehavior() );
00116 geom->mVertexAttribArrays[i]->setAttribIndex( mVertexAttribArrays[i]->attribIndex() );
00117 geom->mVertexAttribArrays[i]->setData( geom->mVertexAttribArrays[i]->data() ? geom->mVertexAttribArrays[i]->data()->clone().get() : NULL );
00118 }
00119
00120 for(int i=0; i<mDrawCalls.size(); ++i)
00121 geom->mDrawCalls.push_back( mDrawCalls[i]->clone().get() );
00122 geom->mColor = mColor;
00123 geom->mSecondaryColor = mSecondaryColor;
00124 geom->mNormal = mNormal;
00125 }
00126
00127 Geometry& Geometry::operator=(const Geometry& other)
00128 {
00129
00130 Renderable::operator=(*this);
00131
00132 mVertexArray = other.mVertexArray;
00133 mNormalArray = other.mNormalArray;
00134 mColorArray = other.mColorArray;
00135 mSecondaryColorArray = other.mSecondaryColorArray;
00136 mFogCoordArray = other.mFogCoordArray;
00137 mTexCoordArrays = other.mTexCoordArrays;
00138 mVertexAttribArrays = other.mVertexAttribArrays;
00139 mColor = other.mColor;
00140 mSecondaryColor = other.mSecondaryColor;
00141 mNormal = other.mNormal;
00142 mDrawCalls = other.mDrawCalls;
00143 return *this;
00144 }
00145
00146 ref<Geometry> Geometry::shallowCopy()
00147 {
00148 ref<Geometry> geom = new Geometry;
00149 geom->operator=(*this);
00150 return geom;
00151 }
00152
00153 void Geometry::shallowCopy(Geometry* geom)
00154 {
00155 geom->operator=(*this);
00156 }
00157
00158 void Geometry::setVertexArray(ArrayAbstract* data)
00159 {
00160
00161
00162 VL_CHECK( !data || (data->glSize() >=2 && data->glSize()<=4) )
00163
00164 mVertexArray = data;
00165 }
00166
00167 void Geometry::setNormalArray(ArrayAbstract* data)
00168 {
00169
00170
00171 VL_CHECK( !data || data->glSize() == 3 )
00172 VL_CHECK( !data || (data->glType() == GL_BYTE||
00173 data->glType() == GL_SHORT ||
00174 data->glType() == GL_INT ||
00175 data->glType() == GL_FLOAT ||
00176 data->glType() == GL_DOUBLE) );
00177
00178 mNormalArray = data;
00179 }
00180
00181 void Geometry::setColorArray(ArrayAbstract* data)
00182 {
00183
00184
00185 VL_CHECK( !data || (data->glSize() >=3 && data->glSize()<=4) )
00186 VL_CHECK( !data || (data->glType() == GL_BYTE ||
00187 data->glType() == GL_SHORT ||
00188 data->glType() == GL_INT ||
00189 data->glType() == GL_UNSIGNED_BYTE ||
00190 data->glType() == GL_UNSIGNED_SHORT ||
00191 data->glType() == GL_UNSIGNED_INT ||
00192 data->glType() == GL_FLOAT ||
00193 data->glType() == GL_DOUBLE) );
00194
00195 mColorArray = data;
00196 }
00197
00198 void Geometry::setSecondaryColorArray(ArrayAbstract* data)
00199 {
00200
00201
00202 VL_CHECK( !data || (data->glSize() >=3 && data->glSize()<=4) )
00203 VL_CHECK( !data || (data->glType() == GL_BYTE ||
00204 data->glType() == GL_SHORT ||
00205 data->glType() == GL_INT ||
00206 data->glType() == GL_UNSIGNED_BYTE ||
00207 data->glType() == GL_UNSIGNED_SHORT ||
00208 data->glType() == GL_UNSIGNED_INT ||
00209 data->glType() == GL_FLOAT ||
00210 data->glType() == GL_DOUBLE) );
00211
00212 mSecondaryColorArray = data;
00213 }
00214
00215 void Geometry::setFogCoordArray(ArrayAbstract* data)
00216 {
00217
00218
00219 VL_CHECK( !data || (data->glSize() == 1) )
00220 VL_CHECK( !data || (data->glType() == GL_FLOAT || data->glType() == GL_DOUBLE) );
00221
00222 mFogCoordArray = data;
00223 }
00224
00225 void Geometry::setTexCoordArray(int tex_unit, ArrayAbstract* data)
00226 {
00227
00228
00229 VL_CHECK( !data || (data->glSize() == 1 || data->glSize() == 2 || data->glSize() == 3 || data->glSize() == 4) )
00230 VL_CHECK( !data || (data->glType() == GL_FLOAT ||
00231 data->glType() == GL_DOUBLE ||
00232 data->glType() == GL_SHORT ||
00233 data->glType() == GL_INT) );
00234
00235 VL_CHECK(tex_unit<VL_MAX_TEXTURE_UNITS);
00236
00237 for(int i=0; i<mTexCoordArrays.size(); ++i)
00238 {
00239 if (mTexCoordArrays.at(i)->mTextureUnit == tex_unit)
00240 {
00241 if (data)
00242 mTexCoordArrays.at(i)->mTexCoordArray = data;
00243 else
00244 mTexCoordArrays.erase(i,1);
00245 return;
00246 }
00247 }
00248 if (data)
00249 mTexCoordArrays.push_back(new TextureArray(tex_unit,data));
00250 }
00251
00252 void Geometry::clearArrays(bool clear_draw_calls)
00253 {
00254 mVertexArray = NULL;
00255 mNormalArray = NULL;
00256 mColorArray = NULL;
00257 mSecondaryColorArray = NULL;
00258 mFogCoordArray = NULL;
00259 mTexCoordArrays.clear();
00260 mVertexAttribArrays.clear();
00261 if (clear_draw_calls)
00262 mDrawCalls.clear();
00263 }
00264
00265 bool Geometry::flipNormals()
00266 {
00267 if (normalArray())
00268 {
00269 ArrayFloat3* norm3f = dynamic_cast<ArrayFloat3*>(normalArray());
00270 if (norm3f)
00271 {
00272 for(size_t i=0; i<norm3f->size(); ++i)
00273 {
00274 norm3f->at(i) = -norm3f->at(i);
00275 }
00276 return true;
00277 }
00278 }
00279 return false;
00280 }
00281
00282 void Geometry::toGenericVertexAttribs()
00283 {
00284 vertexAttribArrays()->clear();
00285 int index = 0;
00286
00287 if (vertexArray())
00288 {
00289 setVertexAttribArray(index++, vertexArray());
00290 setVertexArray(NULL);
00291 }
00292
00293 if (normalArray())
00294 {
00295 setVertexAttribArray(index++, normalArray());
00296 setNormalArray(NULL);
00297 }
00298
00299 if (colorArray())
00300 {
00301 setVertexAttribArray(index++, colorArray());
00302 setColorArray(NULL);
00303 }
00304
00305 for(int i=0; i<mTexCoordArrays.size(); i++)
00306 setVertexAttribArray( index++, mTexCoordArrays[i]->mTexCoordArray.get() );
00307 mTexCoordArrays.clear();
00308
00309 if (secondaryColorArray())
00310 {
00311 setVertexAttribArray(index++, secondaryColorArray());
00312 setSecondaryColorArray(NULL);
00313 }
00314
00315 if (fogCoordArray())
00316 {
00317 setVertexAttribArray(index++, fogCoordArray());
00318 setFogCoordArray(NULL);
00319 }
00320 }
00321
00322 void Geometry::computeNormals(bool verbose)
00323 {
00324 ArrayAbstract* posarr = vertexArray() ? vertexArray() : vertexAttrib(0);
00325 if (!posarr || posarr->size() == 0)
00326 {
00327 Log::warning("Geometry::computeNormals() not performed: no vertex coordinate array present!\n");
00328 return;
00329 }
00330
00331 ref<ArrayFloat3> norm3f = new ArrayFloat3;
00332 norm3f->resize( posarr->size() );
00333 setNormalArray( norm3f.get() );
00334
00335
00336 for(int i=0; i<(int)posarr->size(); ++i)
00337 (*norm3f)[i] = 0;
00338
00339
00340 for(int prim=0; prim<(int)drawCalls()->size(); prim++)
00341 {
00342
00343 for(TriangleIterator trit = mDrawCalls[prim]->triangleIterator(); !trit.isEnd(); trit.next())
00344 {
00345 size_t a = trit.a();
00346 size_t b = trit.b();
00347 size_t c = trit.c();
00348
00349 if (verbose)
00350 if (a == b || b == c || c == a)
00351 {
00352 Log::warning( Say("Geometry::computeNormals(): skipping degenerate triangle %n %n %n\n") << a << b << c );
00353 continue;
00354 }
00355
00356 VL_CHECK( a < posarr->size() )
00357 VL_CHECK( b < posarr->size() )
00358 VL_CHECK( c < posarr->size() )
00359
00360 vec3 n, v0, v1, v2;
00361
00362 v0 = posarr->vectorAsVec4(a).xyz();
00363 v1 = posarr->vectorAsVec4(b).xyz();
00364 v2 = posarr->vectorAsVec4(c).xyz();
00365
00366 if (verbose)
00367 if (v0 == v1 || v1 == v2 || v2 == v0)
00368 {
00369 Log::warning("Geometry::computeNormals(): skipping degenerate triangle (same vertex coodinate).\n");
00370 continue;
00371 }
00372
00373 v1 -= v0;
00374 v2 -= v0;
00375
00376 n = cross(v1, v2);
00377 n.normalize();
00378 if (verbose)
00379 if ( fabs(1.0f - n.length()) > 0.1f )
00380 {
00381 Log::warning("Geometry::computeNormals(): skipping degenerate triangle (normalization failed).\n");
00382 continue;
00383 }
00384
00385 (*norm3f)[a] += (fvec3)n;
00386 (*norm3f)[b] += (fvec3)n;
00387 (*norm3f)[c] += (fvec3)n;
00388 }
00389 }
00390
00391
00392 for(int i=0; i<(int)norm3f->size(); ++i)
00393 (*norm3f)[i].normalize();
00394 }
00395
00396 void Geometry::deleteVBOs()
00397 {
00398 if (!(GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0))
00399 return;
00400
00401 for(int i=0; i<(int)drawCalls()->size(); ++i)
00402 drawCalls()->at(i)->deleteVBOs();
00403
00404 if (mVertexArray)
00405 mVertexArray->gpuBuffer()->deleteGLBufferObject();
00406
00407 if (mNormalArray)
00408 mNormalArray->gpuBuffer()->deleteGLBufferObject();
00409
00410 if (mColorArray)
00411 mColorArray->gpuBuffer()->deleteGLBufferObject();
00412
00413 if (mSecondaryColorArray)
00414 mSecondaryColorArray->gpuBuffer()->deleteGLBufferObject();
00415
00416 if (mFogCoordArray)
00417 mFogCoordArray->gpuBuffer()->deleteGLBufferObject();
00418
00419 for (int i=0; i<mTexCoordArrays.size(); ++i)
00420 mTexCoordArrays[i]->mTexCoordArray->gpuBuffer()->deleteGLBufferObject();
00421
00422 for(int i=0; i<vertexAttribArrays()->size(); ++i)
00423 if ( vertexAttribArrays()->at(i)->data() )
00424 vertexAttribArrays()->at(i)->data()->gpuBuffer()->deleteGLBufferObject();
00425 }
00426
00427 void Geometry::updateVBOs(bool discard_local_data, bool force_update)
00428 {
00429 setVBODirty(false);
00430
00431 if (!(GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0))
00432 return;
00433
00434 if ( mVertexArray && (mVertexArray->isVBODirty() || force_update) )
00435 mVertexArray->updateVBO(discard_local_data);
00436
00437 if ( mNormalArray && (mNormalArray->isVBODirty() || force_update) )
00438 mNormalArray->updateVBO(discard_local_data);
00439
00440 if ( mColorArray && (mColorArray->isVBODirty() || force_update) )
00441 mColorArray->updateVBO(discard_local_data);
00442
00443 if ( mSecondaryColorArray && (mSecondaryColorArray->isVBODirty() || force_update) )
00444 mSecondaryColorArray->updateVBO(discard_local_data);
00445
00446 if ( mFogCoordArray && (mFogCoordArray->isVBODirty() || force_update) )
00447 mFogCoordArray->updateVBO(discard_local_data);
00448
00449 for(int i=0; i<mTexCoordArrays.size(); ++i)
00450 {
00451 if ( mTexCoordArrays[i]->mTexCoordArray->isVBODirty() || force_update )
00452 mTexCoordArrays[i]->mTexCoordArray->updateVBO(discard_local_data);
00453 }
00454
00455 for(int i=0; i<vertexAttribArrays()->size(); ++i)
00456 if ( vertexAttribArrays()->at(i)->data() )
00457 vertexAttribArrays()->at(i)->data()->updateVBO(discard_local_data);
00458
00459 for(int i=0; i<drawCalls()->size(); ++i)
00460 drawCalls()->at(i)->updateVBOs(discard_local_data, force_update);
00461 }
00462
00463 void Geometry::render_Implementation(const Actor*, const Shader*, const Camera*, OpenGLContext* gl_context) const
00464 {
00465 VL_CHECK_OGL()
00466
00467
00468
00469 if (gl_context->isCompatible())
00470 {
00471 if (!normalArray())
00472 glNormal3fv(mNormal.ptr());
00473
00474 if (!colorArray())
00475 glColor4fv(mColor.ptr());
00476
00477 if (!secondaryColorArray() && GLEW_VERSION_1_4)
00478 glSecondaryColor3fv(mSecondaryColor.ptr());
00479 }
00480
00481
00482
00483 bool vbo_on = (GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0) && vboEnabled() && !isDisplayListEnabled();
00484 gl_context->bindVAS(this, vbo_on, false);
00485
00486
00487
00488 for(int i=0; i<(int)drawCalls()->size(); i++)
00489 if (drawCalls()->at(i)->isEnabled())
00490 drawCalls()->at(i)->render( vbo_on );
00491
00492 VL_CHECK_OGL()
00493 }
00494
00495 void Geometry::transform(const mat4& m, bool normalize)
00496 {
00497 ArrayAbstract* posarr = vertexArray() ? vertexArray() : vertexAttrib(0);
00498 if (posarr)
00499 posarr->transform(m);
00500
00501 if (normalArray())
00502 {
00503 mat4 nmat = m.as3x3().getInverse().transpose();
00504 normalArray()->transform(nmat);
00505 if (normalize)
00506 normalArray()->normalize();
00507 }
00508 }
00509
00510 void Geometry::setVertexAttribArray(const VertexAttribInfo& info)
00511 {
00512 for(int i=0; i<vertexAttribArrays()->size(); ++i)
00513 {
00514 VL_CHECK(vertexAttribArrays()->at(i))
00515 if (vertexAttribArrays()->at(i)->attribIndex() == info.attribIndex())
00516 {
00517 *vertexAttribArrays()->at(i) = info;
00518 return;
00519 }
00520 }
00521 mVertexAttribArrays.push_back( new VertexAttribInfo(info) );
00522 }
00523
00524 const ArrayAbstract* Geometry::vertexAttrib(unsigned int name) const
00525 {
00526 const VertexAttribInfo* attrib_info = vertexAttribInfo(name);
00527 if (attrib_info)
00528 return attrib_info->data();
00529 else
00530 return NULL;
00531 }
00532
00533 ArrayAbstract* Geometry::vertexAttrib(unsigned int name)
00534 {
00535 VertexAttribInfo* attrib_info = vertexAttribInfo(name);
00536 if (attrib_info)
00537 return attrib_info->data();
00538 else
00539 return NULL;
00540 }
00541
00542 const VertexAttribInfo* Geometry::vertexAttribInfo(unsigned int name) const
00543 {
00544 for(int i=0; i<vertexAttribArrays()->size(); ++i)
00545 if (vertexAttribArrays()->at(i)->attribIndex() == name)
00546 return vertexAttribArrays()->at(i);
00547 return NULL;
00548 }
00549
00550 VertexAttribInfo* Geometry::vertexAttribInfo(unsigned int name)
00551 {
00552 for(int i=0; i<vertexAttribArrays()->size(); ++i)
00553 if (vertexAttribArrays()->at(i)->attribIndex() == name)
00554 return vertexAttribArrays()->at(i);
00555 return NULL;
00556 }
00557
00558 ref<VertexAttribInfo> Geometry::eraseVertexAttrib(unsigned int name)
00559 {
00560 ref<VertexAttribInfo> vai;
00561 for(int i=0; i<vertexAttribArrays()->size(); ++i)
00562 {
00563 if (vertexAttribArrays()->at(i)->attribIndex() == name)
00564 {
00565 vai = vertexAttribArrays()->at(i);
00566 vertexAttribArrays()->eraseAt(i);
00567 return vai;
00568 }
00569 }
00570 return NULL;
00571 }
00572
00573 void Geometry::mergeTriangleStrips()
00574 {
00575 std::vector< ref<DrawElementsUInt> > de;
00576 std::vector<size_t> indices;
00577
00578
00579 for(int i=drawCalls()->size(); i--; )
00580 {
00581 ref<DrawElementsUInt> de_uint = dynamic_cast<DrawElementsUInt*>( drawCalls()->at(i) );
00582 if (de_uint && de_uint->primitiveType() == PT_TRIANGLE_STRIP)
00583 {
00584 de.push_back(de_uint);
00585 drawCalls()->erase(i,1);
00586 }
00587 }
00588
00589
00590 indices.reserve( vertexArray()->size()*2 );
00591 for(size_t i=0; i<de.size(); ++i)
00592 {
00593 if (!de[i]->indices()->size())
00594 continue;
00595 for(size_t j=0; j<de[i]->indices()->size(); ++j)
00596 indices.push_back(de[i]->indices()->at(j));
00597
00598 if ( de[i]->indices()->size() % 2 )
00599 indices.push_back(indices.back());
00600
00601 if ( i != de.size()-1 )
00602 {
00603 indices.push_back(indices.back());
00604 indices.push_back(de[i+1]->indices()->at(0));
00605 indices.push_back(de[i+1]->indices()->at(0));
00606 indices.push_back(de[i+1]->indices()->at(1));
00607 }
00608 }
00609
00610 if (indices.size())
00611 {
00612 ref<DrawElementsUInt> draw_elems = new DrawElementsUInt(PT_TRIANGLE_STRIP);
00613 draw_elems->indices()->resize(indices.size());
00614 memcpy(draw_elems->indices()->ptr(), &indices[0], sizeof(unsigned int)*indices.size());
00615 drawCalls()->push_back(draw_elems.get());
00616 }
00617 }
00618
00619 void Geometry::regenerateVertices(const std::vector<size_t>& map_new_to_old)
00620 {
00621 VertexMapper mapper;
00622
00623 if (vertexArray())
00624 setVertexArray( mapper.regenerate( vertexArray(), map_new_to_old ).get() );
00625
00626 if (normalArray())
00627 setNormalArray( mapper.regenerate( normalArray(), map_new_to_old ).get() );
00628
00629 if (colorArray())
00630 setColorArray( mapper.regenerate( colorArray(), map_new_to_old ).get() );
00631
00632 if (secondaryColorArray())
00633 setSecondaryColorArray( mapper.regenerate( secondaryColorArray(), map_new_to_old ).get() );
00634
00635 if (fogCoordArray())
00636 setFogCoordArray( mapper.regenerate( fogCoordArray(), map_new_to_old ).get() );
00637
00638 for(int itex=0; itex<VL_MAX_TEXTURE_UNITS; ++itex)
00639 if (texCoordArray(itex))
00640 setTexCoordArray( itex, mapper.regenerate( texCoordArray(itex), map_new_to_old ).get() );
00641
00642 for(int i=0; i<vertexAttribArrays()->size(); ++i)
00643 vertexAttribArrays()->at(i)->setData( mapper.regenerate(vertexAttribArrays()->at(i)->data(), map_new_to_old ).get() );
00644 }
00645
00646 void Geometry::convertDrawCallToDrawArrays()
00647 {
00648
00649 std::vector<size_t> map_new_to_old;
00650 map_new_to_old.reserve( vertexArray()->size() * 3 );
00651
00652 for(int i=drawCalls()->size(); i--; )
00653 {
00654 int start = (int)map_new_to_old.size();
00655 for(IndexIterator it=drawCalls()->at(i)->indexIterator(); !it.isEnd(); it.next())
00656 map_new_to_old.push_back(it.index());
00657 int count = (int)map_new_to_old.size() - start;
00658
00659
00660 ref<DrawArrays> da = new vl::DrawArrays( drawCalls()->at(i)->primitiveType(), start, count, drawCalls()->at(i)->instances() );
00661 drawCalls()->erase(i,1);
00662 drawCalls()->push_back(da.get());
00663 }
00664
00665 regenerateVertices(map_new_to_old);
00666 }
00667
00668 bool Geometry::sortVertices()
00669 {
00670
00671 std::vector< ref<DrawElementsUInt> > de_uint;
00672
00673
00674 for(int i=0; i<drawCalls()->size(); ++i)
00675 {
00676 DrawElementsUInt* dei = dynamic_cast<DrawElementsUInt*>(drawCalls()->at(i));
00677 DrawElementsUShort* des = dynamic_cast<DrawElementsUShort*>(drawCalls()->at(i));
00678 DrawElementsUByte* deb = dynamic_cast<DrawElementsUByte*>(drawCalls()->at(i));
00679 if (dei)
00680 de_uint.push_back(dei);
00681 else
00682 if(des)
00683 {
00684 dei = new DrawElementsUInt(des->primitiveType(), des->instances());
00685 de_uint.push_back(dei);
00686 dei->indices()->resize( des->indices()->size() );
00687 for(unsigned int j=0; j<des->indices()->size(); ++j)
00688 dei->indices()->at(j) = des->indices()->at(j);
00689 }
00690 else
00691 if(deb)
00692 {
00693 dei = new DrawElementsUInt(deb->primitiveType(), deb->instances());
00694 de_uint.push_back(dei);
00695 dei->indices()->resize( deb->indices()->size() );
00696 for(unsigned int j=0; j<deb->indices()->size(); ++j)
00697 dei->indices()->at(j) = deb->indices()->at(j);
00698 }
00699 else
00700 return false;
00701 }
00702
00703 drawCalls()->clear();
00704
00705
00706 std::vector<size_t> map_new_to_old;
00707 map_new_to_old.resize( vertexArray()->size() );
00708 memset(&map_new_to_old[0], 0xFF, map_new_to_old.size()*sizeof(map_new_to_old[0]));
00709
00710 std::vector<size_t> map_old_to_new;
00711 map_old_to_new.resize( vertexArray()->size() );
00712 memset(&map_old_to_new[0], 0xFF, map_old_to_new.size()*sizeof(map_old_to_new[0]));
00713
00714 std::vector<size_t> used;
00715 used.resize( vertexArray()->size() );
00716 memset(&used[0], 0, used.size()*sizeof(used[0]));
00717
00718 size_t index = 0;
00719 for(int i=(int)de_uint.size(); i--; )
00720 {
00721 for(size_t idx=0; idx<de_uint[i]->indices()->size(); ++idx)
00722 if (!used[de_uint[i]->indices()->at(idx)])
00723 {
00724 map_new_to_old[index] = de_uint[i]->indices()->at(idx);
00725 map_old_to_new[de_uint[i]->indices()->at(idx)] = index;
00726 index++;
00727 used[de_uint[i]->indices()->at(idx)] = 1;
00728 }
00729 }
00730
00731 regenerateVertices(map_new_to_old);
00732
00733
00734 for(size_t i=0; i<de_uint.size(); ++i)
00735 {
00736 drawCalls()->push_back(de_uint[i].get());
00737 for(size_t j=0; j<de_uint[i]->indices()->size(); ++j)
00738 {
00739 de_uint[i]->indices()->at(j) = (GLuint)map_old_to_new[de_uint[i]->indices()->at(j)];
00740 }
00741 }
00742
00743 return true;
00744 }
00745
00746 void Geometry::colorizePrimitives()
00747 {
00748 ref<ArrayFloat4> col = new vl::ArrayFloat4;
00749 col->resize( vertexArray()->size() );
00750 setColorArray( col.get() );
00751
00752 for(int i=0; i<drawCalls()->size(); ++i)
00753 {
00754 fvec4 c;
00755 c.r() = rand()%100 / 99.0f;
00756 c.g() = rand()%100 / 99.0f;
00757 c.b() = rand()%100 / 99.0f;
00758 c.a() = 1.0f;
00759
00760 for(IndexIterator it=drawCalls()->at(i)->indexIterator(); !it.isEnd(); it.next())
00761 col->at( it.index() ) = c;
00762 }
00763 }
00764
00765 void Geometry::computeTangentSpace(
00766 size_t vert_count,
00767 const fvec3 *vertex,
00768 const fvec3* normal,
00769 const fvec2 *texcoord,
00770 const DrawCall* prim,
00771 fvec3 *tangent,
00772 fvec3 *bitangent )
00773 {
00774 std::vector<fvec3> tan1;
00775 std::vector<fvec3> tan2;
00776 tan1.resize(vert_count);
00777 tan2.resize(vert_count);
00778
00779 for ( TriangleIterator trit = prim->triangleIterator(); !trit.isEnd(); trit.next() )
00780 {
00781 unsigned int tri[] = { trit.a(), trit.b(), trit.c() };
00782
00783 VL_CHECK(tri[0] < vert_count );
00784 VL_CHECK(tri[1] < vert_count );
00785 VL_CHECK(tri[2] < vert_count );
00786
00787 const fvec3& v1 = vertex[tri[0]];
00788 const fvec3& v2 = vertex[tri[1]];
00789 const fvec3& v3 = vertex[tri[2]];
00790
00791 const fvec2& w1 = texcoord[tri[0]];
00792 const fvec2& w2 = texcoord[tri[1]];
00793 const fvec2& w3 = texcoord[tri[2]];
00794
00795 float x1 = v2.x() - v1.x();
00796 float x2 = v3.x() - v1.x();
00797 float y1 = v2.y() - v1.y();
00798 float y2 = v3.y() - v1.y();
00799 float z1 = v2.z() - v1.z();
00800 float z2 = v3.z() - v1.z();
00801
00802 float s1 = w2.x() - w1.x();
00803 float s2 = w3.x() - w1.x();
00804 float t1 = w2.y() - w1.y();
00805 float t2 = w3.y() - w1.y();
00806
00807 float r = 1.0F / (s1 * t2 - s2 * t1);
00808 fvec3 sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
00809 fvec3 tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
00810
00811 tan1[tri[0]] += sdir;
00812 tan1[tri[1]] += sdir;
00813 tan1[tri[2]] += sdir;
00814
00815 tan2[tri[0]] += tdir;
00816 tan2[tri[1]] += tdir;
00817 tan2[tri[2]] += tdir;
00818 }
00819
00820 for ( size_t a = 0; a < vert_count; a++)
00821 {
00822 const fvec3& n = normal[a];
00823 const fvec3& t = tan1[a];
00824
00825
00826 tangent[a] = (t - n * dot(n, t)).normalize();
00827
00828 if ( bitangent )
00829 {
00830
00831 float w = (dot(cross(n, t), tan2[a]) < 0.0F) ? -1.0F : 1.0F;
00832 bitangent[a] = cross( n, tangent[a] ) * w;
00833 }
00834 }
00835 }
00836