| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- #include "MissionSoundEnvironment.h"
- #define MG_SOUNDENVIRONMENT GroupId('S','E','g','O')
- #define MG_SOUNDENVIRONMENT_MNG GroupId('S','E','M','g')
- MissionSoundEnvironment::MissionSoundEnvironment()
- {
- params = null;
- finder = null;
- }
- MissionSoundEnvironment::~MissionSoundEnvironment()
- {
- RELEASE(finder);
- }
- //Инициализировать объект
- bool MissionSoundEnvironment::Create(MOPReader & reader)
- {
- envName = reader.String();
- if(!finder)
- {
- finder = QTCreateObject(MG_SOUNDENVIRONMENT, _FL_);
- Assert(finder);
- }
- Registry(MG_SOUNDENVIRONMENT);
- Vector pos = reader.Position();
- Vector ang = reader.Angles();
- Vector size;
- size.x = reader.Float()*0.5f;
- size.y = reader.Float()*0.5f;
- size.z = reader.Float()*0.5f;
- finder->SetBox(-size, size);
- finder->SetMatrix(Matrix(ang, pos));
- UpdateStates(GetManager());
- return true;
- }
- //Обновить состояние
- void MissionSoundEnvironment::UpdateStates(MissionSoundEnvironmentManager * mng)
- {
- bool isShow = false;
- bool isActive = true;
- if(mng)
- {
- isShow = mng->IsShow();
- if(envName.NotEmpty())
- {
- params = mng->FindPreset(envName);
- if(!params)
- {
- if(!EditMode_IsOn())
- {
- isActive = false;
- LogicDebugError("Object don't work! environment preset \"%s\" not found.", envName.c_str());
- }
- }
- }
- }else{
- Show(false);
- if(!EditMode_IsOn())
- {
- isActive = false;
- LogicDebugError("Object don't work! Environment manager not found.");
- }
- }
- finder->Activate(isActive);
- #ifndef STOP_DEBUG
- if(isShow)
- {
- SetUpdate(&MissionSoundEnvironment::EditModeDraw, ML_ALPHA5);
- }else{
- DelUpdate(&MissionSoundEnvironment::EditModeDraw);
- }
- #endif
- }
- //Применить параметры среды
- bool MissionSoundEnvironment::ApplyParams(ISoundScene::Enveronment & env)
- {
- if(!params)
- {
- return false;
- }
- env = *params;
- return true;
- }
- //Инициализировать объект
- bool MissionSoundEnvironment::EditMode_Create(MOPReader & reader)
- {
- Create(reader);
- return true;
- }
- //Обновить параметры
- bool MissionSoundEnvironment::EditMode_Update(MOPReader & reader)
- {
- Create(reader);
- return true;
- }
- //Нарисовать детектор
- void _cdecl MissionSoundEnvironment::EditModeDraw(float dltTime, long level)
- {
- //Получить состояния мэнеджера
- dword color = 0x00ffff00;
- MissionSoundEnvironmentManager * mng = GetManager();
- bool isParams = true;
- if(!params)
- {
- if(envName.NotEmpty())
- {
- isParams = false;
- }
- }
- bool isActive = false;
- if(mng && isParams)
- {
- if(mng->IsActive())
- {
- if(mng->IsActiveBox(this))
- {
- isActive = true;
- color = 0x00ff0fff;
- }
- }else{
- color = 0x00909090;
- }
- }else{
- color = 0x00ff0000;
- }
- Vector size = finder->GetBoxSize();
- size *= 0.5f;
- Render().DrawBox(-size, size, finder->GetMatrix(), color | 0xff000000);
- if(isActive)
- {
- Render().Print(50.0f, 130.0f, color | 0xff000000, "Environment box: %s, preset: %s", GetObjectID().c_str(), envName.c_str());
- }
- Render().Print(finder->GetMatrix().pos, 100.0f, 0.0f, color | 0xff000000, "%s", envName.c_str());
- }
- //Получить мэнеджер
- MissionSoundEnvironmentManager * MissionSoundEnvironment::GetManager()
- {
- MissionSoundEnvironmentManager * mng = null;
- MGIterator & it = GroupIterator(MG_SOUNDENVIRONMENT_MNG, _FL_);
- if(!it.IsDone())
- {
- mng = (MissionSoundEnvironmentManager *)it.Get();
- Assert(mng);
- }
- it.Release();
- return mng;
- }
- MOP_BEGINLISTCG(MissionSoundEnvironment, "Environment box", '1.00', 100, "Box volue trigger for sound environment preset", "Effects")
- MOP_STRINGC("Preset", "", "Environment preset defined in \"Environment manager\"")
- MOP_POSITION("Position", Vector(0.0f))
- MOP_ANGLES("Angles", Vector(0.0f))
- MOP_FLOATEX("Width", 10.0f, 1.0f, 1000000.0f)
- MOP_FLOATEX("Height", 10.0f, 1.0f, 1000000.0f)
- MOP_FLOATEX("Length", 10.0f, 1.0f, 1000000.0f)
- MOP_ENDLIST(MissionSoundEnvironment)
- //-------------------------------------------------------------------------------------------------------------
- //MissionSoundEnvironmentManager
- //-------------------------------------------------------------------------------------------------------------
- MissionSoundEnvironmentManager::MissionSoundEnvironmentManager() : boxes(_FL_)
- {
- Assert(ARRSIZE(evtNames) == ARRSIZE(envSetups));
- boxes.Reserve(64);
- Show(false);
- blendTime = 2.0f;
- memset(envSetups, 0, sizeof(envSetups));
- }
- //Текущий активный
- bool MissionSoundEnvironmentManager::IsActiveBox(MissionSoundEnvironment * se)
- {
- if(boxes.Size() > 0)
- {
- if(boxes[boxes.Size() - 1].env == se)
- {
- return true;
- }
- }
- return false;
- }
- //Найти пресет по имени
- ISoundScene::Enveronment * MissionSoundEnvironmentManager::FindPreset(const ConstString & name)
- {
- for(dword i = 0; i < ARRSIZE(evtNames); i++)
- {
- if(evtNames[i] == name)
- {
- return &envSetups[i];
- }
- }
- return null;
- }
- //Инициализировать объект
- bool MissionSoundEnvironmentManager::Create(MOPReader & reader)
- {
- if(!UniqueObjectCheck()) return false;
- SetUpdate(&MissionSoundEnvironmentManager::UpdateScene, ML_SCENE_END - 0xff);
- Init(reader);
- return true;
- }
- //Вызываеться, когда все объекты созданны но ещё не началось исполнение миссии
- void MissionSoundEnvironmentManager::PostCreate()
- {
- UpdateScene(0.0f, ML_FIRST);
- }
- //Активировать/деактивировать объект
- void MissionSoundEnvironmentManager::Activate(bool isActive)
- {
- MissionObject::Activate(isActive);
- }
- //Инициализировать объект
- bool MissionSoundEnvironmentManager::EditMode_Create(MOPReader & reader)
- {
- if(!UniqueObjectCheck()) return false;
- return EditMode_Update(reader);
- }
- //Обновить параметры
- bool MissionSoundEnvironmentManager::EditMode_Update(MOPReader & reader)
- {
- Init(reader);
- MGIterator & it = GroupIterator(MG_SOUNDENVIRONMENT, _FL_);
- for(; !it.IsDone(); it.Next())
- {
- MissionSoundEnvironment * menv = (MissionSoundEnvironment *)it.Get();
- menv->UpdateStates(this);
- }
- it.Release();
- return true;
- }
- //Проверить на единственную копию объекта
- bool MissionSoundEnvironmentManager::UniqueObjectCheck()
- {
- #ifndef STOP_DEBUG
- bool isAlone = true;
- MGIterator & it = GroupIterator(MG_SOUNDENVIRONMENT_MNG, _FL_);
- if(!it.IsDone())
- {
- if(it.Get() != this)
- {
- isAlone = false;
- }
- it.Next();
- if(!it.IsDone())
- {
- isAlone = false;
- }
- }
- it.Release();
- if(!isAlone)
- {
- LogicDebugError("This object can be only one in mission");
- return false;
- }
- return true;
- #else
- return true;
- #endif
- }
- //Общая инициализация
- void MissionSoundEnvironmentManager::Init(MOPReader & reader)
- {
- Registry(MG_SOUNDENVIRONMENT_MNG);
- blendTime = reader.Float();
- memset(envSetups, 0, sizeof(envSetups));
- long count = reader.Array();
- Assert(count <= ARRSIZE(envSetups));
- for(long i = 0; i < count; i++)
- {
- evtNames[i] = reader.String();
- envSetups[i].predelayTime = reader.Float();
- envSetups[i].earlyTime = reader.Float();
- envSetups[i].earlyAttenuation = reader.Float();
- envSetups[i].damping = reader.Float();
- envSetups[i].dispersion = reader.Float();
- envSetups[i].wet = reader.Float();
- envSetups[i].dry = reader.Float();
- envSetups[i].unuse = 0.0f;
- }
- Activate(reader.Bool());
- #ifndef STOP_DEBUG
- Show(reader.Bool());
- #else
- Show(false);
- #endif
- }
- //Посчитать текущий активный детектор
- void _cdecl MissionSoundEnvironmentManager::UpdateScene(float dltTime, long level)
- {
- //Получаем слушателя
- Sound().GetListenerMatrix(listener);
- //Обновляем список ящиков, в которые попал слушатель
- bool isChange = false;
- BoxesUnuse();
- dword count = QTFindObjects(MG_SOUNDENVIRONMENT, listener.pos, listener.pos);
- for(dword i = 0; i < count; i++)
- {
- IMissionQTObject * qtObj = QTGetObject(i);
- if(!qtObj) continue;
- Vector localPos = qtObj->GetMatrix().MulVertexByInverse(listener.pos);
- localPos *= 2.0f;
- const Vector & size = qtObj->GetBoxSize();
- if(localPos.x > size.x || localPos.x < -size.x) continue;
- if(localPos.z > size.z || localPos.z < -size.z) continue;
- if(localPos.y > size.y || localPos.y < -size.y) continue;
- //Добавляем-обновляем ящик в списке
- MissionSoundEnvironment & mse = (MissionSoundEnvironment &)qtObj->GetMissionObject();
- isChange |= BoxesUse(&mse);
- }
- isChange |= BoxesRemoveUnuse();
- float bTime = blendTime;
- #ifndef STOP_DEBUG
- if(IsShow())
- {
- if(api->DebugKeyState(VK_TAB))
- {
- boxes.Empty();
- bTime = 0.0f;
- Render().Print(50.0f, 130.0f, 0xffff00ff, "<TAB> disable environment effects");
- }
- }
- #endif
- //Однобоксовая версия
- if(isChange)
- {
- if(boxes.Size() > 0)
- {
- MissionSoundEnvironment * env = boxes[boxes.Size() - 1].env;
- ISoundScene::Enveronment result;
- if(env->ApplyParams(result))
- {
- Sound().SetSoundEnvironmentScene(&result, bTime);
- }
- }else{
- Sound().SetSoundEnvironmentScene(null, bTime);
- }
- }
- }
- //Сбросить состояние ящиков
- void MissionSoundEnvironmentManager::BoxesUnuse()
- {
- //Маркируем все ящики как необходимые удалить
- ActiveBox * bs = boxes.GetBuffer();
- dword count = boxes.Size();
- for(dword i = 0; i < count; i++)
- {
- bs[i].isUse = 0;
- }
- }
- //Устонавить состояние ящика в используемое
- bool MissionSoundEnvironmentManager::BoxesUse(MissionSoundEnvironment * env)
- {
- //Маркируем все ящики как необходимые удалить
- ActiveBox * bs = boxes.GetBuffer();
- dword count = boxes.Size();
- for(dword i = 0; i < count; i++)
- {
- if(bs[i].env == env)
- {
- bs[i].isUse = 1;
- return false;
- }
- }
- ActiveBox & newBox = boxes[boxes.Add()];
- newBox.env = env;
- newBox.isUse = 1;
- return true;
- }
- //Удалить неиспользуемые ящики
- bool MissionSoundEnvironmentManager::BoxesRemoveUnuse()
- {
- bool isChange = false;
- for(dword i = 0; i < boxes.Size(); )
- {
- if(boxes[i].isUse)
- {
- i++;
- }else{
- boxes.DelIndex(i);
- isChange = true;
- }
- }
- return isChange;
- }
- MOP_BEGINLISTCG(MissionSoundEnvironmentManager, "Environment manager", '1.00', 10, "Environment scene manager", "Effects")
- MOP_FLOATEXC("Blend time (s)", 0.2f, 0.0f, 10.0f, "Время изменения с текущих на новые параметры")
- MOP_ARRAYBEG("Setups", 0, 20)
- MOP_STRING("Name", "")
- MOP_FLOATEXC("Predelay (ms)", 20.0f, 0.0f, 500.0f, "Задержка до первого отражённого звука 0..500мс")
- MOP_FLOATEXC("Early time (ms)", 200.0f, 0.0f, 1000.0f, "Время всех вторичных отражений 0..1000мс")
- MOP_FLOATEXC("Early attenuation", 0.3f, 0.0f, 1.0f, "Коэфициент возвращения первичных отражений")
- MOP_FLOATEXC("Damping", 0.2f, 0.0f, 1.0f, "Поглощение средой высокочастотной составляющей (захламлёность)")
- MOP_FLOATEXC("Dispersion", 0.5f, 0.0f, 1.0f, "Степень рассеивания (мелкие предметы)")
- MOP_FLOATEXC("Wet", 0.5f, 0.0f, 1.0f, "Какая часть рассеяного звука попадает в выходной сигнал (0..1)")
- MOP_FLOATEXC("Dry", 1.0f, 0.0f, 1.0f, "Какая часть исходного звука попадает в выходной сигнал (0..1)")
- MOP_ARRAYEND
- MOP_BOOL("Active", true)
- MOP_BOOL("Draw boxes", false)
- MOP_ENDLIST(MissionSoundEnvironmentManager)
|