void RPG_Effect::UpdateCameraShake(float const deltaTime) { VASSERT(m_cameraShaking); VisContextCamera_cl* camera = VisRenderContext_cl::GetCurrentContext()->GetCamera(); VASSERT(camera); // end camera shake on timeout float const shakeTime = Vision::GetTimer()->GetTime() - m_cameraShakeStartTime; if (shakeTime >= m_cameraShakeDuration) { m_cameraShakeDuration = 0.f; m_cameraShakeStartTime = 0.f; m_cameraShakeMaxAmplitude = 0.f; m_cameraShaking = false; camera->ResetLocalTransformation(); return; } // apply noise to the camera's position camera->ResetLocalTransformation(); // don't allow position updates to be cumulative hkvVec3 camPosition = camera->GetPosition(); camPosition.x += GetCameraShakeNoise(camPosition.x); camPosition.y += GetCameraShakeNoise(camPosition.y); camPosition.z += GetCameraShakeNoise(camPosition.z); camera->SetPosition(camPosition); }
void VShadowMapGenSpotDir::Update(bool force) { VisContextCamera_cl *pMainCam = m_pRendererNode->GetReferenceContext()->GetCamera(); VASSERT(pMainCam); float fCamAngle = hkvMath::Abs (hkvMath::acosDeg (pMainCam->GetDirection().dot (m_vLastCameraDir))); hkvVec3 vCamMove = pMainCam->GetPosition() - m_vLastCameraPos; m_pRendererNode->GetReferenceContext()->GetViewFrustum(m_MainViewFrustum); float fFovX, fFovY; m_pRendererNode->GetReferenceContext()->GetFinalFOV(fFovX, fFovY); float fNear, fFar; m_pRendererNode->GetReferenceContext()->GetClipPlanes(fNear, fFar); VBaseShadowMapComponentSpotDirectional* pComponent = static_cast<VBaseShadowMapComponentSpotDirectional*>(m_pShadowComponent); if (m_eProjectionType == SHADOW_PROJECTION_ORTHOGRAPHIC) { bool bOverestimateCascades = pComponent->GetOverestimateCascades() ? true : false; if (bOverestimateCascades) { if (m_fFovX != fFovX || m_fFovY != fFovY || m_fNear != fNear) { // In case user switches the FOV at runtime we need to update it here float fStartDistance = fNear; for (int iCascade = 0; iCascade < m_iNumParts; iCascade++) { float fEndDistance = pComponent->GetCascadeRange(iCascade) + fNear; m_pParts[iCascade].ComputeOffset(fStartDistance, fEndDistance); fStartDistance = fEndDistance; } m_fFovX = fFovX; m_fFovY = fFovY; m_fNear = fNear; force = true; } if (force || m_vLastLightPos != m_pLightSource->GetPosition() || m_vLastLightDir != m_pLightSource->GetDirection() || vCamMove.getLength() > pComponent->GetShadowMapCameraUpdateInterval() || fCamAngle > pComponent->GetShadowMapCameraUpdateAngle()) { for (int iCascade = 0; iCascade < m_iNumParts; iCascade++) { VShadowMapPart& part = m_pParts[iCascade]; VisContextCamera_cl* pCam = part.GetRenderContext()->GetCamera(); VisContextCamera_cl *pReferenceCam = m_pRendererNode->GetReferenceContext()->GetCamera(); hkvVec3 vCascadeCenter = pReferenceCam->GetPosition() + pReferenceCam->GetDirection() * part.m_fCenterOffset; pCam->SetDirection(GetDirection()); float fRadius = part.m_fRadius + pComponent->GetShadowMapCameraUpdateInterval(); float fCameraDistanceFromCenter = fFar; hkvVec3 vCamPos = vCascadeCenter - GetDirection() * fCameraDistanceFromCenter; pCam->SetPosition(vCamPos); //snapping hkvVec3 offset = pCam->GetWorldToCameraTransformation().getColumn(3).getAsVec3(); float fPixelSize = (fRadius * 2) / (float)m_pShadowComponent->GetShadowMapSize(); offset.x -= floorf(offset.x / fPixelSize) * fPixelSize; offset.y -= floorf(offset.y / fPixelSize) * fPixelSize; vCamPos -= pCam->GetObjDir_Right() * offset.x - pCam->GetObjDir_Up() * offset.y; pCam->SetPosition(vCamPos); // Set far clip plane so that we have z = 1 at the far side of the sphere - the shader expects this when using the BoundingBox cascade selection method. part.GetRenderContext()->SetClipPlanes(0.0f, fCameraDistanceFromCenter + fRadius); part.GetRenderContext()->SetOrthographicSize(fRadius * 2, fRadius * 2); part.Update(); } m_vLastLightPos = m_pLightSource->GetPosition(); m_vLastLightDir = m_pLightSource->GetDirection(); m_vLastCameraPos = pMainCam->GetPosition(); m_vLastCameraDir = pMainCam->GetDirection(); } } else { float fStartDistance = 0.0f; for (int iCascade = 0; iCascade < m_iNumParts; iCascade++) { VShadowMapPart& part = m_pParts[iCascade]; VisContextCamera_cl* pCam = part.GetRenderContext()->GetCamera(); // TODO: Performance // Compute the extremes of the view frustum fragment for this cascade hkvVec3 vCorners[8]; float fEndDistance = pComponent->GetCascadeRange(iCascade); part.m_fCullDistance = fEndDistance; part.GetViewFrustumCornersAtDistance(m_pRendererNode->GetReferenceContext(), fStartDistance, &vCorners[0]); part.GetViewFrustumCornersAtDistance(m_pRendererNode->GetReferenceContext(), fEndDistance, &vCorners[4]); fStartDistance = fEndDistance; pCam->SetDirection(GetDirection()); float fMinRight = FLT_MAX; float fMinUp = FLT_MAX; float fMaxRight = -FLT_MAX; float fMaxUp = -FLT_MAX; float fMinDist = FLT_MAX; float fMaxDist = -FLT_MAX; for (int iCorner = 0; iCorner < 8; iCorner ++ ) { float fRight = pCam->GetObjDir_Right().dot (vCorners[iCorner]); if (fRight < fMinRight) fMinRight = fRight; if (fRight > fMaxRight) fMaxRight = fRight; float fUp = pCam->GetObjDir_Up().dot (vCorners[iCorner]); if (fUp < fMinUp) fMinUp = fUp; if (fUp > fMaxUp) fMaxUp = fUp; float fDist = pCam->GetDirection().dot (vCorners[iCorner]); if (fDist < fMinDist) fMinDist = fDist; if (fDist > fMaxDist) fMaxDist = fDist; } // Since we need to take geometry into account which lies in front of the view frustum, we need to // offset the near clip plane (in this case, the camera position) away from the view frustum fMinDist -= (fFar - fNear); hkvVec3 vCamPos = pCam->GetObjDir_Right() * ((fMinRight + fMaxRight)*0.5f) + pCam->GetObjDir_Up() * ((fMinUp + fMaxUp)*0.5f) + pCam->GetDirection() * fMinDist; float fPadding = pComponent->GetShadowMapCameraUpdateInterval(); pCam->SetPosition(vCamPos); part.GetRenderContext()->SetClipPlanes(0.0f, fMaxDist - fMinDist); part.GetRenderContext()->SetOrthographicSize(fMaxRight - fMinRight + fPadding, fMaxUp - fMinUp + fPadding); part.Update(); } } } else if (m_eProjectionType == SHADOW_PROJECTION_PERSPECTIVE) { if (m_pLightSource->GetRadius() <= 0) //this is the case if triggered is set to false for the light { return; //do render the light at all } if (force || m_vLastLightPos != m_pLightSource->GetPosition() || m_vLastLightDir != m_pLightSource->GetDirection() || m_fLastRadius != m_pLightSource->GetRadius() || m_fLastAngle != m_pLightSource->GetProjectionAngle()) { VShadowMapPart& part = m_pParts[0]; VisContextCamera_cl* pCam = part.GetRenderContext()->GetCamera(); pCam->SetDirection(GetDirection()); pCam->SetPosition(GetPosition()); part.GetRenderContext()->SetClipPlanes(m_pShadowComponent->GetNearClip(), m_pLightSource->GetRadius()); float fAngle = m_pLightSource->GetProjectionAngle(); part.GetRenderContext()->SetFOV(fAngle, fAngle); part.Update(); m_vLastLightPos = m_pLightSource->GetPosition(); m_vLastLightDir = m_pLightSource->GetDirection(); m_fLastRadius = m_pLightSource->GetRadius(); m_fLastAngle = fAngle; } } m_iPartsRendered = 0; }