| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- #include "FreeCamera.h"
- //============================================================================================
- //FreeCameraModule
- //============================================================================================
- #define SENSITIVITY 0.1f
- #define FOV 1.285f
- INTERFACE_FUNCTION
- CREATE_CLASS(FreeCamera)
- FreeCameraModule::FreeCameraModule()
- {
- render = null;
- ctr = null;
- pos = Vector(0.0f, 9.0f, -5.0f);
- ang = Vector(0.0f, 0.0f, 0.0f);
- fov = FOV;
- }
- FreeCameraModule::~FreeCameraModule()
- {
- RELEASE(ctr);
- }
- bool FreeCameraModule::Init()
- {
- render = (IRender *)api->GetService("dx9render");
- Assert(render);
- IControlsService * ctrlsrv = (IControlsService *)api->GetService("ControlsService");
- Assert(ctrlsrv);
- ctr = ctrlsrv->CreateInstance(_FL_);
- Assert(ctr);
- return true;
- }
- //Перемещение камеры
- void FreeCameraModule::Move(float dltTime)
- {
- if(!ctr)
- {
- return;
- }
- //Ограничим временной отрезок
- if(dltTime > 0.1f) dltTime = 0.1f;
- //Углы
- ctrl = pref; ctrl += "FreeCamera_Turn_H";
- ang.y += ctr->GetControlStateFloat(ctrl) * 0.2f;
- ctrl = pref; ctrl += "FreeCamera_Turn_V";
- ang.x -= ctr->GetControlStateFloat(ctrl) * 0.2f;
- if(ang.x < -PI*0.5f) ang.x = -PI*0.5f;
- if(ang.x > PI*0.5f) ang.x = PI*0.5f;
- //Матрица направления
- Matrix mtx(ang);
- //Перемещение
- float speed = 5.0f*dltTime;
- ctrl = pref; ctrl += "FreeCamera_SpeedUp4x";
- if(ctr->GetControlStateType(ctrl) == CST_ACTIVE) speed *= 4.0f;
- ctrl = pref; ctrl += "FreeCamera_SpeedUp10x";
- if(ctr->GetControlStateType(ctrl) == CST_ACTIVE) speed *= 10.0f;
- ctrl = pref; ctrl += "FreeCamera_Forward";
- if(ctr->GetControlStateType(ctrl) == CST_ACTIVE)
- {
- pos += speed*mtx.vz;
- }
- ctrl = pref; ctrl += "FreeCamera_Back";
- if(ctr->GetControlStateType(ctrl) == CST_ACTIVE)
- {
- pos -= speed*mtx.vz;
- }
- ctrl = pref; ctrl += "FreeCamera_Left";
- if(ctr->GetControlStateType(ctrl) == CST_ACTIVE)
- {
- pos -= speed*mtx.vx;
- }
- ctrl = pref; ctrl += "FreeCamera_Right";
- if(ctr->GetControlStateType(ctrl) == CST_ACTIVE)
- {
- pos += speed*mtx.vx;
- }
- mtx.pos = pos;
- mtx.BuildViewFromObject();
- render->SetView(swing*mtx);
- render->SetPerspective(fov);
- }
- //Установить углы по точке
- bool FreeCameraModule::SetTarget(float x, float y, float z)
- {
- if(~(pos - Vector(x, y, z)) < 1e-10f) return false;
- Vector xz = Vector(x - pos.x, 0.0f, z - pos.z);
- ang.y = xz.GetAY();
- Vector yxz = Vector(pos.y - y, 0.0f, xz.GetLengthXZ());
- ang.x = yxz.GetAY();
- return true;
- }
- //============================================================================================
- //FreeCamera
- //============================================================================================
- FreeCamera::FreeCamera()
- {
- }
- FreeCamera::~FreeCamera()
- {
- camera.ctr->EnableControlGroup("FreeCamera", false);
- RELEASE(camera.ctr);
- }
- //Инициализация entity
- bool FreeCamera::Init()
- {
- if(!camera.Init())
- {
- return false;
- }
- camera.ctr->EnableControlGroup("FreeCamera", true);
- api->SetObjectExecution(this, "free camera", Core_DefaultExecuteLevel, &FreeCamera::Execute);
- api->SetGroupLevel("free camera", Core_DefaultExecuteLevel + 0x100);
- return true;
- }
- //Исполнение из слоя
- void __fastcall FreeCamera::Execute(float dltTime)
- {
- IMission * mis = (IMission *)api->FindObject("Mission");
- if(mis)
- {
- camera.swing = mis->GetSwingMatrix();
- }else{
- camera.swing.SetIdentity();
- }
- camera.Move(dltTime);
- }
- //Установить новую позицию камеры
- void FreeCamera::SetPosition(const Vector & pos)
- {
- camera.pos = pos;
- }
- //Получить позицию камеры
- Vector FreeCamera::GetPosition()
- {
- return camera.pos;
- }
- //Установить углы
- void FreeCamera::SetAngles(const Vector & ang)
- {
- camera.ang = ang;
- }
- //Получить углы
- Vector FreeCamera::GetAngles()
- {
- return camera.ang;
- }
- //Соориентировать камеру на точку
- void FreeCamera::SetTarget(const Vector & pos)
- {
- camera.SetTarget(pos.x, pos.y, pos.z);
- }
- //Установить угол обзора
- void FreeCamera::SetFOV(float fov)
- {
- camera.fov = fov;
- }
- //Получить угол обзора
- float FreeCamera::GetFOV()
- {
- return camera.fov;
- }
- //Приостановить работу камеры
- void FreeCamera::Pause(bool isPause)
- {
- if(!isPause)
- {
- api->SetObjectExecution(this, "free camera", Core_DefaultExecuteLevel, &FreeCamera::Execute);
- }else{
- api->DelObjectExecutions(this, "free camera");
- }
- }
- //============================================================================================
- //MissionFreeCamera
- //============================================================================================
- MissionFreeCamera::MissionFreeCamera()
- {
- model = null;
- }
- MissionFreeCamera::~MissionFreeCamera()
- {
- if(model) model->Release(); model = null;
- // camera.ctr->EnableControlGroup("mission.FreeCamera", false);
- Controls().EnableControlGroup("mission.FreeCamera", false);
- }
- //Инициализировать объект
- bool MissionFreeCamera::Create(MOPReader & reader)
- {
- if(!camera.Init()) return false;
- //api->Controls->EnableControlGroup("mission.FreeCamera", true);
- camera.ctr->EnableControlGroup("mission");
- camera.ctr->EnableControlGroup("mission.FreeCamera");
- camera.pref = "Mission";
-
- SetUpdate((MOF_UPDATE)&MissionFreeCamera::Work, ML_CAMERAMOVE_FREE);
- return EditMode_Update(reader);
- }
- //Получить матрицу объекта
- Matrix & MissionFreeCamera::GetMatrix(Matrix & mtx)
- {
- return mtx.Build(camera.ang, camera.pos);
- }
- //Инициализировать объект
- bool MissionFreeCamera::EditMode_Create(MOPReader & reader)
- {
- //Создаём модельку камеры
- IGMXService * geom = (IGMXService *)api->GetService ("GMXService");
- if(!geom) return false;
- model = geom->CreateGMX("editor\\CameraModel.gmx", &Mission().Animation(), &Mission().Particles(), &Mission().Sound());
- SetUpdate((MOF_UPDATE)&MissionFreeCamera::EditModeWork, ML_GEOMETRY1);
- return EditMode_Update(reader);
- }
- //Обновить параметры
- bool MissionFreeCamera::EditMode_Update(MOPReader & reader)
- {
- camera.pos = reader.Position();
- camera.ang = reader.Angles();
- camera.fov = reader.Float()*(PI/180.0f);
- Activate(reader.Bool());
- return true;
- }
- //Получить размеры описывающего ящика
- void MissionFreeCamera::EditMode_GetSelectBox(Vector & min, Vector & max)
- {
- if(model)
- {
- min = model->GetLocalBound().vMin - 0.1f;
- max = model->GetLocalBound().vMax + 0.1f;
- return;
- }
- min = -0.3f;
- max = 0.3f;
- }
- //Работа
- void _cdecl MissionFreeCamera::Work(float dltTime, long level)
- {
- if(!IsActive()) return;
- dltTime = api->GetNoScaleDeltaTime();
- camera.swing = Mission().GetSwingMatrix();
- camera.Move(dltTime);
- }
- //Работа в режиме редактирования
- void _cdecl MissionFreeCamera::EditModeWork(float dltTime, long level)
- {
- if (!Mission().EditMode_IsAdditionalDraw()) return;
- if(model)
- {
- model->SetTransform(Matrix(camera.ang, camera.pos));
- model->Draw();
- }
- }
- MOP_BEGINLISTG(MissionFreeCamera, "Free camera", '1.00', 0, "Cameras")
- MOP_POSITIONC("Start position", Vector(0.0f, 5.0f, -5.0f), "Position in start mission moment")
- MOP_ANGLESEXC("Start angles", Vector(0.6f, 0.0f, 0.0f), Vector(-0.49f*PI, -6*PI, 0.0f), Vector(0.49f*PI, 6*PI, 0.0f), "Orientation in start mission moment")
- MOP_FLOATEXC("Camera FOV", 1.25f*180.0f/PI, 10.0f, 140.0f, "Camera frustum angle in degrees")
- MOP_BOOLC("Active", true, "Active camera in start mission time")
- MOP_ENDLIST(MissionFreeCamera)
|