/*virtual*/ void EldritchSound3DListener::ModifyAttenuation( ISoundInstance* const pSoundInstance, float& Attenuation ) const { PROFILE_FUNCTION; if( !m_World ) { return; } if( !pSoundInstance->ShouldCalcOcclusion() ) { return; } CollisionInfo FromListenerInfo; FromListenerInfo.m_CollideWorld = true; FromListenerInfo.m_CollideEntities = true; FromListenerInfo.m_UserFlags = EECF_Occlusion; FromListenerInfo.m_StopAtAnyCollision = true; CollisionInfo FromSoundInfo; FromSoundInfo.m_CollideWorld = true; FromSoundInfo.m_CollideEntities = true; FromSoundInfo.m_UserFlags = EECF_Occlusion; FromSoundInfo.m_StopAtAnyCollision = true; const Vector SoundLocation = pSoundInstance->GetLocation(); const bool Occluded = m_World->LineCheck( m_Location, SoundLocation, FromListenerInfo ) && m_World->LineCheck( SoundLocation, m_Location, FromSoundInfo ); if( Occluded ) { // Use the ratio between the distances to sound source and to occlusion as a factor in attenuation. Vector ToOcclusionNear = FromListenerInfo.m_Intersection - m_Location; ToOcclusionNear.z *= m_VerticalScalar; Vector ToOcclusionFar = FromSoundInfo.m_Intersection - SoundLocation; ToOcclusionFar.z *= m_VerticalScalar; Vector ToSound = SoundLocation - m_Location; ToSound.z *= m_VerticalScalar; const float DistanceToOcclusionNear = ToOcclusionNear.Length(); const float DistanceToOcclusionFar = ToOcclusionFar.Length(); const float DistanceToSound = ToSound.Length(); const float DistanceRatio = ( DistanceToOcclusionNear + DistanceToOcclusionFar ) / DistanceToSound; // And attenuate occluded sounds more if they're more distant. const float OcclusionAttenuation = Attenuate( DistanceToSound, m_OccludedFalloffRadius ); Attenuation *= DistanceRatio * OcclusionAttenuation; } }
void LuaScreenShake( TGfxVec2 fEpiCenter, TGfxVec2 fObserver, float fStrenght, float fStabilisationSpeed) { float fFullImpactEffect = 4.0f; float fNullImpactEffect = 12.0f; float fImpactFallOff = 1.0f; float fImpactDistance = (fEpiCenter - fObserver).Length(); float fAttenuation = Attenuate(fFullImpactEffect, fNullImpactEffect,fImpactDistance, fImpactFallOff); lua_pushnumber(GfxFreshLuaState(), fStrenght * fAttenuation); lua_pushnumber(GfxFreshLuaState(), fStabilisationSpeed); LuaCallGlobal(GfxFreshLuaState(), "ShakeScreen"); }
void WBCompEldHUDMarker::UpdateMarkerPosition() const { WBEntity* const pEntity = GetEntity(); WBCompEldTransform* const pTransform = pEntity->GetTransformComponent<WBCompEldTransform>(); EldritchWorld* const pWorld = GetWorld(); const View* const pView = GetFramework()->GetMainView(); Vector Location = pTransform->GetLocation(); Location.z += m_OffsetZ; const Vector& ViewLocation = pView->m_Location; const Vector2 ScreenLocation = pView->ProjectAndClipToScreen( Location ); CollisionInfo Info; Info.m_CollideWorld = true; Info.m_CollideEntities = true; Info.m_CollidingEntity = pEntity; Info.m_UserFlags = EECF_Occlusion; Info.m_StopAtAnyCollision = true; const bool Occluded = pWorld->LineCheck( ViewLocation, Location, Info ); const float Distance = ( Location - ViewLocation ).Length(); const float Alpha = Occluded ? Attenuate( Distance, m_FalloffRadius ) : 1.0f; { WB_MAKE_EVENT( SetWidgetImage, NULL ); WB_SET_AUTO( SetWidgetImage, Hash, Screen, m_UIScreenName ); WB_SET_AUTO( SetWidgetImage, Hash, Widget, m_UIWidgetName ); WB_SET_AUTO( SetWidgetImage, Hash, Image, Occluded ? m_OccludedImage : m_UnoccludedImage ); WB_DISPATCH_EVENT( GetEventManager(), SetWidgetImage, NULL ); } { WB_MAKE_EVENT( SetWidgetLocation, NULL ); WB_SET_AUTO( SetWidgetLocation, Hash, Screen, m_UIScreenName ); WB_SET_AUTO( SetWidgetLocation, Hash, Widget, m_UIWidgetName ); WB_SET_AUTO( SetWidgetLocation, Float, X, ScreenLocation.x ); WB_SET_AUTO( SetWidgetLocation, Float, Y, ScreenLocation.y ); WB_DISPATCH_EVENT( GetEventManager(), SetWidgetLocation, NULL ); } { WB_MAKE_EVENT( SetWidgetAlpha, NULL ); WB_SET_AUTO( SetWidgetAlpha, Hash, Screen, m_UIScreenName ); WB_SET_AUTO( SetWidgetAlpha, Hash, Widget, m_UIWidgetName ); WB_SET_AUTO( SetWidgetAlpha, Float, Alpha, Alpha ); WB_DISPATCH_EVENT( GetEventManager(), SetWidgetAlpha, NULL ); } }
/* ================ rvEffect::Event_Attenuate ================ */ void rvEffect::Event_Attenuate( float attenuation ) { Attenuate( attenuation ); }
/*virtual*/ void WBCompEldSensorVision::PollTick( const float DeltaTime ) const { const Array<WBCompEldVisible*>* pVisibleComponents = WBComponentArrays::GetComponents<WBCompEldVisible>(); if( !pVisibleComponents ) { return; } EldritchWorld* const pWorld = GetWorld(); ASSERT( pWorld ); WBEntity* const pEntity = GetEntity(); DEVASSERT( pEntity ); WBCompRodinKnowledge* const pKnowledge = GET_WBCOMP( pEntity, RodinKnowledge ); ASSERT( pKnowledge ); WBCompEldTransform* const pTransform = pEntity->GetTransformComponent<WBCompEldTransform>(); DEVASSERT( pTransform ); WBCompEldHeadTracker* const pHeadTracker = GET_WBCOMP( pEntity, EldHeadTracker ); const Vector Location = pTransform->GetLocation(); const Vector EyeLocation = Location + Vector( 0.0f, 0.0f, m_EyeOffsetZ ); const Vector EyeDirection = pHeadTracker ? pHeadTracker->GetLookDirection() : pTransform->GetOrientation().ToVector(); static const Vector Up = Vector( 0.0f, 0.0f, 1.0f ); const Vector EyeRight = EyeDirection.Cross( Up ).GetNormalized(); const Vector EyeUp = EyeRight.Cross( EyeDirection ); const uint NumVisibles = pVisibleComponents->Size(); for( uint VisibleIndex = 0; VisibleIndex < NumVisibles; ++VisibleIndex ) { WBCompEldVisible* const pVisible = ( *pVisibleComponents )[ VisibleIndex ]; ASSERT( pVisible ); WBEntity* const pVisibleEntity = pVisible->GetEntity(); ASSERT( pVisibleEntity ); WBCompRodinKnowledge::TKnowledge* const pKnowledgeEntry = pKnowledge->GetKnowledge( pVisibleEntity ); if( pKnowledgeEntry ) { // Decay knowledge if there is any STATIC_HASHED_STRING( VisionCertainty ); float VisionCertainty = pKnowledgeEntry->GetFloat( sVisionCertainty ); VisionCertainty = Max( 0.0f, VisionCertainty - m_CertaintyDecay * DeltaTime ); pKnowledgeEntry->SetFloat( sVisionCertainty, VisionCertainty ); } if( !pVisible->IsVisible() ) { continue; } // Don't check visibility of self if( pVisibleEntity == pEntity ) { continue; } // Distance check const Vector VisibleLocation = pVisible->GetVisibleLocation(); const Vector VisibleOffset = VisibleLocation - EyeLocation; const float VisibleDistSq = VisibleOffset.LengthSquared(); if( VisibleDistSq > m_RadiusSq ) { // Entity is beyond vision distance. continue; } // Cone check, with scaling on Z to flatten the cone const Vector OffsetUpPart = VisibleOffset.ProjectionOnto( EyeUp ); const Vector OffsetOtherPart = VisibleOffset - OffsetUpPart; const Vector EffectiveOffset = OffsetOtherPart + OffsetUpPart * m_ConeInvZScale; const Vector EffectiveDirection = EffectiveOffset.GetFastNormalized(); const float EffectiveCos = EyeDirection.Dot( EffectiveDirection ); if( EffectiveCos < m_ConeCos ) { // Entity is outside view cone. continue; } // World line check CollisionInfo Info; Info.m_CollideWorld = true; Info.m_CollideEntities = true; Info.m_UserFlags = EECF_Occlusion; Info.m_StopAtAnyCollision = true; if( pWorld->LineCheck( EyeLocation, VisibleLocation, Info ) ) { // Entity is occluded. continue; } // Entity is visible. WBCompEldTransform* const pVisibleTransform = pVisibleEntity->GetTransformComponent<WBCompEldTransform>(); ASSERT( pVisibleTransform ); const Vector SeenLocation = pVisibleTransform->GetLocation(); const float SeenDistance = ( SeenLocation - Location ).Length(); const float DistanceCertainty = Attenuate( SeenDistance, m_CertaintyFalloffRadius ); const float DistanceCertaintyFactor = Lerp( 1.0f - m_DistanceCertaintyFactor, 1.0f, DistanceCertainty ); // TODO: Multiply other factors in here (luminance, periphery, velocity, crouching, etc.) const float Certainty = DistanceCertaintyFactor; WBCompRodinKnowledge::TKnowledge& Knowledge = pKnowledge->UpdateEntity( pVisibleEntity ); STATIC_HASHED_STRING( VisionCertainty ); float VisionCertainty = Knowledge.GetFloat( sVisionCertainty ); // This is a bit kludgy. Accelerate toward certainty faster if target certainty is higher. VisionCertainty = Min( Certainty, VisionCertainty + m_CertaintyVelocity * Certainty * DeltaTime ); Knowledge.SetFloat( sVisionCertainty, VisionCertainty ); STATIC_HASHED_STRING( LastKnownLocation ); Knowledge.SetVector( sLastKnownLocation, VisibleLocation ); ASSERT( !VisibleLocation.IsZero() ); STATIC_HASHED_STRING( LastSeenLocation ); Knowledge.SetVector( sLastSeenLocation, VisibleLocation ); STATIC_HASHED_STRING( LastSeenTime ); Knowledge.SetFloat( sLastSeenTime, GetTime() ); STATIC_HASHED_STRING( KnowledgeType ); STATIC_HASHED_STRING( Target ); Knowledge.SetHash( sKnowledgeType, sTarget ); } }