weaponliftdiag.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. #ifdef DIAG_DEVELOPER
  2. #ifndef SERVER
  3. //----------------------------------------------------------------------------------------
  4. //!
  5. class WeaponLiftDiagData
  6. {
  7. vector m_Transform[4];
  8. vector m_Start;
  9. vector m_Direction;
  10. float m_WeaponStartDist
  11. float m_WeaponEndDist;
  12. float m_EffectiveAttachmentLength;
  13. float m_ObstructionDistanceCfg;
  14. float m_ObstructionDistance;
  15. float m_RayRadius;
  16. float m_RayRadiusOverride;
  17. ref RaycastRVResult m_RayResult;
  18. float m_HitFraction;
  19. float m_HitDistance;
  20. vector m_LastPosition;
  21. float m_InterpInTime;
  22. float m_InterpInTimeLift;
  23. float m_InterpOutTime;
  24. float m_InterpCurrTime;
  25. float m_InterpCurrValue;
  26. float m_InterpTgtValue;
  27. float m_InterpSmoothValue;
  28. float m_AimUD;
  29. float m_AimLR;
  30. float m_AimUD11;
  31. float m_AimLR11;
  32. //!
  33. void SetTransform(vector transform[4])
  34. {
  35. for (int i = 0; i < 4; ++i) m_Transform[i] = transform[i];
  36. }
  37. //!
  38. void SetAimAngles(float udAngle, float lrAngle, float udAngle11, float lrAngle11)
  39. {
  40. m_AimUD = udAngle;
  41. m_AimLR = lrAngle;
  42. m_AimUD11 = udAngle11;
  43. m_AimLR11 = lrAngle11;
  44. }
  45. //!
  46. void SetWeaponRayParams(vector rayOrigin, vector rayDirection, float weaponStartDist, float weaponEndDist, float effectiveAttachmentLength, float obstructionDistanceCfg, float obstructionDistance, float rayRadius)
  47. {
  48. m_Start = rayOrigin;
  49. m_Direction = rayDirection;
  50. m_WeaponStartDist = weaponStartDist;
  51. m_WeaponEndDist = weaponEndDist;
  52. m_EffectiveAttachmentLength = effectiveAttachmentLength;
  53. m_ObstructionDistanceCfg = obstructionDistanceCfg;
  54. m_ObstructionDistance = obstructionDistance;
  55. m_RayRadius = rayRadius;
  56. }
  57. //!
  58. void SetIntersectionParams(RaycastRVResult rayResult, float hitFraction = 0, float hitDistance = 0)
  59. {
  60. m_RayResult = rayResult;
  61. m_HitFraction = hitFraction;
  62. m_HitDistance = hitDistance;
  63. }
  64. //!
  65. void SetLastPosition(vector lastPosition)
  66. {
  67. m_LastPosition = lastPosition;
  68. }
  69. //!
  70. void SetInterpolation(float inTime, float inTimeLift, float outTime, float currentTime, float smoothValue, float currentValue, float targetValue)
  71. {
  72. m_InterpInTime = inTime;
  73. m_InterpInTimeLift = inTimeLift;
  74. m_InterpOutTime = outTime;
  75. m_InterpCurrTime = currentTime;
  76. m_InterpSmoothValue = smoothValue;
  77. m_InterpCurrValue = currentValue;
  78. m_InterpTgtValue = targetValue;
  79. }
  80. //!
  81. void Clear()
  82. {
  83. Math3D.MatrixIdentity4(m_Transform);
  84. SetIntersectionParams(null, 0, 0);
  85. SetWeaponRayParams(vector.Zero, vector.Zero, 0, 0, 0, 0, 0, 0);
  86. SetLastPosition(vector.Zero);
  87. SetInterpolation(0,0,0,0,0,0,0);
  88. SetAimAngles(0,0,0,0);
  89. }
  90. }
  91. //----------------------------------------------------------------------------------------
  92. //!
  93. class WeaponLiftDiag
  94. {
  95. private ref WeaponLiftDiagData m_Data = new WeaponLiftDiagData();
  96. private const int COLOR_START = 0xFF2ECC71; // Green
  97. private const int COLOR_END = 0xFF4B77BE; // Blue
  98. private const int COLOR_END_NOATTACH = 0xFFF7CA18; // Yellow
  99. private const int COLOR_OBSTRUCTION = 0xFFFF00FF; // Pink
  100. private const int COLOR_HIT = 0xFFFF0000; // Red
  101. private const int COLOR_GUIDE = 0xC03A3A3A; // Semi-transparent gray
  102. private const int COLOR_WEAPON = 0x1FFFFFFF; // Semi-transparent white
  103. private const int COLOR_LAST_POS = 0x3AF7CA18; // Semi-transparent yellow
  104. private bool m_bDrawGizmos = true;
  105. private bool m_bDrawTransform = false;
  106. private bool m_bSmallShapes = false;
  107. private bool m_bZBuffer = false;
  108. private bool m_bWireOnly = true;
  109. private bool m_bForceRaised = false;
  110. private int m_iColorCrosshair= false;
  111. private int m_iCrosshairR = 255;
  112. private int m_iCrosshairG = 0;
  113. private int m_iCrosshairB = 0;
  114. private int m_iCrosshairA = 255;
  115. private float m_fCrosshairBlendPow = 1;
  116. //----------------------------------------------------------------------------------------
  117. WeaponLiftDiagData Data()
  118. {
  119. return m_Data;
  120. }
  121. //----------------------------------------------------------------------------------------
  122. void Reset()
  123. {
  124. m_Data.Clear();
  125. }
  126. //----------------------------------------------------------------------------------------
  127. void DrawDiag(int mode, float deltaTime)
  128. {
  129. const int MODE_BASIC = 1;
  130. const int MODE_EXTENDED = 2;
  131. bool wasColoringCrosshair = m_iColorCrosshair;
  132. WeaponLiftDiagData data = m_Data;
  133. if (data)
  134. {
  135. /// TITLE
  136. DbgUI.Begin("Weapon Lift/Obstruction Diag");
  137. {
  138. /// WEAPON PROPERTIES
  139. int gray = 0x80FFFFFF; // semi transparent white (gray)
  140. int darkObst = gray&COLOR_OBSTRUCTION;
  141. int endNoAttachCol = gray & COLOR_END_NOATTACH;
  142. DbgUI.ColoredText(COLOR_WHITE, "Weapon properties");
  143. DbgUI.ColoredText(COLOR_START, " weaponStartDist: " + data.m_WeaponStartDist);
  144. DbgUI.ColoredText(COLOR_WHITE, " weaponLength: " + (data.m_WeaponEndDist - data.m_WeaponStartDist));
  145. DbgUI.ColoredText(COLOR_END, " weaponEndDist: " + data.m_WeaponEndDist);
  146. if (data.m_EffectiveAttachmentLength > 0)
  147. {
  148. DbgUI.ColoredText(gray, " attachmentLength: " + data.m_EffectiveAttachmentLength);
  149. DbgUI.ColoredText(endNoAttachCol, " distNoAttachment: " + (data.m_WeaponEndDist-data.m_EffectiveAttachmentLength));
  150. }
  151. DbgUI.ColoredText(COLOR_OBSTRUCTION, " obstructionDist(cfg): " + data.m_ObstructionDistanceCfg);
  152. if (DbgUI.FloatOverride("weaponObstruction", data.m_ObstructionDistance, 0.0, data.m_WeaponEndDist - data.m_EffectiveAttachmentLength))
  153. {
  154. data.m_ObstructionDistance += data.m_EffectiveAttachmentLength; // value was overriden directly, take attachment into account
  155. }
  156. DbgUI.ColoredText(darkObst, " obstructionDist(act): " + data.m_ObstructionDistance);
  157. DbgUI.ColoredText(COLOR_HIT, " hitDistance: " + data.m_HitDistance);
  158. DbgUI.PushID_Str("rayRadiusText");
  159. DbgUI.ColoredText(0xFFAAAAAA, " rayRadius: " + data.m_RayRadius );
  160. DbgUI.SameSpot();
  161. DbgUI.Text( " "); // ugly, but prevents some layouting spasms
  162. DbgUI.PopID();
  163. float rayRadius = data.m_RayRadius;
  164. if (DbgUI.FloatOverride("rayRadiusOverride", rayRadius, 0.0, 0.200, 1000))
  165. {
  166. data.m_RayRadiusOverride = rayRadius;
  167. }
  168. else
  169. {
  170. data.m_RayRadiusOverride = rayRadius;
  171. }
  172. /// !WEAPON PROPERTIES
  173. /// UTILITY
  174. DbgUI.Spacer(10);
  175. DbgUI.ColoredText(COLOR_WHITE, "Utility");
  176. DbgUI.Check("Force raised", m_bForceRaised);
  177. TStringArray crossMode = { "Off", "On Obstruction", "On Lift", "On Both (Blend)" };
  178. DbgUI.Combo("Color crosshair", m_iColorCrosshair, crossMode);
  179. /// !UTILITY
  180. /// CROSSHAIR COLOR
  181. if (m_iColorCrosshair)
  182. {
  183. DbgUI.SameLine();
  184. float r = m_iCrosshairR;
  185. float g = m_iCrosshairG;
  186. float b = m_iCrosshairB;
  187. float a = m_iCrosshairA;
  188. DbgUI.ColoredText(ARGB(m_iCrosshairA, m_iCrosshairR, m_iCrosshairG, m_iCrosshairB), " -|-");
  189. //R
  190. DbgUI.SliderFloat("Red: ", r, 0, 255);
  191. DbgUI.SameLine();
  192. DbgUI.PushID_Str("ObstructionDiagColorR");
  193. DbgUI.ColoredText(0xFFFF0000, m_iCrosshairR.ToString());
  194. DbgUI.PopID();
  195. //G
  196. DbgUI.SliderFloat("Green: ", g, 0, 255);
  197. DbgUI.SameLine();
  198. DbgUI.PushID_Str("ObstructionDiagColorG");
  199. DbgUI.ColoredText(0xFF00FF00, m_iCrosshairG.ToString());
  200. DbgUI.PopID();
  201. //B
  202. DbgUI.SliderFloat("Blue: ", b, 0, 255);
  203. DbgUI.SameLine();
  204. DbgUI.PushID_Str("ObstructionDiagColorB");
  205. DbgUI.ColoredText(0xFF0000FF, m_iCrosshairB.ToString());
  206. DbgUI.PopID();
  207. // A
  208. DbgUI.SliderFloat("Alpha: ", a, 0, 255);
  209. DbgUI.SameLine();
  210. DbgUI.PushID_Str("ObstructionDiagColorA");
  211. DbgUI.ColoredText(0xAAFFFFFF, m_iCrosshairA.ToString());
  212. DbgUI.PopID();
  213. m_iCrosshairR = r;
  214. m_iCrosshairG = g;
  215. m_iCrosshairB = b;
  216. m_iCrosshairA = a;
  217. float pow = m_fCrosshairBlendPow * 5000;
  218. DbgUI.SliderFloat("BlendPow: ", pow, 1, 5000);
  219. DbgUI.SameLine();
  220. pow = pow / 1000.0;
  221. DbgUI.Text(pow.ToString());
  222. m_fCrosshairBlendPow = pow;
  223. }
  224. ///! CROSSHAIR COLOR
  225. /// INTERSECTIONS
  226. if (mode > MODE_BASIC)
  227. {
  228. DbgUI.Spacer(10);
  229. DbgUI.ColoredText(COLOR_WHITE, "Intersection data");
  230. if (data.m_RayResult && data.m_RayResult.surface)
  231. {
  232. DbgUI.Text(" Name: " + data.m_RayResult.surface.GetName());
  233. DbgUI.Text(" EntryName: " + data.m_RayResult.surface.GetEntryName());
  234. DbgUI.Text(" SurfaceType: " + data.m_RayResult.surface.GetSurfaceType());
  235. DbgUI.Text(" IsPassThrough: " + data.m_RayResult.surface.IsPassthrough());
  236. DbgUI.Text(" IsSolid: " + data.m_RayResult.surface.IsSolid());
  237. DbgUI.Text(" HitFraction: " + data.m_HitFraction);
  238. }
  239. else
  240. {
  241. DbgUI.Text(" Name: - " );
  242. DbgUI.Text(" EntryName: - " );
  243. DbgUI.Text(" SurfaceType: - " );
  244. DbgUI.Text(" IsPassThrough: - " );
  245. DbgUI.Text(" IsSolid: - " );
  246. DbgUI.Text(" HitFraction: - " );
  247. }
  248. }
  249. ///! INTERSECTIONS
  250. /// INTERPOLATION
  251. if (mode > MODE_BASIC)
  252. {
  253. DbgUI.Spacer(10);
  254. DbgUI.ColoredText(COLOR_WHITE, "Interpolation");
  255. DbgUI.Text(" In time: " + data.m_InterpInTime);
  256. DbgUI.Text(" In time lift: " + data.m_InterpInTimeLift);
  257. DbgUI.Text(" Out time: " + data.m_InterpOutTime);
  258. DbgUI.Text(" Current time: " + data.m_InterpCurrTime);
  259. DbgUI.Text(" Actual value: " + data.m_InterpCurrValue);
  260. DbgUI.Text(" Target value: " + data.m_InterpTgtValue);
  261. DbgUI.Text(" Smooth value: " + data.m_InterpSmoothValue);
  262. }
  263. ///! INTERPOLATION
  264. /// AIMING
  265. if (mode > MODE_BASIC)
  266. {
  267. DbgUI.Spacer(10);
  268. DbgUI.ColoredText(COLOR_WHITE, "Aiming");
  269. DbgUI.ColoredText(0xFF80FF80, " UD Angle: " + data.m_AimUD);
  270. DbgUI.ColoredText(0xFFAAFFAA, " UD[-1,1]: " + data.m_AimUD11);
  271. DbgUI.ColoredText(0xFFFF8080, " LR Angle: " + data.m_AimLR);
  272. DbgUI.ColoredText(0xFFFFAAAA, " LR[-1,1]: " + data.m_AimLR11);
  273. }
  274. ///! AIMING
  275. /// SHAPE PREFERENCES
  276. if (mode > MODE_BASIC)
  277. {
  278. DbgUI.Spacer(10);
  279. DbgUI.ColoredText(COLOR_WHITE, "Preferences");
  280. DbgUI.Check(" Draw shapes", m_bDrawGizmos);
  281. DbgUI.Check(" Small shapes", m_bSmallShapes);
  282. DbgUI.Check(" Z-buffer", m_bZBuffer);
  283. DbgUI.Check(" Draw approx transform", m_bDrawTransform);
  284. DbgUI.Check(" Wire only", m_bWireOnly);
  285. }
  286. ///! SHAPE PREFERENCES
  287. /// CFGGAMEPLAY
  288. if (mode >= MODE_BASIC)
  289. {
  290. DbgUI.ColoredText(COLOR_WHITE, "CfgGameplay WeaponObstructionData");
  291. DbgUI.Text(" Static: " + EnumTools.EnumToString(EWeaponObstructionMode, CfgGameplayHandler.GetWeaponObstructionModeStatic()));
  292. DbgUI.Text(" Dynamic: " + EnumTools.EnumToString(EWeaponObstructionMode, CfgGameplayHandler.GetWeaponObstructionModeDynamic()));
  293. }
  294. ///! SHAPE PREFERENCES
  295. }
  296. DbgUI.End();
  297. // Override input! Extremely helpful!!
  298. if (m_bForceRaised && GetGame().GetPlayer())
  299. {
  300. DayZPlayer ply = GetGame().GetPlayer();
  301. HumanInputController hic = ply.GetInputController();
  302. hic.OverrideRaise( HumanInputControllerOverrideType.ONE_FRAME, true );
  303. }
  304. float radius = rayRadius;
  305. if (m_bSmallShapes) radius = 0.01;
  306. // gizmos
  307. if (m_bDrawTransform) Shape.CreateMatrix(data.m_Transform, 1.0, 0.05);
  308. // "Apply" settings
  309. ShapeFlags flags = ShapeFlags.ONCE | ShapeFlags.TRANSP;
  310. ShapeFlags flags2 = ShapeFlags.ONCE | ShapeFlags.TRANSP | ShapeFlags.NOOUTLINE;
  311. if (!m_bZBuffer)
  312. {
  313. flags |= ShapeFlags.NOZBUFFER;
  314. flags2 |= ShapeFlags.NOZBUFFER;
  315. }
  316. if (m_bWireOnly)
  317. {
  318. flags |= ShapeFlags.WIREFRAME;
  319. }
  320. else
  321. {
  322. flags |= ShapeFlags.NOOUTLINE;
  323. }
  324. vector wepStart = data.m_Start + (data.m_WeaponStartDist * data.m_Direction);
  325. vector wepEnd = data.m_Start + (data.m_WeaponEndDist * data.m_Direction);
  326. vector wepEndNoAttach = data.m_Start + ((data.m_WeaponEndDist - data.m_EffectiveAttachmentLength) * data.m_Direction);
  327. if (m_bDrawGizmos)
  328. {
  329. // Draw "guide" line, start->end
  330. Shape.Create(ShapeType.LINE, COLOR_GUIDE, flags2, data.m_Start, wepEnd);
  331. // Draw weapon points
  332. Shape.CreateSphere(COLOR_START, flags, wepStart, radius);
  333. Shape.CreateSphere(COLOR_END_NOATTACH, flags, wepEndNoAttach, radius);
  334. Shape.CreateSphere(COLOR_END, flags, wepEnd, radius);
  335. // Draw obstruction distance point
  336. if (data.m_ObstructionDistance != 0)
  337. {
  338. vector wepObstr = data.m_Start + (data.m_ObstructionDistance * data.m_Direction);
  339. Shape.CreateSphere(COLOR_OBSTRUCTION, flags, wepObstr, radius);
  340. }
  341. // Draw last hit position (in ext. mode)
  342. if (mode >= MODE_EXTENDED && data.m_LastPosition != vector.Zero)
  343. {
  344. Shape.Create(ShapeType.LINE, COLOR_LAST_POS, flags2, data.m_Start, data.m_LastPosition);
  345. }
  346. // Draw the weapon as it moves (a that slides along the "guide" line)
  347. {
  348. float cylinderLength = (wepEnd - wepStart).Length();
  349. vector cylinderOffset = 0.5 * cylinderLength * data.m_Transform[2];
  350. Shape cylinder = Shape.CreateCylinder(COLOR_WHITE, flags2, vector.Zero, 0.3 * radius, cylinderLength);
  351. vector tm0[4], tm1[3];
  352. Math3D.DirectionAndUpMatrix(data.m_Transform[2], data.m_Transform[1], tm0);
  353. Math3D.YawPitchRollMatrix("90 0 90", tm1);
  354. Math3D.MatrixMultiply3(tm0, tm1, tm0);
  355. float fraction = Math.Clamp(data.m_HitFraction, 0, 1);
  356. if (!data.m_RayResult) fraction = 1.0;
  357. vector center = (data.m_Start + (fraction * (wepEnd - data.m_Start))) - cylinderOffset;
  358. tm0[3] = center;
  359. cylinder.SetMatrix(tm0);
  360. }
  361. // Draw hit
  362. if (data.m_RayResult)
  363. {
  364. Shape.CreateSphere(COLOR_HIT, flags, data.m_RayResult.pos, 0.5 * radius);
  365. }
  366. }
  367. if (m_iColorCrosshair || wasColoringCrosshair)
  368. {
  369. int crossColor = 0xFFFFFFFF;
  370. if (m_iColorCrosshair) // only set if not "restoring"
  371. {
  372. if (m_iColorCrosshair == 1) // obstruction
  373. {
  374. float hitFraction = Data().m_HitFraction;
  375. if (hitFraction != 0 && hitFraction < 1.0)
  376. {
  377. crossColor = ARGB(m_iCrosshairA, m_iCrosshairR, m_iCrosshairG, m_iCrosshairB);
  378. }
  379. }
  380. else if (m_iColorCrosshair == 2) // lift only
  381. {
  382. float hitDist = Data().m_HitDistance;
  383. float obstDist = Data().m_ObstructionDistance;
  384. if (hitDist != 0 && hitDist < obstDist)
  385. {
  386. crossColor = ARGB(m_iCrosshairA, m_iCrosshairR, m_iCrosshairG, m_iCrosshairB);
  387. }
  388. }
  389. else if (m_iColorCrosshair == 3) // magic
  390. {
  391. float t = 0.0;
  392. if (Data().m_HitFraction != 0)
  393. {
  394. float fr = 1.0-Math.InverseLerp( Data().m_ObstructionDistance, Data().m_WeaponEndDist, Data().m_HitDistance );
  395. t = Math.Clamp( fr, 0.0, 1.0 );
  396. t = Math.Pow(t, m_fCrosshairBlendPow);
  397. }
  398. int white=0xFF;
  399. int bA = Math.Lerp(white, m_iCrosshairA, t);
  400. int bR = Math.Lerp(white, m_iCrosshairR, t);
  401. int bG = Math.Lerp(white, m_iCrosshairG, t);
  402. int bB = Math.Lerp(white, m_iCrosshairB, t);
  403. crossColor = ARGB(bA, bR, bG, bB);
  404. }
  405. }
  406. WorkspaceWidget ww = GetGame().GetWorkspace();
  407. if (ww)
  408. {
  409. Widget cw = ww.FindAnyWidget("CrossHairs");
  410. if (cw)
  411. {
  412. Widget child = cw.GetChildren();
  413. while (child)
  414. {
  415. child.SetColor(crossColor);
  416. child = child.GetSibling();
  417. }
  418. }
  419. }
  420. }
  421. }
  422. }
  423. }
  424. #endif
  425. #endif