Blender V2.61 - r43446

RAS_MaterialBucket.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include "RAS_MaterialBucket.h"
00034 
00035 #if defined(WIN32) && !defined(FREE_WINDOWS)
00036 #pragma warning (disable:4786)
00037 #endif
00038 
00039 #ifdef WIN32
00040 #include <windows.h>
00041 #endif // WIN32
00042 
00043 #include "RAS_Polygon.h"
00044 #include "RAS_TexVert.h"
00045 #include "RAS_IRasterizer.h"
00046 #include "RAS_IRenderTools.h"
00047 #include "RAS_MeshObject.h"
00048 #include "RAS_Deformer.h"   // __NLA
00049 
00050 /* mesh slot */
00051 
00052 RAS_MeshSlot::RAS_MeshSlot() : SG_QList()
00053 {
00054     m_clientObj = NULL;
00055     m_pDeformer = NULL;
00056     m_OpenGLMatrix = NULL;
00057     m_mesh = NULL;
00058     m_bucket = NULL;
00059     m_bVisible = false;
00060     m_bCulled = true;
00061     m_bObjectColor = false;
00062     m_RGBAcolor = MT_Vector4(0.0, 0.0, 0.0, 0.0);
00063     m_DisplayList = NULL;
00064     m_bDisplayList = true;
00065     m_joinSlot = NULL;
00066     m_pDerivedMesh = NULL;
00067 }
00068 
00069 RAS_MeshSlot::~RAS_MeshSlot()
00070 {
00071     RAS_DisplayArrayList::iterator it;
00072 
00073 #ifdef USE_SPLIT
00074     Split(true);
00075 
00076     while(m_joinedSlots.size())
00077         m_joinedSlots.front()->Split(true);
00078 #endif
00079 
00080     for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
00081         (*it)->m_users--;
00082         if((*it)->m_users == 0)
00083             delete *it;
00084     }
00085 
00086     if (m_DisplayList) {
00087         m_DisplayList->Release();
00088         m_DisplayList = NULL;
00089     }
00090 }
00091 
00092 RAS_MeshSlot::RAS_MeshSlot(const RAS_MeshSlot& slot) : SG_QList()
00093 {
00094     RAS_DisplayArrayList::iterator it;
00095 
00096     m_clientObj = NULL;
00097     m_pDeformer = NULL;
00098     m_pDerivedMesh = NULL;
00099     m_OpenGLMatrix = NULL;
00100     m_mesh = slot.m_mesh;
00101     m_bucket = slot.m_bucket;
00102     m_bVisible = slot.m_bVisible;
00103     m_bCulled = slot.m_bCulled;
00104     m_bObjectColor = slot.m_bObjectColor;
00105     m_RGBAcolor = slot.m_RGBAcolor;
00106     m_DisplayList = NULL;
00107     m_bDisplayList = slot.m_bDisplayList;
00108     m_joinSlot = NULL;
00109     m_currentArray = slot.m_currentArray;
00110     m_displayArrays = slot.m_displayArrays;
00111     m_joinedSlots = slot.m_joinedSlots;
00112 
00113     m_startarray = slot.m_startarray;
00114     m_startvertex = slot.m_startvertex;
00115     m_startindex = slot.m_startindex;
00116     m_endarray = slot.m_endarray;
00117     m_endvertex = slot.m_endvertex;
00118     m_endindex = slot.m_endindex;
00119 
00120     for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
00121         // don't copy display arrays for now because it breaks python 
00122         // access to vertices, but we'll need a solution if we want to
00123         // join display arrays for reducing draw calls.
00124         //*it = new RAS_DisplayArray(**it);
00125         //(*it)->m_users = 1;
00126 
00127         (*it)->m_users++;
00128     }
00129 }
00130 
00131 void RAS_MeshSlot::init(RAS_MaterialBucket *bucket, int numverts)
00132 {
00133     m_bucket = bucket;
00134 
00135     SetDisplayArray(numverts);
00136 
00137     m_startarray = 0;
00138     m_startvertex = 0;
00139     m_startindex = 0;
00140     m_endarray = 0;
00141     m_endvertex = 0;
00142     m_endindex = 0;
00143 }
00144 
00145 void RAS_MeshSlot::begin(RAS_MeshSlot::iterator& it)
00146 {
00147     int startvertex, endvertex;
00148     int startindex, endindex;
00149 
00150     it.array = (m_displayArrays.size() > 0)? m_displayArrays[m_startarray]: NULL;
00151 
00152     if(it.array == NULL || it.array->m_index.size() == 0 || it.array->m_vertex.size() == 0) {
00153         it.array = NULL;
00154         it.vertex = NULL;
00155         it.index = NULL;
00156         it.startvertex = 0;
00157         it.endvertex = 0;
00158         it.totindex = 0;
00159     }
00160     else {
00161         startvertex = m_startvertex;
00162         endvertex = (m_startarray == m_endarray)? m_endvertex: it.array->m_vertex.size();
00163         startindex = m_startindex;
00164         endindex = (m_startarray == m_endarray)? m_endindex: it.array->m_index.size();
00165 
00166         it.vertex = &it.array->m_vertex[0];
00167         it.index = &it.array->m_index[startindex];
00168         it.startvertex = startvertex;
00169         it.endvertex = endvertex;
00170         it.totindex = endindex-startindex;
00171         it.arraynum = m_startarray;
00172     }
00173 }
00174 
00175 void RAS_MeshSlot::next(RAS_MeshSlot::iterator& it)
00176 {
00177     int startvertex, endvertex;
00178     int startindex, endindex;
00179 
00180     if(it.arraynum == (size_t)m_endarray) {
00181         it.array = NULL;
00182         it.vertex = NULL;
00183         it.index = NULL;
00184         it.startvertex = 0;
00185         it.endvertex = 0;
00186         it.totindex = 0;
00187     }
00188     else {
00189         it.arraynum++;
00190         it.array = m_displayArrays[it.arraynum];
00191 
00192         startindex = 0;
00193         endindex = (it.arraynum == (size_t)m_endarray)? m_endindex: it.array->m_index.size();
00194         startvertex = 0;
00195         endvertex = (it.arraynum == (size_t)m_endarray)? m_endvertex: it.array->m_vertex.size();
00196 
00197         it.vertex = &it.array->m_vertex[0];
00198         it.index = &it.array->m_index[startindex];
00199         it.startvertex = startvertex;
00200         it.endvertex = endvertex;
00201         it.totindex = endindex-startindex;
00202     }
00203 }
00204 
00205 bool RAS_MeshSlot::end(RAS_MeshSlot::iterator& it)
00206 {
00207     return (it.array == NULL);
00208 }
00209 
00210 RAS_DisplayArray *RAS_MeshSlot::CurrentDisplayArray()
00211 {
00212     return m_currentArray;
00213 }
00214 
00215 void RAS_MeshSlot::SetDisplayArray(int numverts)
00216 {
00217     RAS_DisplayArrayList::iterator it;
00218     RAS_DisplayArray *darray = NULL;
00219     
00220     for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
00221         darray = *it;
00222 
00223         if(darray->m_type == numverts) {
00224             if(darray->m_index.size()+numverts >= RAS_DisplayArray::BUCKET_MAX_INDEX)
00225                 darray = NULL;
00226             else if(darray->m_vertex.size()+numverts >= RAS_DisplayArray::BUCKET_MAX_VERTEX)
00227                 darray = NULL;
00228             else
00229                 break;
00230         }
00231         else
00232             darray = NULL;
00233     }
00234 
00235     if(!darray) {
00236         darray = new RAS_DisplayArray();
00237         darray->m_users = 1;
00238 
00239         if(numverts == 2) darray->m_type = RAS_DisplayArray::LINE;
00240         else if(numverts == 3) darray->m_type = RAS_DisplayArray::TRIANGLE;
00241         else darray->m_type = RAS_DisplayArray::QUAD;
00242 
00243         m_displayArrays.push_back(darray);
00244 
00245         if(numverts == 2)
00246             darray->m_type = RAS_DisplayArray::LINE;
00247         else if(numverts == 3)
00248             darray->m_type = RAS_DisplayArray::TRIANGLE;
00249         else if(numverts == 4)
00250             darray->m_type = RAS_DisplayArray::QUAD;
00251         
00252         m_endarray = m_displayArrays.size()-1;
00253         m_endvertex = 0;
00254         m_endindex = 0;
00255     }
00256 
00257     m_currentArray = darray;
00258 }
00259 
00260 void RAS_MeshSlot::AddPolygon(int numverts)
00261 {
00262     SetDisplayArray(numverts);
00263 }
00264 
00265 int RAS_MeshSlot::AddVertex(const RAS_TexVert& tv)
00266 {
00267     RAS_DisplayArray *darray;
00268     int offset;
00269     
00270     darray = m_currentArray;
00271     darray->m_vertex.push_back(tv);
00272     offset = darray->m_vertex.size()-1;
00273 
00274     if(darray == m_displayArrays[m_endarray])
00275         m_endvertex++;
00276 
00277     return offset;
00278 }
00279 
00280 void RAS_MeshSlot::AddPolygonVertex(int offset)
00281 {
00282     RAS_DisplayArray *darray;
00283 
00284     darray = m_currentArray;
00285     darray->m_index.push_back(offset);
00286 
00287     if(darray == m_displayArrays[m_endarray])
00288         m_endindex++;
00289 }
00290 
00291 void RAS_MeshSlot::SetDeformer(RAS_Deformer* deformer)
00292 {
00293     if (deformer && m_pDeformer != deformer) {
00294         RAS_DisplayArrayList::iterator it;
00295         if (deformer->ShareVertexArray()) {
00296             // this deformer uses the base vertex array, first release the current ones
00297             for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
00298                 (*it)->m_users--;
00299                 if((*it)->m_users == 0)
00300                     delete *it;
00301             }
00302             m_displayArrays.clear();
00303             // then hook to the base ones
00304             RAS_MeshMaterial *mmat = m_mesh->GetMeshMaterial(m_bucket->GetPolyMaterial());
00305             if (mmat && mmat->m_baseslot) {
00306                 m_displayArrays = mmat->m_baseslot->m_displayArrays;
00307                 for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
00308                     (*it)->m_users++;
00309                 }
00310             }
00311         }
00312         else {
00313             // no sharing
00314             // we create local copy of RAS_DisplayArray when we have a deformer:
00315             // this way we can avoid conflict between the vertex cache of duplicates
00316             for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
00317                 if (deformer->UseVertexArray()) {
00318                     // the deformer makes use of vertex array, make sure we have our local copy
00319                     if ((*it)->m_users > 1) {
00320                         // only need to copy if there are other users
00321                         // note that this is the usual case as vertex arrays are held by the material base slot
00322                         RAS_DisplayArray *newarray = new RAS_DisplayArray(*(*it));
00323                         newarray->m_users = 1;
00324                         (*it)->m_users--;
00325                         *it = newarray;
00326                     }
00327                 } else {
00328                     // the deformer is not using vertex array (Modifier), release them
00329                     (*it)->m_users--;
00330                     if((*it)->m_users == 0)
00331                         delete *it;
00332                 }
00333             }
00334             if (!deformer->UseVertexArray()) {
00335                 m_displayArrays.clear();
00336                 m_startarray = 0;
00337                 m_startvertex = 0;
00338                 m_startindex = 0;
00339                 m_endarray = 0;
00340                 m_endvertex = 0;
00341                 m_endindex = 0;
00342             }
00343         }
00344     }
00345     m_pDeformer = deformer;
00346 }
00347 
00348 bool RAS_MeshSlot::Equals(RAS_MeshSlot *target)
00349 {
00350     if(!m_OpenGLMatrix || !target->m_OpenGLMatrix)
00351         return false;
00352     if(m_pDeformer || target->m_pDeformer)
00353         return false;
00354     if(m_bVisible != target->m_bVisible)
00355         return false;
00356     if(m_bObjectColor != target->m_bObjectColor)
00357         return false;
00358     if(m_bObjectColor && !(m_RGBAcolor == target->m_RGBAcolor))
00359         return false;
00360     
00361     return true;
00362 }
00363 
00364 bool RAS_MeshSlot::Join(RAS_MeshSlot *target, MT_Scalar distance)
00365 {
00366     RAS_DisplayArrayList::iterator it;
00367     iterator mit;
00368     size_t i;
00369 
00370     // verify if we can join
00371     if(m_joinSlot || m_joinedSlots.size() || target->m_joinSlot)
00372         return false;
00373 
00374     if(!Equals(target))
00375         return false;
00376     
00377     MT_Vector3 co(&m_OpenGLMatrix[12]);
00378     MT_Vector3 targetco(&target->m_OpenGLMatrix[12]);
00379 
00380     if((co - targetco).length() > distance)
00381         return false;
00382 
00383     MT_Matrix4x4 mat(m_OpenGLMatrix);
00384     MT_Matrix4x4 targetmat(target->m_OpenGLMatrix);
00385     targetmat.invert();
00386 
00387     MT_Matrix4x4 transform = targetmat*mat;
00388     
00389     // m_mesh, clientobj
00390     m_joinSlot = target;
00391     m_joinInvTransform = transform;
00392     m_joinInvTransform.invert();
00393     target->m_joinedSlots.push_back(this);
00394 
00395     MT_Matrix4x4 ntransform = m_joinInvTransform.transposed();
00396     ntransform[0][3]= ntransform[1][3]= ntransform[2][3]= 0.0f;
00397 
00398     for(begin(mit); !end(mit); next(mit))
00399         for(i=mit.startvertex; i<mit.endvertex; i++)
00400             mit.vertex[i].Transform(transform, ntransform);
00401     
00402     /* We know we'll need a list at least this big, reserve in advance */
00403     target->m_displayArrays.reserve(target->m_displayArrays.size() + m_displayArrays.size());
00404 
00405     for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
00406         target->m_displayArrays.push_back(*it);
00407         target->m_endarray++;
00408         target->m_endvertex = target->m_displayArrays.back()->m_vertex.size();
00409         target->m_endindex = target->m_displayArrays.back()->m_index.size();
00410     }
00411 
00412     if (m_DisplayList) {
00413         m_DisplayList->Release();
00414         m_DisplayList = NULL;
00415     }
00416     if (target->m_DisplayList) {
00417         target->m_DisplayList->Release();
00418         target->m_DisplayList = NULL;
00419     }
00420     
00421     return true;
00422 #if 0
00423     return false;
00424 #endif
00425 }
00426 
00427 bool RAS_MeshSlot::Split(bool force)
00428 {
00429     list<RAS_MeshSlot*>::iterator jit;
00430     RAS_MeshSlot *target = m_joinSlot;
00431     RAS_DisplayArrayList::iterator it, jt;
00432     iterator mit;
00433     size_t i, found0 = 0, found1 = 0;
00434 
00435     if(target && (force || !Equals(target))) {
00436         m_joinSlot = NULL;
00437 
00438         for(jit=target->m_joinedSlots.begin(); jit!=target->m_joinedSlots.end(); jit++) {
00439             if(*jit == this) {
00440                 target->m_joinedSlots.erase(jit);
00441                 found0 = 1;
00442                 break;
00443             }
00444         }
00445 
00446         if(!found0)
00447             abort();
00448 
00449         for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
00450             found1 = 0;
00451             for(jt=target->m_displayArrays.begin(); jt!=target->m_displayArrays.end(); jt++) {
00452                 if(*jt == *it) {
00453                     target->m_displayArrays.erase(jt);
00454                     target->m_endarray--;
00455                     found1 = 1;
00456                     break;
00457                 }
00458             }
00459 
00460             if(!found1)
00461                 abort();
00462         }
00463 
00464         if(target->m_displayArrays.size()) {
00465             target->m_endvertex = target->m_displayArrays.back()->m_vertex.size();
00466             target->m_endindex = target->m_displayArrays.back()->m_index.size();
00467         }
00468         else {
00469             target->m_endvertex = 0;
00470             target->m_endindex = 0;
00471         }
00472 
00473         MT_Matrix4x4 ntransform = m_joinInvTransform.inverse().transposed();
00474         ntransform[0][3]= ntransform[1][3]= ntransform[2][3]= 0.0f;
00475 
00476         for(begin(mit); !end(mit); next(mit))
00477             for(i=mit.startvertex; i<mit.endvertex; i++)
00478                 mit.vertex[i].Transform(m_joinInvTransform, ntransform);
00479 
00480         if (target->m_DisplayList) {
00481             target->m_DisplayList->Release();
00482             target->m_DisplayList = NULL;
00483         }
00484 
00485         return true;
00486     }
00487 
00488     return false;
00489 }
00490 
00491 
00492 #ifdef USE_SPLIT    
00493 bool RAS_MeshSlot::IsCulled()
00494 {
00495     if(m_joinSlot)
00496         return true;
00497     if(!m_bCulled)
00498         return false;
00499     list<RAS_MeshSlot*>::iterator it;
00500     for(it=m_joinedSlots.begin(); it!=m_joinedSlots.end(); it++)
00501         if(!(*it)->m_bCulled)
00502             return false;
00503     return true;
00504 }
00505 #endif  
00506 
00507 /* material bucket sorting */
00508 
00509 struct RAS_MaterialBucket::less
00510 {
00511     bool operator()(const RAS_MaterialBucket* x, const RAS_MaterialBucket* y) const 
00512     { 
00513         return *x->GetPolyMaterial() < *y->GetPolyMaterial(); 
00514     }
00515 };
00516 
00517 /* material bucket */
00518 
00519 RAS_MaterialBucket::RAS_MaterialBucket(RAS_IPolyMaterial* mat)
00520 {
00521     m_material = mat;
00522 }
00523 
00524 RAS_MaterialBucket::~RAS_MaterialBucket()
00525 {
00526 }
00527 
00528 RAS_IPolyMaterial* RAS_MaterialBucket::GetPolyMaterial() const
00529 { 
00530     return m_material;
00531 }
00532 
00533 bool RAS_MaterialBucket::IsAlpha() const
00534 {   
00535     return (m_material->IsAlpha());
00536 }
00537 
00538 bool RAS_MaterialBucket::IsZSort() const
00539 {   
00540     return (m_material->IsZSort());
00541 }
00542 
00543 RAS_MeshSlot* RAS_MaterialBucket::AddMesh(int numverts)
00544 {
00545     RAS_MeshSlot *ms;
00546 
00547     m_meshSlots.push_back(RAS_MeshSlot());
00548     
00549     ms = &m_meshSlots.back();
00550     ms->init(this, numverts);
00551 
00552     return ms;
00553 }
00554 
00555 RAS_MeshSlot* RAS_MaterialBucket::CopyMesh(RAS_MeshSlot *ms)
00556 {
00557     m_meshSlots.push_back(RAS_MeshSlot(*ms));
00558     
00559     return &m_meshSlots.back();
00560 }
00561 
00562 void RAS_MaterialBucket::RemoveMesh(RAS_MeshSlot* ms)
00563 {
00564     list<RAS_MeshSlot>::iterator it;
00565 
00566     for(it=m_meshSlots.begin(); it!=m_meshSlots.end(); it++) {
00567         if(&*it == ms) {
00568             m_meshSlots.erase(it);
00569             return;
00570         }
00571     }
00572 }
00573 
00574 list<RAS_MeshSlot>::iterator RAS_MaterialBucket::msBegin()
00575 {
00576     return m_meshSlots.begin();
00577 }
00578 
00579 list<RAS_MeshSlot>::iterator RAS_MaterialBucket::msEnd()
00580 {
00581     return m_meshSlots.end();
00582 }
00583 
00584 bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
00585     RAS_IRenderTools *rendertools)
00586 {
00587     bool uselights;
00588     
00589     if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW && !m_material->CastsShadows())
00590         return false;
00591 
00592     if(!rasty->SetMaterial(*m_material))
00593         return false;
00594     
00595     uselights= m_material->UsesLighting(rasty);
00596     rendertools->ProcessLighting(rasty, uselights, cameratrans);
00597     
00598     return true;
00599 }
00600 
00601 void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
00602     RAS_IRenderTools* rendertools, RAS_MeshSlot &ms)
00603 {
00604     m_material->ActivateMeshSlot(ms, rasty);
00605 
00606     if (ms.m_pDeformer)
00607     {
00608         ms.m_pDeformer->Apply(m_material);
00609     //  KX_ReInstanceShapeFromMesh(ms.m_mesh); // Recompute the physics mesh. (Can't call KX_* from RAS_)
00610     }
00611     
00612     if(IsZSort() && rasty->GetDrawingMode() >= RAS_IRasterizer::KX_SOLID)
00613         ms.m_mesh->SortPolygons(ms, cameratrans*MT_Transform(ms.m_OpenGLMatrix));
00614 
00615     rendertools->PushMatrix();
00616     if (!ms.m_pDeformer || !ms.m_pDeformer->SkipVertexTransform())
00617     {
00618         rendertools->applyTransform(rasty,ms.m_OpenGLMatrix,m_material->GetDrawingMode());
00619     }
00620 
00621     if(rasty->QueryLists())
00622         if(ms.m_DisplayList)
00623             ms.m_DisplayList->SetModified(ms.m_mesh->MeshModified());
00624 
00625     // verify if we can use display list, not for deformed object, and
00626     // also don't create a new display list when drawing shadow buffers,
00627     // then it won't have texture coordinates for actual drawing. also
00628     // for zsort we can't make a display list, since the polygon order
00629     // changes all the time.
00630     if(ms.m_pDeformer && ms.m_pDeformer->IsDynamic())
00631         ms.m_bDisplayList = false;
00632     else if(!ms.m_DisplayList && rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW)
00633         ms.m_bDisplayList = false;
00634     else if (IsZSort())
00635         ms.m_bDisplayList = false;
00636     else if(m_material->UsesObjectColor() && ms.m_bObjectColor)
00637         ms.m_bDisplayList = false;
00638     else
00639         ms.m_bDisplayList = true;
00640 
00641     // for text drawing using faces
00642     if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT)
00643         rasty->IndexPrimitives_3DText(ms, m_material, rendertools);
00644     // for multitexturing
00645     else if((m_material->GetFlag() & (RAS_MULTITEX|RAS_BLENDERGLSL)))
00646         rasty->IndexPrimitivesMulti(ms);
00647     // use normal IndexPrimitives
00648     else
00649         rasty->IndexPrimitives(ms);
00650 
00651     if(rasty->QueryLists())
00652         if(ms.m_DisplayList)
00653             ms.m_mesh->SetMeshModified(false);
00654 
00655     rendertools->PopMatrix();
00656 }
00657 
00658 void RAS_MaterialBucket::Optimize(MT_Scalar distance)
00659 {
00660     /* TODO: still have to check before this works correct:
00661      * - lightlayer, frontface, text, billboard
00662      * - make it work with physics */
00663     
00664 #if 0
00665     list<RAS_MeshSlot>::iterator it;
00666     list<RAS_MeshSlot>::iterator jt;
00667 
00668     // greed joining on all following buckets
00669     for(it=m_meshSlots.begin(); it!=m_meshSlots.end(); it++)
00670         for(jt=it, jt++; jt!=m_meshSlots.end(); jt++)
00671             jt->Join(&*it, distance);
00672 #endif
00673 }
00674