FWCamera::FWCamera(FWGraphics* pkGraphics) { m_pkGraphics = pkGraphics; if(CORE3D_FAILED(m_pkGraphics->GetDevice()->CreateRenderTarget(&m_pkRenderTarget))) { m_pkRenderTarget = NULL; } m_bLockedSurfaceViewport = false; Core3D::MatrixIdentity(m_kMatWorld); Core3D::MatrixIdentity(m_kMatView); Core3D::MatrixIdentity(m_kMatProjection); BuildFrustum(); }
void FWCamera::CalculateView() { Matrix4x4 kMatRotation, kMatTranslation; Core3D::MatrixTranslation(kMatTranslation, -m_kPosition); Core3D::MatrixRotationQuaternion(kMatRotation, m_kOrientation); m_kMatView = kMatTranslation * kMatRotation; // COMMENT : Update camera axis Core3D::MatrixTranspose(kMatRotation, kMatRotation); m_kDirection.x = kMatRotation._31; m_kDirection.y = kMatRotation._32; m_kDirection.z = kMatRotation._33; m_kUp.x = kMatRotation._21; m_kUp.y = kMatRotation._22; m_kUp.z = kMatRotation._23; m_kRight.x = kMatRotation._11; m_kRight.y = kMatRotation._12; m_kRight.z = kMatRotation._13; // COMMENT : Re-build frustum BuildFrustum(); }
void Renderer::FrustumCull(const Scene * scene, const Vector3f& camera_position, const Array<SceneObject*> & scene_objects, Array<RenderData*> & render_data_vector, const Matrix4f &vp_matrix, const OESShader * oesShader) { for (auto it = scene_objects.Begin(); it != scene_objects.End(); ++it) { SceneObject *scene_object = (*it); RenderData* render_data = scene_object->GetRenderData(); if (render_data == nullptr || render_data->GetMaterial() == nullptr) { continue; } // Check for frustum culling flag if (!scene->GetFrustumCulling()) { //No occlusion or frustum tests enabled render_data_vector.PushBack(render_data); continue; } // Frustum culling setup Mesh* currentMesh = render_data->GetMesh(); if (currentMesh == nullptr) { continue; } BoundingBoxInfo bounding_box_info = currentMesh->GetBoundingBoxInfo(); Matrix4f modelMatrixTmp = render_data->GetOwnerObject()->GetMatrixWorld(); Matrix4f mvpMatrixTmp(vp_matrix * modelMatrixTmp); // Frustum float frustum[6][4]; // Matrix to array float mvp_matrix_array[16] = { 0.0 }; const float *mat_to_array = (const float*)mvpMatrixTmp.Transposed().M[0]; // TODO this is originally glm::mat4 so transposed memcpy(mvp_matrix_array, mat_to_array, sizeof(float) * 16); // Build the frustum BuildFrustum(frustum, mvp_matrix_array); // Check for being inside or outside frustum bool is_inside = IsCubeInFrustum(frustum, bounding_box_info); // Only push those scene objects that are inside of the frustum if (!is_inside) { scene_object->SetInFrustum(false); continue; } // Transform the bounding sphere const BoundingSphereInfo sphereInfo = currentMesh->GetBoundingSphereInfo(); Vector4f sphere_center(sphereInfo.center, 1.0f); Vector4f transformed_sphere_center = mvpMatrixTmp.Transform(sphere_center); // Calculate distance from camera Vector4f position(camera_position, 1.0f); Vector4f difference = transformed_sphere_center - position; float distance = difference.Dot(difference); // this distance will be used when sorting transparent objects render_data->SetCameraDistance(distance); // Check if this is the correct LOD level if (!scene_object->InLODRange(distance)) { // not in range, don't add it to the list continue; } scene_object->SetInFrustum(); bool visible = scene_object->IsVisible(); //If visibility flag was set by an earlier occlusion query, //turn visibility on for the object if (visible) { render_data_vector.PushBack(render_data); } if (render_data->GetMaterial() == nullptr || !scene->GetOcclusionCulling()) { continue; } } }