#include "OgreStableHeaders.h" #include "OgreSolidBoundingBox.h" #include #include #include #include #include #include #include #include namespace Ogre { #define POSITION_BINDING 0 //----------------------------------------------------------------------- SolidBoundingBox::SolidBoundingBox() { mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = new IndexData(); mRenderOp.indexData->indexStart = 0; mRenderOp.vertexData->vertexStart = 0; mRenderOp.vertexData->vertexCount = 8; mRenderOp.indexData->indexCount = 36; mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; mRenderOp.useIndexes = true; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding; decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); //decl->addElement(INDEX_BINDING, 0, VET_, VES_POSITION); // create the vertex buffer HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); //-- index buffer unsigned short faces[36] = { 0,2,3, 0,1,2, 1,6,2, 1,5,6, 4,6,5, 4,7,6, 0,7,4, 0,3,7, 0,5,1, 0,4,5, 2,7,3, 2,6,7 }; /// Allocate index buffer of the requested number of vertices HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). createIndexBuffer( HardwareIndexBuffer::IT_16BIT, mRenderOp.indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); /// Upload the index data to the card ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); //mRenderOp.useSharedVertices = true; mRenderOp.indexData->indexBuffer = ibuf; // set material with no lighting, no color, no depth write SetOcclusionQueryMaterial(); //setMaterial("BaseWhiteNoLighting"); } //----------------------------------------------------------------------- SolidBoundingBox::~SolidBoundingBox() { delete mRenderOp.vertexData; delete mRenderOp.indexData; } //----------------------------------------------------------------------- void SolidBoundingBox::SetupBoundingBoxVertices(const AxisAlignedBox& aab) { 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)); *pPos++ = min.x; *pPos++ = max.y; *pPos++ = min.z; *pPos++ = max.x; *pPos++ = max.y; *pPos++ = min.z; *pPos++ = max.x; *pPos++ = min.y; *pPos++ = min.z; *pPos++ = min.x; *pPos++ = min.y; *pPos++ = min.z; *pPos++ = min.x; *pPos++ = max.y; *pPos++ = max.z; *pPos++ = max.x; *pPos++ = max.y; *pPos++ = max.z; *pPos++ = max.x; *pPos++ = min.y; *pPos++ = max.z; *pPos++ = min.x; *pPos++ = min.y; *pPos++ = max.z; vbuf->unlock(); } //----------------------------------------------------------------------- void SolidBoundingBox::SetupBoundingBox(const AxisAlignedBox& aab) { // init the vertices to the aabb SetupBoundingBoxVertices(aab); Real sqLen = std::max(aab.getMaximum().squaredLength(), aab.getMinimum().squaredLength()); mRadius = Math::Sqrt(sqLen); // setup the bounding box of this SimpleRenderable setBoundingBox(aab); } //----------------------------------------------------------------------- void SolidBoundingBox::SetOcclusionQueryMaterial() { m_pMaterial = MaterialManager::getSingleton().getByName("Visibility/QueryMaterial"); if (m_pMaterial.isNull()) { m_pMaterial = MaterialManager::getSingleton(). create("Visibility/QueryMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Pass *queryPass = m_pMaterial->getTechnique(0)->getPass(0); queryPass->setColourWriteEnabled(false); queryPass->setDepthWriteEnabled(false); queryPass->setLightingEnabled(false); } setMaterial("Visibility/QueryMaterial"); } // Override this method to prevent parent transforms (rotation,translation,scale) void SolidBoundingBox::getWorldTransforms(Matrix4* xform) const { // return identity matrix to prevent parent transforms *xform = Matrix4::IDENTITY; } //----------------------------------------------------------------------- const Quaternion& SolidBoundingBox::getWorldOrientation() const { return Quaternion::IDENTITY; } //----------------------------------------------------------------------- const Vector3& SolidBoundingBox::getWorldPosition() const { return Vector3::ZERO; } Real SolidBoundingBox::getSquaredViewDepth(const Camera* cam) const { const Vector3 &min = mBox.getMinimum(); const Vector3 &max = mBox.getMaximum(); const Vector3 &mid = ((min - max) * 0.5) + min; const Vector3 &dist = cam->getDerivedPosition() - mid; return dist.squaredLength(); } } // namespace Ogre