//////////////////////////////////////////////////////////////////////////// // // Crytek Engine Source File. // Copyright (C), Crytek Studios, 2001. // ------------------------------------------------------------------------- // File name: scenenode.cpp // Version: v1.00 // Created: 23/4/2002 by Lennert. // Compilers: Visual C++ 7.0 // Description: // ------------------------------------------------------------------------- // History: // //////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "SceneNode.h" #include "AnimTrack.h" #include "SelectTrack.h" #include "EventTrack.h" #include "ConsoleTrack.h" #include "MusicTrack.h" #include "isystem.h" #include "igame.h" #include "AnimCameraNode.h" #include "Movie.h" #include #include namespace { bool s_nodeParamsInitialized = false; std::vector s_nodeParams; void AddSupportedParam( const char *sName,int paramId,EAnimValue valueType ) { IAnimNode::SParamInfo param; param.name = sName; param.paramId = paramId; param.valueType = valueType; s_nodeParams.push_back( param ); } } ////////////////////////////////////////////////////////////////////////// CAnimSceneNode::CAnimSceneNode( IMovieSystem *sys ) : CAnimNode(sys) { m_dwSupportedTracks = PARAM_BIT(APARAM_CAMERA) | PARAM_BIT(APARAM_EVENT) | PARAM_BIT(APARAM_SOUND1)|PARAM_BIT(APARAM_SOUND2)|PARAM_BIT(APARAM_SOUND3) | PARAM_BIT(APARAM_SEQUENCE) | PARAM_BIT(APARAM_CONSOLE) | PARAM_BIT(APARAM_MUSIC); m_pMovie=sys; for (int i=0;i= 0 && nIndex < s_nodeParams.size()) { info = s_nodeParams[nIndex]; return true; } return false; } ////////////////////////////////////////////////////////////////////////// bool CAnimSceneNode::GetParamInfoFromId( int paramId, SParamInfo &info ) const { for (int i = 0; i < s_nodeParams.size(); i++) { if (s_nodeParams[i].paramId == paramId) { info = s_nodeParams[i]; return true; } } return false; } /* ////////////////////////////////////////////////////////////////////////// IAnimBlock* CAnimSceneNode::CreateAnimBlock() { // Assign tracks to this anim node. IAnimBlock *block = new CAnimBlock; CreateTrack(block, APARAM_CAMERA); return block; };*/ ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::Animate( SAnimContext &ec ) { CAnimBlock *anim = (CAnimBlock*)GetAnimBlock(); if (!anim) return; if (ec.bResetting) return; CSelectTrack *cameraTrack = NULL; CEventTrack *pEventTrack = NULL; CSoundTrack *pSoundTrack[3] = { NULL,NULL,NULL }; CSelectTrack *pSequenceTrack = NULL; CConsoleTrack *pConsoleTrack = NULL; CMusicTrack *pMusicTrack = NULL; /* bool bTimeJump = false; if (ec.time < m_time) bTimeJump = true; */ int paramCount = anim->GetTrackCount(); for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) { int trackType; IAnimTrack *pTrack; if (!anim->GetTrackInfo( paramIndex,trackType,&pTrack )) continue; switch (trackType) { case APARAM_CAMERA: cameraTrack = (CSelectTrack*)pTrack; break; case APARAM_EVENT: pEventTrack = (CEventTrack*)pTrack; break; case APARAM_SOUND1: pSoundTrack[0] = (CSoundTrack*)pTrack; break; case APARAM_SOUND2: pSoundTrack[1] = (CSoundTrack*)pTrack; break; case APARAM_SOUND3: pSoundTrack[2] = (CSoundTrack*)pTrack; break; case APARAM_SEQUENCE: pSequenceTrack = (CSelectTrack*)pTrack; break; case APARAM_CONSOLE: pConsoleTrack = (CConsoleTrack*)pTrack; break; case APARAM_MUSIC: pMusicTrack = (CMusicTrack*)pTrack; break; } } // Process entity track. if (cameraTrack) { ISelectKey key; int cameraKey = cameraTrack->GetActiveKey(ec.time,&key); if (cameraKey != m_lastCameraKey/* && cameraKey > m_lastCameraKey*/) { if (!ec.bSingleFrame || key.time == ec.time) // If Single frame update key time must match current time. ApplyCameraKey( key,ec ); } m_lastCameraKey = cameraKey; } if (pEventTrack) { IEventKey key; int nEventKey = pEventTrack->GetActiveKey(ec.time,&key); if (nEventKey != m_lastEventKey && nEventKey >= 0) { if (!ec.bSingleFrame || key.time == ec.time) // If Single frame update key time must match current time. ApplyEventKey(key, ec); } m_lastEventKey = nEventKey; } if (pConsoleTrack) { IConsoleKey key; int nConsoleKey = pConsoleTrack->GetActiveKey(ec.time,&key); if (nConsoleKey != m_lastConsoleKey && nConsoleKey >= 0) { if (!ec.bSingleFrame || key.time == ec.time) // If Single frame update key time must match current time. ApplyConsoleKey(key, ec); } m_lastConsoleKey = nConsoleKey; } if (pMusicTrack) { IMusicKey key; int nMusicKey = pMusicTrack->GetActiveKey(ec.time,&key); if (nMusicKey != m_lastMusicKey && nMusicKey >= 0) { if (!ec.bSingleFrame || key.time == ec.time) // If Single frame update key time must match current time. ApplyMusicKey(key, ec); } m_lastMusicKey = nMusicKey; } for (int i=0;iGetActiveKey(ec.time, &key); if (nSoundKey!=m_SoundInfo[i].nLastKey || key.time==ec.time || nSoundKey==-1) { if (!ec.bSingleFrame || key.time == ec.time) // If Single frame update key time must match current time. { m_SoundInfo[i].nLastKey=nSoundKey; ApplySoundKey( pSoundTrack[i],nSoundKey,i, key, ec); } } } } if (pSequenceTrack) { ISelectKey key; int nSequenceKey = pSequenceTrack->GetActiveKey(ec.time,&key); if (nSequenceKey != m_lastSequenceKey && nSequenceKey >= 0) { if (!ec.bSingleFrame || key.time == ec.time) // If Single frame update key time must match current time. ApplySequenceKey(pSequenceTrack,nSequenceKey,key, ec); } m_lastSequenceKey = nSequenceKey; } m_time = ec.time; if (m_callback) { m_callback->OnNodeAnimated(); }else { } } void CAnimSceneNode::ReleaseSounds() { // stop all sounds for (int i=0;iStop(); m_SoundInfo[i].nLastKey=-1; m_SoundInfo[i].sLastFilename=""; m_SoundInfo[i].pSound=NULL; } // enable music-event processing if (m_bMusicMoodSet) { IMusicSystem *pMusicSystem=GetMovieSystem()->GetSystem()->GetIMusicSystem(); if (pMusicSystem) pMusicSystem->EnableEventProcessing(true); m_bMusicMoodSet=false; } } ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::Reset() { // If camera from this sequence still active, remove it. // reset camera SCameraParams CamParams = m_pMovie->GetCameraParams(); if (CamParams.nCameraId != 0 && CamParams.nCameraId == m_sequenceCameraId) { CamParams.cameraNode = NULL; CamParams.nCameraId = 0; m_pMovie->SetCameraParams(CamParams); } m_lastCameraKey = -1; m_lastEventKey = -1; m_lastConsoleKey = -1; m_lastMusicKey = -1; m_lastSequenceKey = -1; m_sequenceCameraId = -1; ReleaseSounds(); } ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::Pause() { ReleaseSounds(); } ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::ApplyCameraKey( ISelectKey &key,SAnimContext &ec ) { IAnimNode *cameraNode = GetMovieSystem()->FindNode(key.szSelection); float fov=60.0f; SCameraParams CamParams; CamParams.cameraNode = cameraNode; CamParams.nCameraId=0; if (cameraNode) { cameraNode->GetParamValue( ec.time,APARAM_FOV,fov ); IEntity *cameraEntity=cameraNode->GetEntity(); if (cameraEntity) CamParams.nCameraId=cameraEntity->GetId(); } else { if (strlen(key.szSelection) > 0) { m_pMovie->GetSystem()->Warning( VALIDATOR_MODULE_MOVIE,VALIDATOR_WARNING,0,0, "[CryMovie] Camera entity %s not found",(const char*)key.szSelection ); } } CamParams.fFOV=DEG2RAD(fov); m_pMovie->SetCameraParams(CamParams); m_sequenceCameraId = CamParams.nCameraId; } ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::ApplyEventKey(IEventKey &key, SAnimContext &ec) { char funcName[1024]; strcpy(funcName, "Event_"); strcat(funcName, key.event); m_pMovie->SendGlobalEvent(funcName); } ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::ApplySoundKey( IAnimTrack *pTrack,int nCurrKey,int nLayer, ISoundKey &key, SAnimContext &ec) { if (m_SoundInfo[nLayer].nLastKey==-1) { if (m_SoundInfo[nLayer].pSound) m_SoundInfo[nLayer].pSound->Stop(); m_SoundInfo[nLayer].pSound=NULL; return; } if (((strcmp(m_SoundInfo[nLayer].sLastFilename.c_str(), key.pszFilename)) || (!m_SoundInfo[nLayer].pSound))) { int flags = 0; //if (key.bStream) //flags |= FLAG_SOUND_STREAM; //else flags |= FLAG_SOUND_LOAD_SYNCHRONOUSLY; // Allways synchronously for now. if (key.bLoop) flags |= FLAG_SOUND_LOOP; //if (key.b3DSound) { // Always 2D sound. flags |= FLAG_SOUND_2D|FLAG_SOUND_STEREO|FLAG_SOUND_16BITS; } // we have a different sound now if (m_SoundInfo[nLayer].pSound) m_SoundInfo[nLayer].pSound->Stop(); m_SoundInfo[nLayer].pSound = m_pMovie->GetSystem()->GetISoundSystem()->LoadSound(key.pszFilename, flags|FLAG_SOUND_UNSCALABLE); m_SoundInfo[nLayer].sLastFilename=key.pszFilename; if (m_SoundInfo[nLayer].pSound) { m_SoundInfo[nLayer].nLength=m_SoundInfo[nLayer].pSound->GetLengthMs(); key.fDuration = ((float)m_SoundInfo[nLayer].nLength) / 1000.0f; pTrack->SetKey( nCurrKey,&key ); // Update key duration. } }else { if (m_SoundInfo[nLayer].pSound) m_SoundInfo[nLayer].pSound->Stop(); } if (!m_SoundInfo[nLayer].pSound) return; m_SoundInfo[nLayer].pSound->SetSoundPriority( MOVIE_SOUND_PRIORITY ); m_SoundInfo[nLayer].pSound->SetVolume(key.nVolume); m_SoundInfo[nLayer].pSound->SetPan(key.nPan); int nOffset=(int)((ec.time-key.time)*1000.0f); if (nOffset < m_SoundInfo[nLayer].nLength) { //return; m_SoundInfo[nLayer].pSound->SetCurrentSamplePos(nOffset, true); } ((CMovieSystem*)m_pMovie)->OnPlaySound( m_SoundInfo[nLayer].pSound ); if (!m_SoundInfo[nLayer].pSound->IsPlaying()) m_SoundInfo[nLayer].pSound->Play(); } ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::ApplySequenceKey( IAnimTrack *pTrack,int nCurrKey,ISelectKey &key,SAnimContext &ec ) { if (strlen(key.szSelection) > 0) { IAnimSequence *pSequence = GetMovieSystem()->FindSequence(key.szSelection); if (pSequence) { key.fDuration = pSequence->GetTimeRange().Length(); pTrack->SetKey( nCurrKey,&key ); } GetMovieSystem()->PlaySequence(key.szSelection,true); } } ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::ApplyConsoleKey(IConsoleKey &key, SAnimContext &ec) { if (strlen(key.command) > 0) { GetMovieSystem()->GetSystem()->GetIConsole()->ExecuteString( key.command,false ); } } ////////////////////////////////////////////////////////////////////////// void CAnimSceneNode::ApplyMusicKey(IMusicKey &key, SAnimContext &ec) { IMusicSystem *pMusicSystem=GetMovieSystem()->GetSystem()->GetIMusicSystem(); if (!pMusicSystem) return; switch (key.eType) { case eMusicKeyType_SetMood: m_bMusicMoodSet=true; pMusicSystem->EnableEventProcessing(false); pMusicSystem->SetMood(key.szMood); break; case eMusicKeyType_VolumeRamp: break; } }