void CClientSound::Process3D ( CVector vecPosition ) { if ( !m_pSound || !m_b3D ) return; // Update our position and velocity if we're attached CClientEntity* pAttachedToEntity = GetAttachedTo (); if ( pAttachedToEntity ) { DoAttaching (); CVector vecVelocity; if ( CStaticFunctionDefinitions::GetElementVelocity ( *pAttachedToEntity, vecVelocity ) ) SetVelocity ( vecVelocity ); } // Volume float fDistance = DistanceBetweenPoints3D ( vecPosition, m_vecPosition ); float fDistDiff = m_fMaxDistance - m_fMinDistance; float fVolume = 1.0; //Transform e^-x to suit our sound if ( fDistance <= m_fMinDistance ) fVolume = 1.0f; else if ( fDistance >= m_fMaxDistance ) fVolume = 0.0f; else fVolume = exp ( - ( fDistance - m_fMinDistance ) * ( CUT_OFF / fDistDiff ) ); BASS_ChannelSetAttribute( m_pSound, BASS_ATTRIB_VOL, fVolume * m_fVolume ); }
void CClientMarker::DoPulse ( void ) { // Update our position/rotation if we're attached DoAttaching (); // Pulse the element we contain if ( m_pMarker ) m_pMarker->DoPulse (); }
void CClientSound::Process3D ( CVector vecPosition, CVector vecLookAt ) { if ( !m_b3D ) return; // Update our position/rotation if we're attached DoAttaching (); if ( m_pSound ) { // Pan CVector vecLook = vecLookAt - vecPosition; CVector vecSound = m_vecPosition - vecPosition; vecLook.fZ = vecSound.fZ = 0.0f; vecLook.Normalize (); vecSound.Normalize (); vecLook.CrossProduct ( &vecSound ); // The length of the cross product (which is simply fZ in this case) // is equal to the sine of the angle between the vectors float fPan = vecLook.fZ; if ( fPan < -1.0f + SOUND_PAN_THRESHOLD ) fPan = -1.0f + SOUND_PAN_THRESHOLD; else if ( fPan > 1.0f - SOUND_PAN_THRESHOLD ) fPan = 1.0f - SOUND_PAN_THRESHOLD; m_pSound->setPan ( fPan ); // Volume float fDistance = DistanceBetweenPoints3D ( vecPosition, m_vecPosition ); float fSilenceDistance = m_fMinDistance * 20.0f; float fVolume = 1.0; if ( fDistance <= m_fMinDistance ) { fVolume = 1.0f; } else if ( fDistance >= fSilenceDistance ) { fVolume = 0.0f; } else { float fLinear = (fSilenceDistance - fDistance) / fSilenceDistance; fVolume = sqrt ( fLinear ) * fLinear; } m_pSound->setVolume ( m_fVolume * fVolume ); } }
void CClientObject::StreamedInPulse ( void ) { // Some things to do if low LOD object if ( m_bIsLowLod ) { // Manually update attaching in case other object is streamed out DoAttaching (); // Be hidden if all HighLodObjects are fully visible m_IsHiddenLowLod = true; if ( m_HighLodObjectList.empty () ) m_IsHiddenLowLod = false; for ( std::vector < CClientObject* >::iterator iter = m_HighLodObjectList.begin () ; iter != m_HighLodObjectList.end () ; ++iter ) { CObject* pObject = (*iter)->m_pObject; if ( !pObject || !pObject->IsFullyVisible () ) { m_IsHiddenLowLod = false; break; } } UpdateVisibility (); } // Are we not a static object (allowed to move by physics) if ( !m_bIsStatic ) { // Grab our actual position (as GTA moves it too) CVector vecPosition = *m_pObject->GetPosition (); // Has it moved without MTA knowing? if ( vecPosition != m_vecPosition ) { m_vecPosition = vecPosition; // Update our streaming position UpdateStreamPosition ( m_vecPosition ); } } }
bool CClientCamera::ProcessFixedCamera ( CCam* pCam ) { assert ( pCam ); // The purpose of this handler function is changing the Source, Front and Up vectors in CCam // when called by GTA. This is called when we are in fixed camera mode. // Make sure we actually want to apply our custom camera position/lookat // (this handler could also be called from cinematic mode) if ( !m_bFixed ) return false; // Update our position/rotation if we're attached DoAttaching (); SetGtaMatrix( m_matFixedMatrix, pCam ); // Set the zoom pCam->SetFOV ( m_fFOV ); return true; }
//////////////////////////////////////////////////////////// // // CClientSound::Process3D // // Update position and velocity and pass on the BASS for processing. // m_pAudio->DoPulse needs to be called for non-3D sounds also. // //////////////////////////////////////////////////////////// void CClientSound::Process3D ( const CVector& vecPlayerPosition, const CVector& vecCameraPosition, const CVector& vecLookAt ) { // Update 3D things if required if ( m_b3D ) { // Update our position and velocity if we're attached CClientEntity* pAttachedToEntity = GetAttachedTo (); if ( pAttachedToEntity ) { GetPosition( m_vecPosition ); DoAttaching (); CVector vecVelocity; if ( CStaticFunctionDefinitions::GetElementVelocity ( *pAttachedToEntity, vecVelocity ) ) SetVelocity ( vecVelocity ); // Update our spatial data position UpdateSpatialData (); } } // If the sound isn't active, we don't need to process it // Moved after 3D updating as the streamer didn't know the position changed if a sound isn't streamed in when attached. if ( !m_pAudio ) return; m_pAudio->DoPulse ( vecPlayerPosition, vecCameraPosition, vecLookAt ); // Trigger script events for things SSoundEventInfo eventInfo; while ( m_pAudio->GetQueuedEvent ( eventInfo ) ) { if ( eventInfo.type == SOUND_EVENT_FINISHED_DOWNLOAD ) { CLuaArguments Arguments; Arguments.PushNumber ( eventInfo.dNumber ); CallEvent ( "onClientSoundFinishedDownload", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundFinishedDownload %f", eventInfo.dNumber ) ); } else if ( eventInfo.type == SOUND_EVENT_CHANGED_META ) { CLuaArguments Arguments; Arguments.PushString ( eventInfo.strString ); CallEvent ( "onClientSoundChangedMeta", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundChangedMeta %s", *eventInfo.strString ) ); } else if ( eventInfo.type == SOUND_EVENT_STREAM_RESULT ) { // Call onClientSoundStream LUA event CLuaArguments Arguments; Arguments.PushBoolean ( eventInfo.bBool ); Arguments.PushNumber ( eventInfo.dNumber ); if ( !eventInfo.strString.empty () ) Arguments.PushString ( eventInfo.strString ); CallEvent ( "onClientSoundStream", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundStream %d %f %s", eventInfo.bBool, eventInfo.dNumber, *eventInfo.strString ) ); } else if ( eventInfo.type == SOUND_EVENT_BEAT ) { CLuaArguments Arguments; Arguments.PushNumber ( eventInfo.dNumber ); CallEvent ( "onClientSoundBeat", Arguments, true ); } } }