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