00001 #include "lugre_prefix.h"
00002 #include "lugre_robrenderable.h"
00003 #include <OgreCamera.h>
00004 #include <Ogre.h>
00005
00006
00007 using namespace Ogre;
00008
00009 namespace Lugre {
00010
00011
00012 cRobSimpleRenderable::cRobSimpleRenderable() : cRobRenderOp(&mRenderOp,&mBox) { PROFILE
00013 setMaterial("BaseWhiteNoLighting");
00014 }
00015
00016 cRobSimpleRenderable::~cRobSimpleRenderable() { PROFILE
00017 delete mRenderOp.vertexData; mRenderOp.vertexData = 0;
00018 delete mRenderOp.indexData; mRenderOp.indexData = 0;
00019 }
00020
00021 Ogre::Real cRobSimpleRenderable::getBoundingRadius(void) const { PROFILE
00022 return mfBoundingRadius;
00023
00024 }
00025
00026 Ogre::Real cRobSimpleRenderable::getSquaredViewDepth(const Camera* cam) const { PROFILE
00027 return (cam->getDerivedPosition() - (mBox.getMinimum() + mBox.getMaximum()) * 0.5).squaredLength();
00028 }
00029
00030 void cRobSimpleRenderable::ConvertToMesh (const std::string& sMeshName) {
00031 cRobRenderOp::ConvertToMesh(sMeshName,getMaterial()->getName());
00032 }
00033
00034 void cRobSimpleRenderable::AddToMesh (const std::string& sMeshName) {
00035 Ogre::MeshPtr pMesh = Ogre::MeshManager::getSingleton().load(sMeshName,
00036 Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );
00037 AddToMesh(pMesh);
00038 }
00039
00040 void cRobSimpleRenderable::AddToMesh (Ogre::MeshPtr pMesh) {
00041 cRobRenderOp::AddToMesh(pMesh,getMaterial()->getName());
00042 }
00043
00044 #if 0
00045 Real cRobSimpleRenderable::getSquaredViewDepth(const Camera* cam) const { PROFILE
00046 return 0;
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 }
00063
00064 Real cRobSimpleRenderable::getBoundingRadius(void) const { PROFILE
00065
00066 return 0;
00067
00068 }
00069 #endif
00070
00071
00072
00073 cRobRenderOp::cRobRenderOp(Ogre::RenderOperation* pRenderOp,Ogre::AxisAlignedBox* pBox)
00074 : mpRenderOp(pRenderOp), mpBox(pBox), mpRenderSys(0),
00075 miVertexCapacity(0), miIndexCapacity(0), miVertexFormat(kVertexFormat_none), mVertexWritePtr(0), mIndexWritePtr(0) {
00076 mfBoundingRadius = 1;
00077 if (mpBox) mpBox->setExtents(Ogre::Vector3::ZERO,Ogre::Vector3::ZERO);
00078 }
00079 cRobRenderOp::~cRobRenderOp() { PROFILE
00080
00081
00082
00083
00084
00085 }
00086
00087 void cRobRenderOp::Begin (const size_t iVertexCount,const size_t iIndexCount,const bool bDynamic,const bool bKeepOldIndices,
00088 const Ogre::RenderOperation::OperationType opType,const bool bReadable) { PROFILE
00089 assert(mpRenderOp && "mpRenderOp not set");
00090 if (!mpRenderOp) return;
00091 mvAABMin = Vector3::ZERO;
00092 mvAABMax = Vector3::ZERO;
00093 mbBoundingBoxEmpty = true;
00094 miVertexCount = iVertexCount;
00095 miIndexCount = iIndexCount;
00096 miReceivedVertices = 0;
00097 miReceivedIndices = 0;
00098 mVertexWritePtr = 0;
00099 mIndexWritePtr = 0;
00100 mbDynamic = bDynamic;
00101 mbReadable = bReadable;
00102 mbKeepOldIndices = bKeepOldIndices;
00103 if (!mpRenderSys) mpRenderSys = Root::getSingleton().getRenderSystem();
00104
00105 mpRenderOp->operationType = opType;
00106 mpRenderOp->useIndexes = iIndexCount > 0;
00107 if (!mpRenderOp->vertexData) mpRenderOp->vertexData = new VertexData();
00108 if (!mpRenderOp->indexData && mpRenderOp->useIndexes) mpRenderOp->indexData = new IndexData();
00109 mpRenderOp->vertexData->vertexCount = miVertexCount;
00110 if (mpRenderOp->indexData && mpRenderOp->useIndexes) {
00111 mpRenderOp->indexData->indexCount = miIndexCount;
00112 mpRenderOp->indexData->indexStart = 0;
00113 }
00114 }
00115
00116 void cRobRenderOp::_StartWrite (const bool bVertexFormatChanged) { PROFILE
00117 VertexDeclaration *decl = GetVertexDecl();
00118 miVertexSize = decl->getVertexSize(0);
00119
00120
00121 bool bNeedNewVertexBuffer = bVertexFormatChanged || mbDynamic != mbBufferIsDynamic || mbReadable != mbBufferIsReadable || miVertexCount > miVertexCapacity;
00122 if (bNeedNewVertexBuffer) {
00123 if (miVertexCount > miVertexCapacity) miVertexCapacity = miVertexCount;
00124
00125
00126
00127
00128 HardwareBuffer::Usage hbu_V = mbReadable ?
00129 (mbDynamic ? HardwareBuffer::HBU_DYNAMIC : HardwareBuffer::HBU_STATIC) :
00130 (mbDynamic ? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE : HardwareBuffer::HBU_STATIC_WRITE_ONLY);
00131
00132
00133 mHWVBuf = HardwareBufferManager::getSingleton().createVertexBuffer(miVertexSize,miVertexCapacity,hbu_V);
00134 mpRenderOp->vertexData->vertexBufferBinding->setBinding(0, mHWVBuf);
00135 }
00136
00137 mbBufferIsDynamic = mbDynamic;
00138 mbBufferIsReadable = mbReadable;
00139
00140 mVertexWritePtr = static_cast<char*>(mHWVBuf->lock(HardwareBuffer::HBL_DISCARD));
00141 }
00142
00143 void cRobRenderOp::SetVertexFormatFromEnum (const eVertexFormat iVertexFormat,const int iNumTexCoordsSets) {
00144 VertexDeclaration *decl = GetVertexDecl();
00145
00146
00147 while (decl->getVertexSize(0) > 0) decl->removeElement(0);
00148
00149
00150 miVertexSize = 0;
00151 miVertexSize += decl->addElement(0, miVertexSize, VET_FLOAT3, VES_POSITION).getSize();
00152
00153
00154 switch (iVertexFormat) {
00155 case kVertexFormat_pn:
00156 case kVertexFormat_pnuv:
00157 case kVertexFormat_pnc:
00158 case kVertexFormat_pnuvc:
00159 miVertexSize += decl->addElement(0, miVertexSize, VET_FLOAT3, VES_NORMAL).getSize();
00160 break;
00161 }
00162
00163
00164 for (int i=0;i<iNumTexCoordsSets;++i) {
00165 switch (iVertexFormat) {
00166 case kVertexFormat_puv:
00167 case kVertexFormat_pnuv:
00168 case kVertexFormat_puvc:
00169 case kVertexFormat_pnuvc:
00170 miVertexSize += decl->addElement(0, miVertexSize, VET_FLOAT2, VES_TEXTURE_COORDINATES, i ).getSize();
00171 break;
00172 }
00173 }
00174
00175
00176 switch (iVertexFormat) {
00177 case kVertexFormat_pc:
00178 case kVertexFormat_puvc:
00179 case kVertexFormat_pnc:
00180 case kVertexFormat_pnuvc:
00181 miVertexSize += decl->addElement(0, miVertexSize, VET_COLOUR, VES_DIFFUSE).getSize();
00182 break;
00183 }
00184 }
00185
00186
00187 Ogre::VertexDeclaration* cRobRenderOp::GetVertexDecl () { return mpRenderOp->vertexData->vertexDeclaration; }
00188
00189 Ogre::Real* cRobRenderOp::StartCustomWriter (const Ogre::Vector3& vBoundsMin,const Ogre::Vector3& vBoundsMax) {
00190 assert(mpRenderOp && "mpRenderOp not set");
00191 if (!mpRenderOp) return 0;
00192 _StartWrite(true);
00193 assert(miReceivedVertices == 0);
00194 miReceivedVertices = miVertexCount;
00195 assert(mVertexWritePtr);
00196 mbBoundingBoxEmpty = false;
00197 mvAABMin = vBoundsMin;
00198 mvAABMax = vBoundsMax;
00199 return reinterpret_cast<Real*>(mVertexWritePtr);
00200 }
00201
00202 Ogre::Real* cRobRenderOp::PrepareAddVertex (const eVertexFormat iVertexFormat,const Ogre::Vector3& p) { PROFILE
00203 assert(mpRenderOp && "mpRenderOp not set");
00204 if (!mpRenderOp) return 0;
00205 if (miReceivedVertices >= miVertexCount) { PROFILE_PRINT_STACKTRACE }
00206 assert(miReceivedVertices < miVertexCount && "Buffer Overflow");
00207 ++miReceivedVertices;
00208 if (miReceivedVertices <= 1) {
00209
00210 bool bVertexFormatChanged = miVertexFormat != iVertexFormat;
00211 if (bVertexFormatChanged) {
00212 miVertexFormat = iVertexFormat;
00213 SetVertexFormatFromEnum(iVertexFormat);
00214 }
00215 _StartWrite(bVertexFormatChanged);
00216 } else {
00217 assert(miVertexFormat == iVertexFormat && "cannot change VertexFormat");
00218 }
00219 assert(mVertexWritePtr);
00220
00221 static Real* w;
00222 w = reinterpret_cast<Real*>(mVertexWritePtr);
00223 mVertexWritePtr += miVertexSize;
00224
00225 if (mbBoundingBoxEmpty) {
00226 mvAABMin = p;
00227 mvAABMax = p;
00228 mbBoundingBoxEmpty = false;
00229 }
00230 if (mvAABMin.x > p.x) mvAABMin.x = p.x;
00231 if (mvAABMin.y > p.y) mvAABMin.y = p.y;
00232 if (mvAABMin.z > p.z) mvAABMin.z = p.z;
00233 if (mvAABMax.x < p.x) mvAABMax.x = p.x;
00234 if (mvAABMax.y < p.y) mvAABMax.y = p.y;
00235 if (mvAABMax.z < p.z) mvAABMax.z = p.z;
00236 *w++ = p.x;
00237 *w++ = p.y;
00238 *w++ = p.z;
00239
00240 return w;
00241 }
00242
00243 void cRobRenderOp::Vertex (const Ogre::Vector3& p) {
00244 PrepareAddVertex(kVertexFormat_p,p);
00245 }
00246
00247 void cRobRenderOp::Vertex (const Ogre::Vector3& p,const Ogre::Real u,const Ogre::Real v) {
00248 Real* w = PrepareAddVertex(kVertexFormat_puv,p);
00249 *w++ = u;
00250 *w++ = v;
00251 }
00252
00253 void cRobRenderOp::Vertex (const Ogre::Vector3& p,const Ogre::Vector3& n) {
00254 Real* w = PrepareAddVertex(kVertexFormat_pn,p);
00255 *w++ = n.x;
00256 *w++ = n.y;
00257 *w++ = n.z;
00258 }
00259
00260 void cRobRenderOp::Vertex (const Ogre::Vector3& p,const Ogre::Vector3& n,const Ogre::Real u,const Ogre::Real v) {
00261 Real* w = PrepareAddVertex(kVertexFormat_pnuv,p);
00262 *w++ = n.x;
00263 *w++ = n.y;
00264 *w++ = n.z;
00265 *w++ = u;
00266 *w++ = v;
00267 }
00268
00270 inline void RobWriteCol (Real* w,const Ogre::ColourValue& c,RenderSystem* pRenderSys) { PROFILE
00271 if (pRenderSys)
00272 pRenderSys->convertColourValue(c, reinterpret_cast<RGBA*>(w));
00273 else *reinterpret_cast<RGBA*>(w) = c.getAsRGBA();
00274 }
00275
00276 void cRobRenderOp::Vertex (const Ogre::Vector3& p,const Ogre::ColourValue& c) {
00277 Real* w = PrepareAddVertex(kVertexFormat_pc,p);
00278 RobWriteCol(w,c,mpRenderSys);
00279 }
00280
00281 void cRobRenderOp::Vertex (const Ogre::Vector3& p,const Ogre::Real u,const Ogre::Real v,const Ogre::ColourValue& c) {
00282 Real* w = PrepareAddVertex(kVertexFormat_puvc,p);
00283 *w++ = u;
00284 *w++ = v;
00285 RobWriteCol(w,c,mpRenderSys);
00286 }
00287
00288 void cRobRenderOp::Vertex (const Ogre::Vector3& p,const Ogre::Vector3& n,const Ogre::ColourValue& c) {
00289 Real* w = PrepareAddVertex(kVertexFormat_pnc,p);
00290 *w++ = n.x;
00291 *w++ = n.y;
00292 *w++ = n.z;
00293 RobWriteCol(w,c,mpRenderSys);
00294 }
00295
00296 void cRobRenderOp::Vertex (const Ogre::Vector3& p,const Ogre::Vector3& n,const Ogre::Real u,const Ogre::Real v,const Ogre::ColourValue& c) {
00297 Real* w = PrepareAddVertex(kVertexFormat_pnuvc,p);
00298 *w++ = n.x;
00299 *w++ = n.y;
00300 *w++ = n.z;
00301 *w++ = u;
00302 *w++ = v;
00303 RobWriteCol(w,c,mpRenderSys);
00304 }
00305
00306 void cRobRenderOp::Index (const int i,const int j,const int k) { Index(i); Index(j); Index(k); }
00307
00308 void cRobRenderOp::Index (const int i) { PROFILE
00309
00310 assert(i >= 0 && "cRobRenderOp::End : warning ! negative index");
00311 assert(i < miVertexCount && "cRobRenderOp::End : index out of bounds");
00312
00313 assert(mpRenderOp && "mpRenderOp not set");
00314 if (!mpRenderOp) return;
00315 assert(miReceivedIndices < miIndexCount && "Buffer Overflow");
00316 ++miReceivedIndices;
00317 if (miReceivedIndices <= 1) {
00318 _AllocateIndexBufferIfNeeded();
00319 mIndexWritePtr = static_cast<unsigned short*>(mHWIBuf->lock(HardwareBuffer::HBL_DISCARD));
00320 }
00321 assert(mIndexWritePtr);
00322 *mIndexWritePtr = (unsigned short)i;
00323 ++mIndexWritePtr;
00324 }
00325
00326 void cRobRenderOp::_AllocateIndexBufferIfNeeded () {
00327 if (!mpRenderOp->useIndexes) return;
00328 if (miIndexCapacity > 0 && miIndexCapacity > miIndexCount) return;
00329
00330
00331
00332
00333
00334 HardwareBuffer::Usage hbu_i = HardwareBuffer::HBU_STATIC_WRITE_ONLY;
00335
00336
00337 miIndexCapacity = (miIndexCount > 0) ? miIndexCount : 3;
00338 mHWIBuf = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT,miIndexCapacity,hbu_i);
00339 mpRenderOp->indexData->indexBuffer = mHWIBuf;
00340 }
00341
00342 void cRobRenderOp::End () { PROFILE
00343
00344 mfBoundingRadius = Math::Sqrt(std::max(mvAABMax.squaredLength(), mvAABMin.squaredLength()));
00345 if (mpBox) mpBox->setExtents(mvAABMin,mvAABMax);
00346
00347 assert(miReceivedVertices == miVertexCount && "cRobRenderOp::End : not enough vertices");
00348 assert((mbKeepOldIndices || miReceivedIndices == miIndexCount) && "cRobRenderOp::End : not enough indices");
00349 if (!mbKeepOldIndices && mpRenderOp->useIndexes && miReceivedIndices == 0) {
00350
00351
00352 _AllocateIndexBufferIfNeeded();
00353 }
00354 if (mVertexWritePtr) { mHWVBuf->unlock(); mVertexWritePtr = 0; }
00355 if (mIndexWritePtr) { mHWIBuf->unlock(); mIndexWritePtr = 0; }
00356 }
00357
00359 void cRobRenderOp::SkipVertices (const size_t iNum) {
00360 miVertexCount -= iNum;
00361 mpRenderOp->vertexData->vertexCount = miVertexCount;
00362 }
00363
00364 void cRobRenderOp::SkipIndices (const size_t iNum) {
00365 miIndexCount -= iNum;
00366 mpRenderOp->indexData->indexCount = miIndexCount;
00367 }
00368
00369
00370 void cRobRenderOp::ConvertToMesh (const std::string& sMeshName,const std::string& sMatName){
00371 Ogre::MeshPtr pMesh = Ogre::MeshManager::getSingleton().createManual(sMeshName,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
00372 AddToMesh(pMesh,sMatName);
00373 }
00374
00375
00376
00377 void cRobRenderOp::AddToMesh (Ogre::MeshPtr pMesh, const std::string& sMatName) {
00378
00379
00380
00381
00382
00383
00384
00385
00386 Ogre::SubMesh* sub = pMesh->createSubMesh();
00387 sub->setMaterialName(sMatName);
00388 sub->useSharedVertices = false;
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 sub->vertexData = mpRenderOp->vertexData->clone();
00400 sub->indexData = mpRenderOp->indexData->clone();
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 if(pMesh->getNumSubMeshes() == 0){
00436
00437 pMesh->_setBounds(AxisAlignedBox(mvAABMin.x,mvAABMin.y,mvAABMin.z,mvAABMax.x,mvAABMax.y,mvAABMax.z), true);
00438 pMesh->_setBoundingSphereRadius(mfBoundingRadius);
00439 } else {
00440
00441 AxisAlignedBox aabb = AxisAlignedBox(mvAABMin.x,mvAABMin.y,mvAABMin.z,mvAABMax.x,mvAABMax.y,mvAABMax.z);
00442 aabb.merge(pMesh->getBounds());
00443 pMesh->_setBounds(aabb, true);
00444
00445 pMesh->_setBoundingSphereRadius(mymax(pMesh->getBoundingSphereRadius(),mfBoundingRadius));
00446 }
00447 pMesh->load();
00448 }
00449
00450 Ogre::Real cRobRenderOp::GetMaxZ () { PROFILE
00451 return Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue();
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 };