#include "OgreStableHeaders.h" #include "OgreSolidHalfBoundingBox.h" #include "OgreSimpleRenderable.h" #include "OgreHardwareBufferManager.h" #include "OgreCamera.h" #include "OgreMaterialManager.h" namespace Ogre { #define POSITION_BINDING 0 //----------------------------------------------------------------------- SolidHalfBoundingBox::SolidHalfBoundingBox() { SetOcclusionQueryMaterial(); mRenderOp.vertexData->vertexCount = 8; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_FAN; } //----------------------------------------------------------------------- void SolidHalfBoundingBox::SetupBoundingBoxVertices(const AxisAlignedBox& aab, const bool isFirstHalf) { const Vector3& min = aab.getMinimum(); const Vector3& max = aab.getMaximum(); // fill the vertex buffer: 12 lines with 2 endpoints each make up a box HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); float* pPos = static_cast(vbuf->lock(HardwareBuffer::HBL_DISCARD)); // 5+------+7 // /| /| // / | / | // / 1+---/--+3 // 2+------+6 / y z // | / | / | / // |/ |/ |/ // 0+------+4 *---x if (isFirstHalf) // fan 1 { *pPos++ = min.x; *pPos++ = max.y; *pPos++ = max.z; //011 *pPos++ = min.x; *pPos++ = min.y; *pPos++ = max.z; //001 *pPos++ = max.x; *pPos++ = min.y; *pPos++ = max.z; //101 *pPos++ = max.x; *pPos++ = max.y; *pPos++ = max.z; //111 *pPos++ = max.x; *pPos++ = max.y; *pPos++ = min.z; //110 *pPos++ = min.x; *pPos++ = max.y; *pPos++ = min.z; //010 *pPos++ = min.x; *pPos++ = min.y; *pPos++ = min.z; //000 *pPos++ = min.x; *pPos++ = min.y; *pPos++ = max.z; //001 } else // fan 2 { *pPos++ = max.x; *pPos++ = min.y; *pPos++ = min.z; //100 *pPos++ = min.x; *pPos++ = min.y; *pPos++ = min.z; //000 *pPos++ = min.x; *pPos++ = max.y; *pPos++ = min.z; //010 *pPos++ = max.x; *pPos++ = max.y; *pPos++ = min.z; //110 *pPos++ = max.x; *pPos++ = max.y; *pPos++ = max.z; //111 *pPos++ = max.x; *pPos++ = min.y; *pPos++ = max.z; //101 *pPos++ = min.x; *pPos++ = min.y; *pPos++ = max.z; //001 *pPos++ = min.x; *pPos++ = min.y; *pPos++ = min.z; //000 } vbuf->unlock(); } //----------------------------------------------------------------------- void SolidHalfBoundingBox::SetupBoundingBox(const AxisAlignedBox& aab, const bool isFirstHalf) { // init the vertices to the aabb SetupBoundingBoxVertices(aab, isFirstHalf); Real sqLen = std::max(aab.getMaximum().squaredLength(), aab.getMinimum().squaredLength()); mRadius = Math::Sqrt(sqLen); // setup the bounding box of this SimpleRenderable setBoundingBox(aab); } //----------------------------------------------------------------------- void SolidHalfBoundingBox::SetOcclusionQueryMaterial( void ) { m_pMaterial = MaterialManager::getSingleton().getByName("Visibility/QueryMaterial"); if (m_pMaterial.isNull()) { m_pMaterial = MaterialManager::getSingleton(). create("Visibility/QueryMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); } m_pMaterial->setColourWriteEnabled(false); m_pMaterial->setDepthWriteEnabled(false); m_pMaterial->setLightingEnabled(false); setMaterial("Visibility/QueryMaterial"); } } // namespace Ogre