FreeCamera.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include "FreeCamera.h"
  2. //============================================================================================
  3. //FreeCameraModule
  4. //============================================================================================
  5. #define SENSITIVITY 0.1f
  6. #define FOV 1.285f
  7. INTERFACE_FUNCTION
  8. CREATE_CLASS(FreeCamera)
  9. FreeCameraModule::FreeCameraModule()
  10. {
  11. render = null;
  12. ctr = null;
  13. pos = Vector(0.0f, 9.0f, -5.0f);
  14. ang = Vector(0.0f, 0.0f, 0.0f);
  15. fov = FOV;
  16. }
  17. FreeCameraModule::~FreeCameraModule()
  18. {
  19. RELEASE(ctr);
  20. }
  21. bool FreeCameraModule::Init()
  22. {
  23. render = (IRender *)api->GetService("dx9render");
  24. Assert(render);
  25. IControlsService * ctrlsrv = (IControlsService *)api->GetService("ControlsService");
  26. Assert(ctrlsrv);
  27. ctr = ctrlsrv->CreateInstance(_FL_);
  28. Assert(ctr);
  29. return true;
  30. }
  31. //Перемещение камеры
  32. void FreeCameraModule::Move(float dltTime)
  33. {
  34. if(!ctr)
  35. {
  36. return;
  37. }
  38. //Ограничим временной отрезок
  39. if(dltTime > 0.1f) dltTime = 0.1f;
  40. //Углы
  41. ctrl = pref; ctrl += "FreeCamera_Turn_H";
  42. ang.y += ctr->GetControlStateFloat(ctrl) * 0.2f;
  43. ctrl = pref; ctrl += "FreeCamera_Turn_V";
  44. ang.x -= ctr->GetControlStateFloat(ctrl) * 0.2f;
  45. if(ang.x < -PI*0.5f) ang.x = -PI*0.5f;
  46. if(ang.x > PI*0.5f) ang.x = PI*0.5f;
  47. //Матрица направления
  48. Matrix mtx(ang);
  49. //Перемещение
  50. float speed = 5.0f*dltTime;
  51. ctrl = pref; ctrl += "FreeCamera_SpeedUp4x";
  52. if(ctr->GetControlStateType(ctrl) == CST_ACTIVE) speed *= 4.0f;
  53. ctrl = pref; ctrl += "FreeCamera_SpeedUp10x";
  54. if(ctr->GetControlStateType(ctrl) == CST_ACTIVE) speed *= 10.0f;
  55. ctrl = pref; ctrl += "FreeCamera_Forward";
  56. if(ctr->GetControlStateType(ctrl) == CST_ACTIVE)
  57. {
  58. pos += speed*mtx.vz;
  59. }
  60. ctrl = pref; ctrl += "FreeCamera_Back";
  61. if(ctr->GetControlStateType(ctrl) == CST_ACTIVE)
  62. {
  63. pos -= speed*mtx.vz;
  64. }
  65. ctrl = pref; ctrl += "FreeCamera_Left";
  66. if(ctr->GetControlStateType(ctrl) == CST_ACTIVE)
  67. {
  68. pos -= speed*mtx.vx;
  69. }
  70. ctrl = pref; ctrl += "FreeCamera_Right";
  71. if(ctr->GetControlStateType(ctrl) == CST_ACTIVE)
  72. {
  73. pos += speed*mtx.vx;
  74. }
  75. mtx.pos = pos;
  76. mtx.BuildViewFromObject();
  77. render->SetView(swing*mtx);
  78. render->SetPerspective(fov);
  79. }
  80. //Установить углы по точке
  81. bool FreeCameraModule::SetTarget(float x, float y, float z)
  82. {
  83. if(~(pos - Vector(x, y, z)) < 1e-10f) return false;
  84. Vector xz = Vector(x - pos.x, 0.0f, z - pos.z);
  85. ang.y = xz.GetAY();
  86. Vector yxz = Vector(pos.y - y, 0.0f, xz.GetLengthXZ());
  87. ang.x = yxz.GetAY();
  88. return true;
  89. }
  90. //============================================================================================
  91. //FreeCamera
  92. //============================================================================================
  93. FreeCamera::FreeCamera()
  94. {
  95. }
  96. FreeCamera::~FreeCamera()
  97. {
  98. camera.ctr->EnableControlGroup("FreeCamera", false);
  99. RELEASE(camera.ctr);
  100. }
  101. //Инициализация entity
  102. bool FreeCamera::Init()
  103. {
  104. if(!camera.Init())
  105. {
  106. return false;
  107. }
  108. camera.ctr->EnableControlGroup("FreeCamera", true);
  109. api->SetObjectExecution(this, "free camera", Core_DefaultExecuteLevel, &FreeCamera::Execute);
  110. api->SetGroupLevel("free camera", Core_DefaultExecuteLevel + 0x100);
  111. return true;
  112. }
  113. //Исполнение из слоя
  114. void __fastcall FreeCamera::Execute(float dltTime)
  115. {
  116. IMission * mis = (IMission *)api->FindObject("Mission");
  117. if(mis)
  118. {
  119. camera.swing = mis->GetSwingMatrix();
  120. }else{
  121. camera.swing.SetIdentity();
  122. }
  123. camera.Move(dltTime);
  124. }
  125. //Установить новую позицию камеры
  126. void FreeCamera::SetPosition(const Vector & pos)
  127. {
  128. camera.pos = pos;
  129. }
  130. //Получить позицию камеры
  131. Vector FreeCamera::GetPosition()
  132. {
  133. return camera.pos;
  134. }
  135. //Установить углы
  136. void FreeCamera::SetAngles(const Vector & ang)
  137. {
  138. camera.ang = ang;
  139. }
  140. //Получить углы
  141. Vector FreeCamera::GetAngles()
  142. {
  143. return camera.ang;
  144. }
  145. //Соориентировать камеру на точку
  146. void FreeCamera::SetTarget(const Vector & pos)
  147. {
  148. camera.SetTarget(pos.x, pos.y, pos.z);
  149. }
  150. //Установить угол обзора
  151. void FreeCamera::SetFOV(float fov)
  152. {
  153. camera.fov = fov;
  154. }
  155. //Получить угол обзора
  156. float FreeCamera::GetFOV()
  157. {
  158. return camera.fov;
  159. }
  160. //Приостановить работу камеры
  161. void FreeCamera::Pause(bool isPause)
  162. {
  163. if(!isPause)
  164. {
  165. api->SetObjectExecution(this, "free camera", Core_DefaultExecuteLevel, &FreeCamera::Execute);
  166. }else{
  167. api->DelObjectExecutions(this, "free camera");
  168. }
  169. }
  170. //============================================================================================
  171. //MissionFreeCamera
  172. //============================================================================================
  173. MissionFreeCamera::MissionFreeCamera()
  174. {
  175. model = null;
  176. }
  177. MissionFreeCamera::~MissionFreeCamera()
  178. {
  179. if(model) model->Release(); model = null;
  180. // camera.ctr->EnableControlGroup("mission.FreeCamera", false);
  181. Controls().EnableControlGroup("mission.FreeCamera", false);
  182. }
  183. //Инициализировать объект
  184. bool MissionFreeCamera::Create(MOPReader & reader)
  185. {
  186. if(!camera.Init()) return false;
  187. //api->Controls->EnableControlGroup("mission.FreeCamera", true);
  188. camera.ctr->EnableControlGroup("mission");
  189. camera.ctr->EnableControlGroup("mission.FreeCamera");
  190. camera.pref = "Mission";
  191. SetUpdate((MOF_UPDATE)&MissionFreeCamera::Work, ML_CAMERAMOVE_FREE);
  192. return EditMode_Update(reader);
  193. }
  194. //Получить матрицу объекта
  195. Matrix & MissionFreeCamera::GetMatrix(Matrix & mtx)
  196. {
  197. return mtx.Build(camera.ang, camera.pos);
  198. }
  199. //Инициализировать объект
  200. bool MissionFreeCamera::EditMode_Create(MOPReader & reader)
  201. {
  202. //Создаём модельку камеры
  203. IGMXService * geom = (IGMXService *)api->GetService ("GMXService");
  204. if(!geom) return false;
  205. model = geom->CreateGMX("editor\\CameraModel.gmx", &Mission().Animation(), &Mission().Particles(), &Mission().Sound());
  206. SetUpdate((MOF_UPDATE)&MissionFreeCamera::EditModeWork, ML_GEOMETRY1);
  207. return EditMode_Update(reader);
  208. }
  209. //Обновить параметры
  210. bool MissionFreeCamera::EditMode_Update(MOPReader & reader)
  211. {
  212. camera.pos = reader.Position();
  213. camera.ang = reader.Angles();
  214. camera.fov = reader.Float()*(PI/180.0f);
  215. Activate(reader.Bool());
  216. return true;
  217. }
  218. //Получить размеры описывающего ящика
  219. void MissionFreeCamera::EditMode_GetSelectBox(Vector & min, Vector & max)
  220. {
  221. if(model)
  222. {
  223. min = model->GetLocalBound().vMin - 0.1f;
  224. max = model->GetLocalBound().vMax + 0.1f;
  225. return;
  226. }
  227. min = -0.3f;
  228. max = 0.3f;
  229. }
  230. //Работа
  231. void _cdecl MissionFreeCamera::Work(float dltTime, long level)
  232. {
  233. if(!IsActive()) return;
  234. dltTime = api->GetNoScaleDeltaTime();
  235. camera.swing = Mission().GetSwingMatrix();
  236. camera.Move(dltTime);
  237. }
  238. //Работа в режиме редактирования
  239. void _cdecl MissionFreeCamera::EditModeWork(float dltTime, long level)
  240. {
  241. if (!Mission().EditMode_IsAdditionalDraw()) return;
  242. if(model)
  243. {
  244. model->SetTransform(Matrix(camera.ang, camera.pos));
  245. model->Draw();
  246. }
  247. }
  248. MOP_BEGINLISTG(MissionFreeCamera, "Free camera", '1.00', 0, "Cameras")
  249. MOP_POSITIONC("Start position", Vector(0.0f, 5.0f, -5.0f), "Position in start mission moment")
  250. 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")
  251. MOP_FLOATEXC("Camera FOV", 1.25f*180.0f/PI, 10.0f, 140.0f, "Camera frustum angle in degrees")
  252. MOP_BOOLC("Active", true, "Active camera in start mission time")
  253. MOP_ENDLIST(MissionFreeCamera)