예제 #1
0
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 );
}
예제 #2
0
void CClientMarker::DoPulse ( void )
{
    // Update our position/rotation if we're attached
    DoAttaching ();

    // Pulse the element we contain
    if ( m_pMarker ) m_pMarker->DoPulse ();
}
예제 #3
0
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 );
    }
}
예제 #4
0
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 );
        }
    }
}
예제 #5
0
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;
}
예제 #6
0
////////////////////////////////////////////////////////////
//
// 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 );
        }
    }
}