コード例 #1
0
// -------------------------------------------------------------------------- //
// Misc                                           
// -------------------------------------------------------------------------- //
void VFmodManager::OnHandleCallback(IVisCallbackDataObject_cl *pData)
{
  if (pData->m_pSender==&Vision::Callbacks.OnEngineInit)
  {
    InitFmodSystem();
    return;
  }

  if(pData->m_pSender == &Vision::Callbacks.OnEngineDeInit)
  {
    // release all resources before the engine deinitializes
    m_soundInstances.Clear(); 
    m_events.Clear();
    m_collisionMeshes.Clear();
    m_reverbs.Clear();

    m_bAnyStopped = false;

    DeInitFmodSystem();
    return;
  }

  if (pData->m_pSender==&Vision::Callbacks.OnUpdateSceneFinished)
  {
    RunTick(Vision::GetTimer()->GetTimeDifference());
#ifdef _DEBUG_OUTPUT
    SoundInstances().DebugOutput();
    Events().DebugOutput();
#endif
    return;
  }

  if (pData->m_pSender==&Vision::Callbacks.OnWorldInit)
  {
    if (!IsInitialized())
      return;

    VASSERT(m_pSystem!=NULL);

    // notify the sound engine about the world extents   
    float fRadius = 32000.0f;
    hkvAlignedBBox bbox;
    Vision::GetSceneManager()->GetSceneExtents(bbox);
    if (bbox.isValid())
      fRadius = bbox.getBoundingSphere().m_fRadius; 
    FMOD_ERRORCHECK(m_pSystem->setGeometrySettings(fRadius));

    return;
  }

  if (pData->m_pSender==&Vision::Callbacks.OnWorldDeInit)
  {
    // stop all instances and dispose them if possible (i.e VFMOD_FLAG_NODISPOSE flag not set)
    SoundInstances().StopAll(true); 
    Events().StopAll(true);

    // remove all collision meshes
    CollisionMeshes().Clear(); 

    // remove all reverbs
    Reverbs().Clear();

    m_bAnyStopped = false;
  
    return;
  }

  if (pData->m_pSender==&IVScriptManager::OnScriptProxyCreation)
  {
    VScriptCreateStackProxyObject * pScriptData = (VScriptCreateStackProxyObject *)pData;

    //process data only as far as not handled until now
    if (!pScriptData->m_bProcessed)
    {
      int iRetParams = 0;
      if (pScriptData->m_pInstance->IsOfType(V_RUNTIME_CLASS(VFmodSoundObject)))
        iRetParams = LUA_CallStaticFunction(pScriptData->m_pLuaState,"FireLight","VFmodSoundObject","Cast","O>O",pScriptData->m_pInstance);
      else if (pScriptData->m_pInstance->IsOfType(V_RUNTIME_CLASS(VFmodEvent)))
        iRetParams = LUA_CallStaticFunction(pScriptData->m_pLuaState,"FireLight","VFmodEvent","Cast","O>O",pScriptData->m_pInstance);

      if (iRetParams>0)
      {
        if(lua_isnil(pScriptData->m_pLuaState, -1))   
          lua_pop(pScriptData->m_pLuaState, iRetParams);
        else                                         
          pScriptData->m_bProcessed = true;
      }
    }
    return;
  }

  if(pData->m_pSender==&IVScriptManager::OnRegisterScriptFunctions)
  {
    IVScriptManager* pSM = Vision::GetScriptManager();
    if (pSM)
    {
      lua_State* pLuaState = ((VScriptResourceManager*)pSM)->GetMasterState();
      if(pLuaState)
      {
        lua_getglobal(pLuaState, "Fmod");
        int iType = lua_type(pLuaState, -1);
        lua_pop(pLuaState, 1);

        if(iType!=LUA_TUSERDATA)
        {
          luaopen_FireLight(pLuaState);
          int iRetParams = LUA_CallStaticFunction(pLuaState,"FireLight","VFmodManager","Cast","v>v", &VFmodManager::GlobalManager());
          if (iRetParams==1)
          {
            if(lua_isnil(pLuaState, -1))
            {
              lua_pop(pLuaState, iRetParams);
            }
            else
            {
              lua_setglobal(pLuaState, "Fmod");
              return;
            }
          }
        }
        else
        {
          return; //already loaded
        }
      }
      
      Vision::Error.Warning("Unable to create Lua Fmod Module, lua_State is NULL or cast failed!");
    }
    return;
  }

#if defined(_VISION_MOBILE)
  // Pause Sound when in background
  if (pData->m_pSender == &Vision::Callbacks.OnLeaveForeground)
  {
    if (IsInitialized())
    {
      // From the FMOD Ex documentation:
      // "Channels will not have their per channel pause state overwritten, 
      // so that when a channelgroup is unpaused, the paused state of the channels will 
      // correct as they were set on a per channel basis."
      m_pMasterGroup->getPaused(&m_bMasterGroupPausedInForeground);
      m_pMusicGroup->getPaused(&m_bMusicGroupPausedInForeground);

      m_pMasterGroup->setPaused(true);
      m_pMusicGroup->setPaused(true);

      // Get master event category and pause it as well
      FMOD::EventCategory *pEventCategory = NULL;   
      FMOD_ERRORCHECK(m_pEventSystem->getCategoryByIndex(-1, &pEventCategory));

      pEventCategory->getPaused(&m_bMasterEventCategoryPausedInForeground);
      pEventCategory->setPaused(true);
    }

    return;
  }

  if (pData->m_pSender == &Vision::Callbacks.OnEnterForeground)
  {
    if (IsInitialized())
    {
      m_pMasterGroup->setPaused(m_bMasterGroupPausedInForeground);
      m_pMusicGroup->setPaused(m_bMusicGroupPausedInForeground);

      FMOD::EventCategory *pEventCategory = NULL;   
      FMOD_ERRORCHECK(m_pEventSystem->getCategoryByIndex(-1, &pEventCategory));

      pEventCategory->setPaused(m_bMasterEventCategoryPausedInForeground);
    }

    return;
  }
#endif
}
コード例 #2
0
void VFmodManager::RunTick(float fTimeDelta)
{
  if (!IsInitialized())
    return;

  VISION_PROFILE_FUNCTION(PROFILING_FMOD_OVERALL);

  // profiling scope
  {
    VISION_PROFILE_FUNCTION(PROFILING_FMOD_PUREUPDATE);

    VASSERT(m_pEventSystem!=NULL);
    
    // update Fmod listener attributes
    VisObject3D_cl *pListener = m_pListenerObject ? m_pListenerObject : Vision::Camera.GetMainCamera();
    if (!pListener)
      return;

    hkvVec3 vCamPos = pListener->GetPosition();
    hkvVec3 vDir(pListener->GetObjDir()),
            vRight(pListener->GetObjDir_Right()),
            vUp(pListener->GetObjDir_Up());

    vUp = -vUp; // compensate for coordinate system
    m_pEventSystem->set3DListenerAttributes(0, (FMOD_VECTOR *)&vCamPos, NULL, (FMOD_VECTOR *)&vDir, (FMOD_VECTOR *)&vUp); // no speed (yet)
    
    
    // update all sound objects 
    SoundInstances().Update();

    // update all events 
    Events().Update();

    // update Fmod event system
    m_fTimeLeftOver += fTimeDelta;
    if (m_fTimeLeftOver > m_config.fTimeStep)
    { 
      m_pEventSystem->update();
#ifdef VFMOD_SUPPORTS_NETWORK
      if (m_config.bUseNetworkSystem)
        FMOD::NetEventSystem_Update();
#endif
      m_fTimeLeftOver = hkvMath::mod (m_fTimeLeftOver, m_config.fTimeStep);
    }
  } 
  
  // do not purge sounds/ events in vForge, in order to allow toggling playback via hotspot button
  if (Vision::Editor.IsInEditor())
    return;  

  if (m_bAnyStopped)
  {
    VISION_PROFILE_FUNCTION(PROFILING_FMOD_PURGE);

    // all sounds/ events that have finished playing are removed from handling
    SoundInstances().PurgeNotPlaying();
    Events().PurgeNotPlaying();

    m_bAnyStopped = false; // reset any stopped flag
  }
}
コード例 #3
0
void VFmodManager::RunTick(float fTimeDelta)
{
  VISION_PROFILE_FUNCTION(PROFILING_FMOD_OVERALL);

  if (!IsInitialized())
  {
    if (!IsOutputDevicePresent())
      InitDevice();

    return; 
  }

  // profiling scope
  {
    VISION_PROFILE_FUNCTION(PROFILING_FMOD_PUREUPDATE);

    VASSERT(m_pEventSystem!=NULL);

    // update Fmod listener attributes
    VisObject3D_cl *pListener = m_pListenerObject;
    if (pListener == NULL)
    {
      // The listener is the main camera. Check for teleportation since the last Fmod update, in
      // which case we won't use the position difference to calculate the listener speed.
      VisContextCamera_cl* pCamera = Vision::Camera.GetMainCamera();
      VisRenderContext_cl* pContext = VisRenderContext_cl::GetMainRenderContext();
      if (pCamera != NULL && pContext != NULL)
      {
        if (m_bLastListenerPositionValid && pCamera->GetLastTeleported() > m_iFrameOfLastUpdate)
          m_bLastListenerPositionValid = false;

        m_iFrameOfLastUpdate = pContext->GetLastRenderedFrame();
        pListener = pCamera;
      }
    }

    if (!pListener)
      return;

    hkvVec3 vCamPos = pListener->GetPosition();
    hkvVec3 vDir(pListener->GetObjDir()),
            vRight(pListener->GetObjDir_Right()),
            vUp(pListener->GetObjDir_Up());

    // Determine the camera velocity based on the previous known position
    hkvVec3 vCamVel(m_bLastListenerPositionValid && (fTimeDelta > 0.f) ? (vCamPos - m_vLastListenerPosition) * (1.f / fTimeDelta) : hkvVec3::ZeroVector());
    m_vLastListenerPosition = vCamPos;
    m_bLastListenerPositionValid = true;

    vUp = -vUp; // compensate for coordinate system
    m_pEventSystem->set3DListenerAttributes(0, (FMOD_VECTOR *)&vCamPos, (FMOD_VECTOR *)&vCamVel, (FMOD_VECTOR *)&vDir, (FMOD_VECTOR *)&vUp);

    // update all sound objects 
    SoundInstances().Update(fTimeDelta);

    // update all events 
    Events().Update(fTimeDelta);

    // update Fmod event system
    m_fTimeLeftOver += fTimeDelta;
    if (m_fTimeLeftOver > m_config.fTimeStep)
    { 
      m_pEventSystem->update();

#ifdef VFMOD_SUPPORTS_NETWORK
      if (m_config.bUseNetworkSystem)
        FMOD::NetEventSystem_Update();
#endif
      m_fTimeLeftOver = hkvMath::mod (m_fTimeLeftOver, m_config.fTimeStep);
    }
  }

  // do not purge sounds/ events in vForge, in order to allow toggling playback via hotspot button
  if (Vision::Editor.IsInEditor())
    return;  

  if (m_bAnyStopped)
  {
    VISION_PROFILE_FUNCTION(PROFILING_FMOD_PURGE);

    // all sounds/ events that have finished playing are removed from handling
    SoundInstances().PurgeNotPlaying();
    Events().PurgeNotPlaying();

    m_bAnyStopped = false; // reset any stopped flag
  }
}