MissionVolumeSound.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "MissionVolumeSound.h"
  2. MissionVolumeSound::MissionVolumeSound()
  3. {
  4. radius = 0.0f;
  5. fadeDist2 = 0.0f;
  6. kFadeDist = 0.0f;
  7. flags = f_init;
  8. debug = null;
  9. }
  10. MissionVolumeSound::~MissionVolumeSound()
  11. {
  12. DELETE(debug);
  13. }
  14. //Инициализировать объект
  15. bool MissionVolumeSound::Create(MOPReader & reader)
  16. {
  17. flags = f_init;
  18. const char * figure = reader.Enum().c_str();
  19. Vector pos = reader.Position();
  20. connectToObject = reader.String();
  21. Vector ang = reader.Angles();
  22. size = reader.Position()*0.5f;
  23. radius = reader.Float();
  24. if(figure[0] == 'B' || figure[0] == 'b')
  25. {
  26. matrix.Build(ang, pos);
  27. radius = -1.0f;
  28. }else{
  29. matrix.SetIdentity();
  30. matrix.pos = pos;
  31. size = radius;
  32. flags |= f_isSphere;
  33. }
  34. bool is3D = (reader.Enum().c_str()[0] == '3');
  35. fadeDist2 = reader.Float();
  36. if(reader.Bool()) flags |= f_isManageByDist;
  37. if(is3D)
  38. {
  39. flags |= f_is3D;
  40. fadeDist2 *= fadeDist2;
  41. }else{
  42. Assert(fadeDist2 > 0.0f);
  43. kFadeDist = 1.0f/fadeDist2;
  44. fadeDist2 *= fadeDist2;
  45. flags |= f_isManageByDist;
  46. }
  47. bool res = CreateSounds(reader, is3D ? &matrix.pos : null);
  48. if(reader.Bool() && !EditMode_IsOn())
  49. {
  50. debug = NEW Debug();
  51. memset(debug, 0, sizeof(Debug));
  52. SetUpdate(&MissionVolumeSound::EditModeDraw, ML_POSTEFFECTS);
  53. }else{
  54. DELETE(debug);
  55. }
  56. return res;
  57. }
  58. //Вызываеться, когда все объекты созданны но ещё не началось исполнение миссии
  59. void MissionVolumeSound::PostCreate()
  60. {
  61. FindObject(connectToObject, objectPtr);
  62. }
  63. //Получить матрицу объекта
  64. Matrix & MissionVolumeSound::GetMatrix(Matrix & mtx)
  65. {
  66. Sound().GetListenerMatrix(mtx);
  67. Vector pos = mtx.pos;
  68. MissionObject * cmo = objectPtr.Ptr();
  69. if((flags & f_isSphere) == 0)
  70. {
  71. if(!cmo)
  72. {
  73. mtx = matrix;
  74. }else{
  75. cmo->GetMatrix(mtx);
  76. mtx = Matrix(matrix, mtx);
  77. }
  78. Vector local = mtx.MulVertexByInverse(pos);
  79. local.Max(local, -size);
  80. local.Min(local, size);
  81. mtx.pos = mtx.MulVertex(local);
  82. }else{
  83. Vector dir = mtx.pos - matrix.pos;
  84. if(cmo)
  85. {
  86. cmo->GetMatrix(mtx);
  87. dir -= mtx.pos;
  88. }
  89. dir.ClampLength(radius);
  90. mtx = matrix;
  91. mtx.pos += dir;
  92. }
  93. return mtx;
  94. }
  95. //Инициализировать объект
  96. bool MissionVolumeSound::EditMode_Create(MOPReader & reader)
  97. {
  98. SetUpdate(&MissionVolumeSound::EditModeDraw, ML_POSTEFFECTS - 1);
  99. Create(reader);
  100. return true;
  101. }
  102. //Обновить параметры
  103. bool MissionVolumeSound::EditMode_Update(MOPReader & reader)
  104. {
  105. Create(reader);
  106. return true;
  107. }
  108. //Получить размеры описывающего ящика
  109. void MissionVolumeSound::EditMode_GetSelectBox(Vector & min, Vector & max)
  110. {
  111. Matrix mtx;
  112. MissionObject * cmo = null;
  113. if(objectPtr.Validate())
  114. {
  115. cmo = objectPtr.Ptr();
  116. }
  117. if(cmo)
  118. {
  119. cmo->GetMatrix(mtx);
  120. mtx = Matrix(matrix, mtx);
  121. }else{
  122. mtx = matrix;
  123. }
  124. Matrix m;
  125. GetMatrix(m);
  126. min = m.MulVertexByInverse(-size*mtx);
  127. max = m.MulVertexByInverse(size*mtx);
  128. }
  129. //Рисование модельки в режиме редактирования
  130. void _cdecl MissionVolumeSound::EditModeDraw(float dltTime, long level)
  131. {
  132. if(EditMode_IsOn())
  133. {
  134. if(!EditMode_IsSelect()) return;
  135. if(!EditMode_IsVisible()) return;
  136. }
  137. objectPtr.Reset();
  138. if(connectToObject.NotEmpty())
  139. {
  140. FindObject(connectToObject, objectPtr);
  141. }
  142. Matrix mtx;
  143. bool isConnectActive = true;
  144. if(!objectPtr.Ptr())
  145. {
  146. mtx = matrix;
  147. }else{
  148. objectPtr.Ptr()->GetMatrix(mtx);
  149. mtx = Matrix(matrix, mtx);
  150. isConnectActive = objectPtr.Ptr()->IsShow();
  151. }
  152. if(flags & f_isSphere)
  153. {
  154. Render().DrawSphereGizmo(mtx.pos, radius, 0xff8080ff, 0xff8080ff);
  155. if(flags & f_isManageByDist)
  156. {
  157. Render().DrawSphereGizmo(mtx.pos, radius + sqrtf(fadeDist2), 0xff808080, 0xff808080);
  158. }
  159. }else{
  160. if(!EditMode_IsOn())
  161. {
  162. Render().DrawBox(-size, size, mtx, 0xff8080ff);
  163. }
  164. if(flags & f_isManageByDist)
  165. {
  166. float addSize = sqrtf(fadeDist2);
  167. Render().DrawBox(-size - Vector(addSize), size + Vector(addSize), mtx, 0xff8080ff);
  168. }
  169. }
  170. if(IsActive())
  171. {
  172. Vector pos = GetMatrix(Matrix()).pos;
  173. dword color = 0xff6060ff;
  174. if(debug)
  175. {
  176. pos = debug->sndPos;
  177. if(isConnectActive)
  178. {
  179. Render().DrawLine(debug->sndPos, color, debug->listPos, 0xffffffff);
  180. }
  181. if(debug->curVolume <= 1e-6f) color = 0xff606060;
  182. }
  183. Render().DrawSphere(pos, 0.2f, color);
  184. Render().Print(pos, 1000.0f, -1.1f, 0xffc0c0ff, "%s", GetObjectID().c_str());
  185. if(debug)
  186. {
  187. if(isConnectActive)
  188. {
  189. Render().Print(pos, 1000.0f, 0.0f, 0xffc0c0ff, "dist = %f", debug->dist);
  190. if(fadeDist2 > 0.0f)
  191. {
  192. Render().Print(pos, 1000.0f, 1.1f, 0xffc0c0ff, "vol = %f", debug->curVolume);
  193. }
  194. }else{
  195. Render().Print(pos, 1000.0f, 0.0f, 0xffc0c0c0, "Parent object: %s isn't visible", connectToObject.c_str());
  196. }
  197. }
  198. }else{
  199. Render().Print(mtx.pos, 1000.0f, -0.6f, 0xffc0c0ff, "%s", GetObjectID().c_str());
  200. Render().Print(mtx.pos, 1000.0f, 0.6f, 0xffc0c0ff, "not active");
  201. }
  202. }
  203. //Работа
  204. void _cdecl MissionVolumeSound::Work(float dltTime, long level)
  205. {
  206. if(objectPtr.Ptr())
  207. {
  208. if(!objectPtr.Ptr()->IsShow())
  209. {
  210. Fadeout();
  211. return;
  212. }
  213. }
  214. Vector pos = GetMatrix(Matrix()).pos;
  215. if((flags & f_isManageByDist) == 0)
  216. {
  217. UpdatePosition(pos);
  218. Update(dltTime);
  219. if(debug)
  220. {
  221. Matrix mtx;
  222. Sound().GetListenerMatrix(mtx);
  223. float dist2 = ~(mtx.pos - pos);
  224. debug->curVolume = 0.0f;
  225. debug->dist = sqrtf(dist2);
  226. debug->sndPos = pos;
  227. debug->listPos = mtx.pos;
  228. }
  229. }else{
  230. Matrix mtx;
  231. Sound().GetListenerMatrix(mtx);
  232. float dist2 = ~(mtx.pos - pos);
  233. float vol = 0.0f;
  234. if(dist2 < fadeDist2)
  235. {
  236. if((flags & f_is3D) == 0)
  237. {
  238. vol = 1.0f - sqrtf(dist2)*kFadeDist;
  239. vol *= vol;
  240. UpdateVolumes(vol);
  241. }else{
  242. UpdatePosition(pos);
  243. }
  244. Update(dltTime);
  245. }else{
  246. UpdatePosition(pos);
  247. Fadeout();
  248. }
  249. if(debug)
  250. {
  251. debug->curVolume = vol;
  252. debug->dist = sqrtf(dist2);
  253. debug->sndPos = pos;
  254. debug->listPos = mtx.pos;
  255. }
  256. }
  257. }
  258. //============================================================================================
  259. //Параметры инициализации
  260. //============================================================================================
  261. MOP_BEGINLISTG(MissionVolumeSound, "Volume sound", '1.00', 100, "Effects")
  262. MOP_ENUMBEG("Geometry")
  263. MOP_ENUMELEMENT("Box")
  264. MOP_ENUMELEMENT("Shpere")
  265. MOP_ENUMEND
  266. MOP_ENUMBEG("Mode")
  267. MOP_ENUMELEMENT("3D")
  268. MOP_ENUMELEMENT("stereo")
  269. MOP_ENUMEND
  270. MOP_ENUM("Geometry", "Figure")
  271. MOP_POSITIONC("Position", Vector(0.0f), "Figuge position in world")
  272. MOP_STRING("Connect to object", "")
  273. MOP_GROUPBEG("Box params")
  274. MOP_ANGLESC("Angles", Vector(0.0f), "Box orientation in world")
  275. MOP_POSITIONEXC("Size", Vector(1.0f), Vector(0.1f), Vector(10000.0f), "Box size")
  276. MOP_GROUPEND()
  277. MOP_GROUPBEG("Shpere params")
  278. MOP_FLOATEXC("Radius", 1.0f, 0.1f, 10000.0f, "Shpere radius")
  279. MOP_GROUPEND()
  280. MOP_ENUM("Mode", "Sound is")
  281. MOP_FLOATEXC("Fade distance", 10.0, 0.1f, 1000.0f, "Inside box stereo sound play with maximem volume,\noutside box volume of stereo sound fade in that distance")
  282. MOP_BOOLC("Manage 3D", false, "Manage 3D sound by fade distance")
  283. MISSION_SOUND_PARAMS
  284. MOP_BOOL("Debug", false)
  285. MOP_ENDLIST(MissionVolumeSound)