/*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 );
	}
}
Example #4
0
/*
================
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 );
	}
}