//[-------------------------------------------------------] //[ Public virtual SceneNode functions ] //[-------------------------------------------------------] void SNCamera::DrawDebug(Renderer &cRenderer, const VisNode *pVisNode) { // Call base implementation SceneNode::DrawDebug(cRenderer, pVisNode); // Draw anything? if (pVisNode && (!(GetDebugFlags() & DebugNoFrustum) || (GetDebugFlags() & DebugFrustumVertices))) { // Setup render states cRenderer.GetRendererContext().GetEffectManager().Use(); cRenderer.SetRenderState(RenderState::ZEnable, false); cRenderer.SetRenderState(RenderState::ZWriteEnable, false); static const Color4 cColor(0.8f, 1.0f, 0.8f, 1.0f); // Draw the camera frustum? if (!(GetDebugFlags() & DebugNoFrustum)) { // Get world transform matrix with no scale Matrix4x4 mWorld; mWorld.FromQuatTrans(CalculateViewRotation(), GetTransform().GetPosition()); mWorld *= GetProjectionMatrix(cRenderer.GetViewport()).GetInverted(); // Draw const Matrix4x4 mWorldViewProjection = pVisNode->GetViewProjectionMatrix()*mWorld; cRenderer.GetDrawHelpers().DrawBox(cColor, Vector3::NegativeOne, Vector3::One, mWorldViewProjection, 1.0f); } // Draw the frustum vertices? (there are ALWAYS 8 of them!) if ((GetDebugFlags() & DebugFrustumVertices) && pVisNode->GetParent()) { // Draw them - this points are within the 'container space' const Array<Vector3> &lstV = GetFrustumVertices(cRenderer.GetViewport()); for (uint8 i=0; i<lstV.GetNumOfElements(); i++) cRenderer.GetDrawHelpers().DrawPoint(cColor, lstV[i], pVisNode->GetParent()->GetWorldViewProjectionMatrix(), 5.0f); } } }
/** * @brief * Returns the 8 camera frustum vertices */ const Array<Vector3> &SNCamera::GetFrustumVertices(const Rectangle &cViewport) { // Get the viewport width and height const uint32 nViewportWidth = static_cast<uint32>(cViewport.GetWidth()); const uint32 nViewportHeight = static_cast<uint32>(cViewport.GetHeight()); // Calculate frustum vertices if required if ((m_nInternalCameraFlags & RecalculateFrustumVertices) || m_nViewportWidth != nViewportWidth || m_nViewportHeight != nViewportHeight) { // Ensure that the other camera properties which depend on the viewport dimension are also updated correctly // -> This may lead to a "double" (in sense of "we could probably avoid one when doing more complex tests") calculation, but this in here is just an optimization and should never result in invalid settings m_nInternalCameraFlags |= RecalculateProjectionMatrix; m_nInternalCameraFlags |= RecalculateFrustum; // Backup the viewport dimension m_nViewportWidth = nViewportWidth; m_nViewportHeight = nViewportHeight; // Set unit box m_cFrustumVertices.Resize(8); m_cFrustumVertices[0].SetXYZ(-1.0f, -1.0f, -1.0f); m_cFrustumVertices[1].SetXYZ(-1.0f, 1.0f, -1.0f); m_cFrustumVertices[2].SetXYZ( 1.0f, 1.0f, -1.0f); m_cFrustumVertices[3].SetXYZ( 1.0f, -1.0f, -1.0f); m_cFrustumVertices[4].SetXYZ(-1.0f, -1.0f, 1.0f); m_cFrustumVertices[5].SetXYZ(-1.0f, 1.0f, 1.0f); m_cFrustumVertices[6].SetXYZ( 1.0f, 1.0f, 1.0f); m_cFrustumVertices[7].SetXYZ( 1.0f, -1.0f, 1.0f); // Get world transform matrix with no scale Matrix4x4 mWorld; mWorld.FromQuatTrans(CalculateViewRotation(), GetTransform().GetPosition()); mWorld *= GetProjectionMatrix(cViewport).GetInverted(); // Project the vertices for (uint8 i=0; i<m_cFrustumVertices.GetNumOfElements(); i++) m_cFrustumVertices[i] *= mWorld; // Recalculation done m_nInternalCameraFlags &= ~RecalculateFrustumVertices; } // Return the frustum vertices return m_cFrustumVertices; }