lugre_fastbatch.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include "lugre_fastbatch.h"
00003 #include "lugre_meshbuffer.h"
00004 #include <stdlib.h>
00005 #include <list>
00006 #include <Ogre.h>
00007 #include <utility>
00008 
00009 #define DEBUG_FASTBATCH 0
00010 
00011 // TODO : gfx3d::AttachObject   (Ogre::MovableObject* pObj); // all cSubBatch es   pSceneNode->attachObject(this);
00012 
00013 //~ static inline void  WriteColour (void* pWriter,const Ogre::ColourValue& c) { 
00014     //~ mpRenderSys->convertColourValue(c, reinterpret_cast<Ogre::uint32*>(pWriter)); // c.getAsRGBA()
00015 //~ }
00016 
00017 using namespace Ogre;
00018 
00019 namespace Lugre {
00020 
00021 // ***** ***** ***** ***** ***** cFastBatch
00022     
00023 cFastBatch::cFastBatch  () : mfBoundRad(0) { 
00024     mParentNode = NULL;
00025 
00026     //~ // Generate name
00027     StringUtil::StrStreamType name;
00028     static int ms_uGenNameCount = 1;
00029     name << "LugreFastBatch" << ms_uGenNameCount++;
00030     mName = name.str();
00031 
00032     // bounds
00033     mfBoundRad = 0.0;
00034     mBounds.setExtents(Ogre::Vector3::ZERO,Ogre::Vector3::ZERO); 
00035     //~ mBounds.setExtents(-10.0*Ogre::Vector3::UNIT_SCALE,10.0*Ogre::Vector3::UNIT_SCALE);
00036 }
00037     
00038 cFastBatch::~cFastBatch () {
00039     // release subbatches
00040     for (tSubBatchMapIterator itor=mSubBatches.begin();itor!=mSubBatches.end();++itor) delete (*itor).second;
00041     mSubBatches.clear();
00042 }
00043 
00044 void    cFastBatch::AddMesh (cBufferedMesh& pBufferedMesh,  const Ogre::Vector3&        vPos,
00045                                                 const Ogre::Quaternion&     qRot,
00046                                                 const Ogre::Vector3&        vScale,
00047                                                 const Ogre::ColourValue&    vCol,
00048                                                 const bool                  bColourOverride,
00049                                                 const float                 fOrderValue) {
00050     
00051     if (DEBUG_FASTBATCH) printf("cFastBatch::AddMesh(%f,%f,%f)\n",vPos.x,vPos.y,vPos.z);
00052                                                             
00053     //Update bounding box
00054     if (1) {
00055         Ogre::Matrix4 mat(qRot);
00056         mat.setScale(vScale);
00057         Ogre::AxisAlignedBox entBounds = pBufferedMesh.GetBounds();
00058         entBounds.transform(mat);
00059         
00060         if (mSubBatches.size() == 0) { // bounds not initalized
00061             mBounds.setMinimum(entBounds.getMinimum() + vPos);
00062             mBounds.setMaximum(entBounds.getMaximum() + vPos);
00063         } else {
00064             Ogre::Vector3 vMin = mBounds.getMinimum();
00065             Ogre::Vector3 vMax = mBounds.getMaximum();
00066             vMin.makeFloor( entBounds.getMinimum() + vPos);
00067             vMax.makeCeil(  entBounds.getMaximum() + vPos);
00068             mBounds.setMinimum(vMin);
00069             mBounds.setMaximum(vMax);
00070         }
00071     }
00072         
00073     // add submesh to subbatches
00074     for (int i=0;i<pBufferedMesh.GetSubMeshCount();++i) {
00075         cBufferedSubMesh& pBufferedSubMesh = pBufferedMesh.GetSubMesh(i);
00076         if (pBufferedSubMesh.GetUsesShared()) { printf("warning, FastBatch doesn support shared vertex data\n"); continue; }
00077         
00078         // search the fitting subbatch depending on vertex format hash
00079         cSubBatch*& mySubBatch = mSubBatches[bColourOverride ? pBufferedSubMesh.GetFormatHashWithColour() : pBufferedSubMesh.GetFormatHash()];
00080         if (!mySubBatch) mySubBatch = new cSubBatch(this,pBufferedSubMesh,bColourOverride);
00081         
00082         mySubBatch->AddInstance(cInstance(&pBufferedSubMesh,vPos,qRot,vScale,vCol,bColourOverride),fOrderValue);
00083     }
00084 }
00085 
00086 void    cFastBatch::Build   () {
00087     
00088     // Finish bounds information
00089     //~ Ogre::Vector3 vCenter = mBounds.getCenter();        // Calculate bounds center
00090     Ogre::Vector3 vCenter = Ogre::Vector3::ZERO;
00091     //~ mBounds.setMinimum(mBounds.getMinimum() - vCenter); // Center the bounding box
00092     //~ mBounds.setMaximum(mBounds.getMaximum() - vCenter); // Center the bounding box
00093     mfBoundRad = mymax(mBounds.getMinimum().length(),mBounds.getMaximum().length());    // Calculate BB radius
00094     mvBoundsCenter = (mBounds.getMinimum() + mBounds.getMaximum()) * 0.5;
00095     
00096     
00097     if (DEBUG_FASTBATCH) {
00098         printf("cFastBatch::Build() mfBoundRad=%f\n",mfBoundRad);
00099         Ogre::Vector3 v = mBounds.getMinimum();
00100         Ogre::Vector3 w = mBounds.getMaximum();
00101         printf("cFastBatch::Build() min=%f,%f,%f max=%f,%f,%f\n",v.x,v.y,v.z, w.x,w.y,w.z);
00102     }
00103     
00104     // build subbatches
00105     for (tSubBatchMapIterator itor=mSubBatches.begin();itor!=mSubBatches.end();++itor) (*itor).second->Build();
00106 }
00107 
00108 void    cFastBatch::SetDisplayRange (const float fMin,const float fMax) {
00109     for (tSubBatchMapIterator itor=mSubBatches.begin();itor!=mSubBatches.end();++itor) (*itor).second->SetDisplayRange(fMin,fMax);
00110 }
00111 
00112 void    cFastBatch::_updateRenderQueue      (Ogre::RenderQueue *queue) {
00113     //~ if (DEBUG_FASTBATCH) printf("cFastBatch::_updateRenderQueue vis=%d\n",isVisible()?1:0);
00114     if (isVisible()) {
00115         for (tSubBatchMapIterator itor=mSubBatches.begin();itor!=mSubBatches.end();++itor) {
00116             queue->addRenderable( (*itor).second, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY); 
00117             //~ return; // TODO : debug : remove me,  prevents all after first to be added
00118         }
00119         //~ mRenderQueueID = getRenderQueueGroup() ?
00120     }
00121 }
00122 
00123 const Ogre::String&     cFastBatch::getMovableType  (void) const { static Ogre::String t = "LugreFastBatch"; return t; }
00124 
00125 // ***** ***** ***** ***** ***** cSubBatch
00126 
00127 
00128 cFastBatch::cSubBatch::cSubBatch    (cFastBatch* pParent,cBufferedSubMesh& pBufferedSubMesh, const bool bColourOverride) {
00129     // remember parent
00130     mpParent = pParent;
00131     
00132     // set material
00133     //~ setMaterialName("BaseWhiteNoLighting");
00134     setMaterial(pBufferedSubMesh.GetMat());
00135     if (DEBUG_FASTBATCH) printf("cFastBatch::cSubBatch::cSubBatch matptr.isnull()=%d\n",mpMat.isNull()?1:0);
00136     
00137     // init vertex
00138     mpVertexData = new Ogre::VertexData();
00139     mpVertexData->vertexStart = 0;
00140     mpVertexData->vertexCount = 0;
00141     
00142     // index data
00143     mpIndexData = new Ogre::IndexData();
00144     mpIndexData->indexStart = 0;
00145     mpIndexData->indexCount = 0;
00146     miTotalIndexCount = 0;
00147     
00148     // create new vertex declaration by collecting all elements from into a single buffer
00149     VertexDeclaration* decl = mpVertexData->vertexDeclaration; // IMPORTANT !!!
00150     
00151     // access vertex data 
00152     cBufferedVertexData&        pVertexData = pBufferedSubMesh.GetBufferedVertexData();
00153     Ogre::VertexDeclaration*    pVertexDecl = pVertexData.GetVertexDecl();
00154     const Ogre::VertexDeclaration::VertexElementList&   pVertexElemList = pVertexDecl->getElements();
00155     bool bHasColour = false;
00156     int iOffset = 0;
00157     
00158     // iterate over sample vertex decl
00159     if (DEBUG_FASTBATCH) printf("cFastBatch::cSubBatch::cSubBatch  vertex format:");
00160     for (Ogre::VertexDeclaration::VertexElementList::const_iterator ei=pVertexElemList.begin();ei!=pVertexElemList.end();++ei) {
00161         const Ogre::VertexElement &elem = *ei;
00162         assert((elem.getSize() % sizeof(float)) == 0 && "error, vertex decl element size must be multiple of 4(sizeof(float))");
00163         iOffset += decl->addElement(kCommonSourceIndex,iOffset,elem.getType(),elem.getSemantic(),elem.getIndex()).getSize();
00164         if (DEBUG_FASTBATCH) switch (elem.getSemantic()) {
00165             case Ogre::VES_POSITION             : printf("pos,"); break;
00166             case Ogre::VES_NORMAL               : printf("normal,"); break;
00167             case Ogre::VES_DIFFUSE              : printf("diffuse,"); break;
00168             case Ogre::VES_TANGENT              : printf("tangent,"); break;
00169             case Ogre::VES_BINORMAL             : printf("binormal,"); break;
00170             case Ogre::VES_TEXTURE_COORDINATES  : printf("texcoords,"); break;
00171             default                             : printf("UNKNOWN,"); break;
00172         }
00173         if (elem.getSemantic() == Ogre::VES_DIFFUSE) bHasColour = true;
00174     }
00175     if (DEBUG_FASTBATCH) printf("\n");
00176     
00177     // add colour element if needed
00178     mbAddColourAtEnd = !bHasColour && bColourOverride;
00179     if (mbAddColourAtEnd) {
00180         miPreferredColourFormat = Ogre::Root::getSingleton().getRenderSystem()->getColourVertexElementType(); // Ogre::VET_COLOUR;
00181         iOffset += decl->addElement(kCommonSourceIndex,iOffset,miPreferredColourFormat,Ogre::VES_DIFFUSE,0).getSize();
00182     }
00183     
00184     // done assembling vertexdecl, calc size
00185     miVertexSize = iOffset; // decl->getVertexSize(kCommonSourceIndex);
00186     if (DEBUG_FASTBATCH) printf("cFastBatch::cSubBatch::cSubBatch miVertexSize=%d bHasColour=%d mbAddColourAtEnd=%d\n",(int)miVertexSize,bHasColour?1:0,mbAddColourAtEnd?1:0);
00187     
00188     /* // vertex decl
00189     int miVertexSize = 0;
00190     VertexDeclaration *decl = mpVertexData->vertexDeclaration;
00191     miVertexSize += decl->addElement(0, miVertexSize, VET_FLOAT3, VES_POSITION).getSize();
00192     miVertexSize += decl->addElement(0, miVertexSize, VET_FLOAT3, VES_NORMAL).getSize();
00193     miVertexSize += decl->addElement(0, miVertexSize, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0 ).getSize();
00194     */
00195 }
00196 
00197 cFastBatch::cSubBatch::~cSubBatch   () {
00198     delete mpVertexData; mpVertexData = 0;
00199     delete mpIndexData; mpIndexData = 0;
00200 }
00201     
00202 void    cFastBatch::cSubBatch::AddInstance  (cInstance pInstance,const float fOrderValue) {
00203     // increment vertex and index count
00204     mpVertexData->vertexCount   += pInstance.mpBufferedSubMesh->GetVertexCount();
00205     mpIndexData->indexCount     += pInstance.mpBufferedSubMesh->GetIndexCount();
00206     miTotalIndexCount           += pInstance.mpBufferedSubMesh->GetIndexCount();
00207     
00208     // pre-swap colour here so it doesn't have to be swapped for every vertex later
00209     if (miPreferredColourFormat == VET_COLOUR_ARGB) { std::swap(pInstance.mvCol.r, pInstance.mvCol.b); }
00210     
00211     // add instance to queue
00212     mInstances.insert(std::pair<float,cInstance>(fOrderValue,pInstance));
00213 }
00214 
00215 void    cFastBatch::cSubBatch::SetDisplayRange  (const float fMin,const float fMax) {
00216     assert(mpVertexData && "should not happen");
00217     assert(mpIndexData && "should not happen");
00218     
00219     // no parts and offset entries so just do nothing
00220     if(mOrderValueOffsets.size() == 0)return;
00221     
00222     // get min max order values
00223     float minOrderValue = (*mOrderValueOffsets.begin()).first;
00224     float maxOrderValue = (*mOrderValueOffsets.rbegin()).first;
00225     
00226     if(fMax < minOrderValue || fMin > maxOrderValue || fMin > fMax){
00227         // non overlapping, display nothing 
00228         mpIndexData->indexStart = 0;
00229         mpIndexData->indexCount = 0;
00230     } else {
00231         // overlapping, display something
00232         std::map<float,int>::iterator itor_min = mOrderValueOffsets.lower_bound(fMin); // first elem >= fMin
00233         std::map<float,int>::iterator itor_max = mOrderValueOffsets.upper_bound(fMax); // first elem >  fMax  (first elem OUTSIDE the INCLUSIVE [min,max] range)
00234         int     iIndexIndexStart    = (itor_min != mOrderValueOffsets.end()) ? (*itor_min).second : 0;
00235         int     iIndexIndexEnd      = (itor_max != mOrderValueOffsets.end()) ? (*itor_max).second : miTotalIndexCount;
00236         
00237         mpIndexData->indexStart = iIndexIndexStart;
00238         mpIndexData->indexCount = iIndexIndexEnd - iIndexIndexStart;
00239     }
00240 }
00241 
00242 void    cFastBatch::cSubBatch::Build    () {
00243     Ogre::HardwareVertexBufferSharedPtr mHWVBuf;
00244     Ogre::HardwareIndexBufferSharedPtr  mHWIBuf;
00245     HardwareBuffer::Usage hbu = HardwareBuffer::HBU_STATIC_WRITE_ONLY;
00246     bool b32BitIndices = true; // always 32 bit, can't hurt, and 16 bit seems to cause alignment and compatibility problems
00247     //~ bool b32BitIndices = mpVertexData->vertexCount >= 0x00010000; // signed ? there were some problems with this...
00248     //~ bool b32BitIndices = mpVertexData->vertexCount >= 0x00008000; // signed ? there were some problems with this...s
00249     
00250     // allocate vertex buffer
00251     mHWVBuf = HardwareBufferManager::getSingleton().createVertexBuffer(miVertexSize,mpVertexData->vertexCount,hbu,false);
00252     mpVertexData->vertexBufferBinding->setBinding(kCommonSourceIndex,mHWVBuf);
00253     
00254     // allocate index buffer
00255     Ogre::HardwareIndexBuffer::IndexType iIdxType = b32BitIndices ? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT;
00256     mHWIBuf = HardwareBufferManager::getSingleton().createIndexBuffer(iIdxType,mpIndexData->indexCount,hbu,false);
00257     mpIndexData->indexBuffer = mHWIBuf;
00258     
00259     // get rendersystem pointer if neccessary, helpful for colour writing
00260     if (!mpRenderSys) mpRenderSys = Ogre::Root::getSingleton().getRenderSystem();
00261     
00262     // init some vars
00263     Ogre::uint32    iIndexOffset = 0;
00264     Vector3 tmp;
00265     Ogre::uint32 tmpColour;
00266     Ogre::uint8 tmpR, tmpG, tmpB, tmpA;
00267     mOrderValueOffsets.clear();
00268     
00269     // notes from PagedGeometry Addon, BatchedGeometry 
00270     /*
00271     Pass *p = material->getTechnique(0)->getPass(0);
00272     p->setVertexColourTracking(TVC_AMBIENT);
00273     ColourValue ambient = p->getAmbient();
00274     */
00275     
00276     // lock vertex buffer
00277     float*              pWriter = static_cast<float*>(mHWVBuf->lock(HardwareBuffer::HBL_DISCARD));
00278     --pWriter; // pre-decrement so we can use ++bla later, is faster than bla++
00279     // writing to vram (pWriter) should be done sequentially, according to Ogre::HardwareBuffer docs
00280     
00281     // lock index buffer
00282     Ogre::uint16*       pIndexWriter16 = 0;
00283     Ogre::uint32*       pIndexWriter32 = 0;
00284     if (b32BitIndices)
00285             pIndexWriter32 = static_cast<Ogre::uint32*>(mHWIBuf->lock(HardwareBuffer::HBL_DISCARD));
00286     else    pIndexWriter16 = static_cast<Ogre::uint16*>(mHWIBuf->lock(HardwareBuffer::HBL_DISCARD));
00287 
00288     // iterate over all registered instances and write to the buffers
00289     if (DEBUG_FASTBATCH) printf("cFastBatch::cSubBatch::Build : %d instances, vc=%d, ic=%d\n",(int)mInstances.size(),mpVertexData->vertexCount,mpIndexData->indexCount);
00290     
00291     int iNumberOfWrittenIndices = 0;
00292     
00293     float fLastOrderVal = 0;
00294     for (std::multimap<float,cInstance>::iterator itor=mInstances.begin();itor!=mInstances.end();++itor) { // multimap is SORTED by orderval
00295         cInstance&                  pInst = (*itor).second;
00296         float                       fOrderValue = (*itor).first;
00297         if (iNumberOfWrittenIndices == 0 || fOrderValue != fLastOrderVal) { // iNumberOfWrittenIndices=0 means first instance of list
00298             fLastOrderVal = fOrderValue;
00299             mOrderValueOffsets[fOrderValue] = iNumberOfWrittenIndices; // mark the offset at which this ordervalue begins
00300         }
00301         cBufferedSubMesh&           pSubMesh = *pInst.mpBufferedSubMesh;
00302         cBufferedVertexData&        pVertexData = pSubMesh.GetBufferedVertexData();
00303         Ogre::VertexDeclaration*    pVertexDecl = pVertexData.GetVertexDecl();
00304         const Ogre::VertexDeclaration::VertexElementList&   pVertexElemList = pVertexDecl->getElements();
00305         
00306         // only if the source vertexdata doesn't already have colour
00307         // tmpColour won't be needed during reading from the source, so calculate it here for faster writing
00308         if (mbAddColourAtEnd) {
00309             // g and b in mvCol is swapped if preferred format is VET_COLOUR_ARGB. see also WriteColour()
00310             tmpR = Ogre::uint8(float(0xFF) * pInst.mvCol.r); // * ambient.r;
00311             tmpG = Ogre::uint8(float(0xFF) * pInst.mvCol.g); // * ambient.g;
00312             tmpB = Ogre::uint8(float(0xFF) * pInst.mvCol.b); // * ambient.b;
00313             tmpA = Ogre::uint8(float(0xFF) * pInst.mvCol.a);
00314             tmpColour = (tmpR) | (tmpG << 8) | (tmpB << 16) | (tmpA << 24);
00315         }
00316         
00317         if (DEBUG_FASTBATCH) printf("inst rot=%f,%f,%f,%f pos=%f,%f,%f scale=%f,%f,%f mbAddColourAtEnd=%d\n",
00318                 pInst.mqRot.w,pInst.mqRot.x,pInst.mqRot.y,pInst.mqRot.z,
00319                 pInst.mvPos.x,pInst.mvPos.y,pInst.mvPos.z,
00320                 pInst.mvScale.x,pInst.mvScale.y,pInst.mvScale.z, mbAddColourAtEnd?1:0);
00321         
00322         // vars
00323         int                 iVertexCount = pVertexData.GetVertexCount();
00324         Ogre::Quaternion    qRot = pInst.mqRot;
00325         Ogre::Vector3       vScale = pInst.mvScale;
00326         Ogre::Vector3       vSign(vScale.x<0?-1:1,vScale.y<0?-1:1,vScale.z<0?-1:1);
00327         Ogre::Vector3       vPos = pInst.mvPos;
00328         
00329         // write vertex data
00330         if (DEBUG_FASTBATCH) printf("cFastBatch::cSubBatch::Build : GetVertexCount()=%d\n",iVertexCount);
00331         for (int iVertex=0;iVertex<iVertexCount;++iVertex) {
00332             // write all vertex elements, collected from different buffers if neccessary
00333             for (Ogre::VertexDeclaration::VertexElementList::const_iterator ei=pVertexElemList.begin();ei!=pVertexElemList.end();++ei) {
00334                 const Ogre::VertexElement &elem = *ei;
00335                 const float* pReader = reinterpret_cast<const float*>(pVertexData.GetVertexData(elem.getSource(),iVertex) + elem.getOffset());
00336                 
00337                 switch (elem.getSemantic()) {
00338                 case VES_POSITION:
00339                         tmp.x = pReader[0];
00340                         tmp.y = pReader[1];
00341                         tmp.z = pReader[2];
00342                         
00343                         //Transform
00344                         tmp = (qRot * (tmp * vScale)) + vPos;
00345                     
00346                         *++pWriter = tmp.x;
00347                         *++pWriter = tmp.y;
00348                         *++pWriter = tmp.z;
00349                     break;
00350 
00351                 case VES_NORMAL:
00352                         tmp.x = pReader[0];
00353                         tmp.y = pReader[1];
00354                         tmp.z = pReader[2];
00355 
00356                         //Rotate
00357                         tmp = qRot * (tmp * vSign);
00358 
00359                         *++pWriter = tmp.x;
00360                         *++pWriter = tmp.y;
00361                         *++pWriter = tmp.z;
00362                     break;
00363 
00364                 case VES_DIFFUSE:
00365                         tmpColour = *((Ogre::uint32*)pReader);
00366                         tmpR = Ogre::uint8(float((tmpColour      ) & 0xFF) * pInst.mvCol.r); // * ambient.r;
00367                         tmpG = Ogre::uint8(float((tmpColour >>  8) & 0xFF) * pInst.mvCol.g); // * ambient.g;
00368                         tmpB = Ogre::uint8(float((tmpColour >> 16) & 0xFF) * pInst.mvCol.b); // * ambient.b;
00369                         tmpA = Ogre::uint8(float((tmpColour >> 24) & 0xFF) * pInst.mvCol.a);
00370                         // g and b in mvCol is swapped if preferred format is VET_COLOUR_ARGB
00371                         // bug if vertexformat of source is different from preferred format, see see also WriteColour()
00372 
00373                         tmpColour = tmpR | (tmpG << 8) | (tmpB << 16) | (tmpA << 24);
00374                         *((Ogre::uint32*)++pWriter) = tmpColour;
00375                     break;
00376 
00377                 case VES_TANGENT:
00378                 case VES_BINORMAL:
00379                         tmp.x = pReader[0];
00380                         tmp.y = pReader[1];
00381                         tmp.z = pReader[2];
00382 
00383                         //Rotate
00384                         tmp = qRot * (tmp * vSign);
00385 
00386                         *++pWriter = tmp.x;
00387                         *++pWriter = tmp.y;
00388                         *++pWriter = tmp.z;
00389                     break;
00390 
00391                 default: {
00392                         // avoid memcpy to make sure data is written sequentially
00393                         int iElementSizeInFloats = elem.getSize() / sizeof(float);
00394                         for (int k=0;k<iElementSizeInFloats;++k) *++pWriter = pReader[k];
00395                     }
00396                     break;
00397                 };
00398             }
00399             
00400             // add colour at the end, only if the source vertexdata doesn't already have colour
00401             if (mbAddColourAtEnd) {
00402                 *((Ogre::uint32*)++pWriter) = tmpColour;
00403             }
00404         }
00405         
00406         // write index data
00407         if (DEBUG_FASTBATCH) printf("cFastBatch::cSubBatch::Build : GetIndexCount()=%d\n",(int)pSubMesh.GetIndexCount());
00408         int iSubMeshIndexCount = pSubMesh.GetIndexCount();
00409         iNumberOfWrittenIndices += iSubMeshIndexCount;
00410         Ogre::uint32* pIndexReader = pSubMesh.GetIndexData();
00411         Ogre::uint32* pIndexReaderEnd = pIndexReader + iSubMeshIndexCount;
00412         if (b32BitIndices) {
00413             for (;pIndexReader!=pIndexReaderEnd;++pIndexReader,++pIndexWriter32) *pIndexWriter32 = (iIndexOffset + *pIndexReader);
00414         } else {
00415             for (;pIndexReader!=pIndexReaderEnd;++pIndexReader,++pIndexWriter16) *pIndexWriter16 = (iIndexOffset + *pIndexReader);
00416         }
00417         
00418         // increase index offset for next instance
00419         iIndexOffset += iVertexCount;
00420     }
00421     mInstances.clear();
00422     
00423     // writing finished, unlock buffers
00424     mHWVBuf->unlock();
00425     mHWIBuf->unlock();
00426     
00427     if (DEBUG_FASTBATCH) printf("cFastBatch::cSubBatch::Build : count v,i=%d,%d\n",(int)mpVertexData->vertexCount,(int)mpIndexData->indexCount);
00428 }
00429 
00430 
00431 // ***** ***** ***** ***** ***** cSubBatch Ogre::Renderable implementation
00432 
00433 Ogre::Real                  cFastBatch::cSubBatch::getSquaredViewDepth      (const Ogre::Camera* cam) const {
00434     //~ return (cam->getDerivedPosition() - (mpParent->mBounds.getMinimum() + mpParent->mBounds.getMaximum()) * 0.5).squaredLength();
00435     return (cam->getDerivedPosition() - mpParent->GetBoundsCenter()).squaredLength();
00436 }
00437 
00438 void                    cFastBatch::cSubBatch::setMaterialName          (const Ogre::String &mat) { 
00439     mpMat = Ogre::MaterialManager::getSingleton().getByName(mat); 
00440     if (mpMat.isNull())
00441         OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + mat,
00442             "cFastBatch::cSubBatch::setMaterialName" );
00443     mpMat->load();
00444 }
00445 
00446 Ogre::String            cFastBatch::cSubBatch::getMaterialName          () const { return mpMat->getName(); }
00447 
00448 void    cFastBatch::cSubBatch::getRenderOperation   (Ogre::RenderOperation& op) {
00449     //~ if (DEBUG_FASTBATCH) printf("cFastBatch::cSubBatch::getRenderOperation\n");
00450     op.operationType    = Ogre::RenderOperation::OT_TRIANGLE_LIST; // OT_TRIANGLE_LIST , OT_LINE_STRIP 
00451     op.srcRenderable    = this;
00452     op.useIndexes       = true;
00453     op.vertexData       = mpVertexData;
00454     op.indexData        = mpIndexData;
00455 }
00456 
00457 void                        cFastBatch::cSubBatch::getWorldTransforms       (Ogre::Matrix4* xform) const {
00458     *xform = mpParent->_getParentNodeFullTransform();
00459 }
00460 const Ogre::Quaternion&     cFastBatch::cSubBatch::getWorldOrientation      (void) const {
00461     return mpParent->getParentNode()->_getDerivedOrientation();
00462 }
00463 const Ogre::Vector3&        cFastBatch::cSubBatch::getWorldPosition         (void) const {
00464     return mpParent->getParentNode()->_getDerivedPosition();
00465 }
00466 
00467 // ***** ***** ***** ***** ***** global interface
00468 
00469 Ogre::RenderSystem* cFastBatch::cSubBatch::mpRenderSys = 0;
00470     
00471 };

Generated on Wed Feb 8 06:00:13 2012 for cpp by  doxygen 1.5.6