debug_line.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright (c) 2012-2016 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "color4.h"
  6. #include "debug_line.h"
  7. #include "device.h"
  8. #include "math_utils.h"
  9. #include "matrix4x4.h"
  10. #include "shader_manager.h"
  11. #include "vector3.h"
  12. #include <string.h> // memcpy
  13. namespace crown
  14. {
  15. DebugLine::DebugLine(bool depth_test)
  16. : _marker(MARKER)
  17. , _shader(depth_test ? "debug_line" : "debug_line_noz")
  18. , _num(0)
  19. {
  20. _vertex_decl.begin()
  21. .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
  22. .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
  23. .end();
  24. }
  25. DebugLine::~DebugLine()
  26. {
  27. _marker = 0;
  28. }
  29. void DebugLine::add_line(const Vector3& start, const Vector3& end, const Color4& color)
  30. {
  31. if (_num >= CROWN_MAX_DEBUG_LINES)
  32. return;
  33. _lines[_num].p0 = start;
  34. _lines[_num].c0 = to_abgr(color);
  35. _lines[_num].p1 = end;
  36. _lines[_num].c1 = to_abgr(color);
  37. ++_num;
  38. }
  39. void DebugLine::add_axes(const Matrix4x4& m, f32 length)
  40. {
  41. const Vector3 pos = translation(m);
  42. add_line(pos, pos + x(m)*length, COLOR4_RED);
  43. add_line(pos, pos + y(m)*length, COLOR4_GREEN);
  44. add_line(pos, pos + z(m)*length, COLOR4_BLUE);
  45. }
  46. void DebugLine::add_circle(const Vector3& center, f32 radius, const Vector3& normal, const Color4& color, u32 segments)
  47. {
  48. const Vector3 dir = normal;
  49. const Vector3 arr[] =
  50. {
  51. { dir.z, dir.z, -dir.x -dir.y },
  52. { -dir.y -dir.z, dir.x, dir.x }
  53. };
  54. const int idx = ((dir.z != 0.0f) && (-dir.x != dir.y));
  55. Vector3 right = arr[idx];
  56. normalize(right);
  57. const f32 incr = 360.0f / (f32)(segments >= 3 ? segments : 3);
  58. f32 deg0 = 0.0f;
  59. for (u32 ss = 0; ss < segments; ++ss, deg0 += incr)
  60. {
  61. const f32 rad0 = to_rad(deg0);
  62. const f32 rad1 = to_rad(deg0 + incr);
  63. const Vector3 from0 = right*cos(-rad0) + cross(dir, right)*sin(-rad0) + dir*dot(dir, right)*(1.0f-cos(-rad0));
  64. const Vector3 from1 = right*cos(-rad1) + cross(dir, right)*sin(-rad1) + dir*dot(dir, right)*(1.0f-cos(-rad1));
  65. add_line(center + radius*from0, center + radius*from1, color);
  66. }
  67. }
  68. void DebugLine::add_cone(const Vector3& from, const Vector3& to, f32 radius, const Color4& color, u32 segments)
  69. {
  70. Vector3 dir = to - from;
  71. normalize(dir);
  72. const Vector3 arr[] =
  73. {
  74. { dir.z, dir.z, -dir.x -dir.y },
  75. { -dir.y -dir.z, dir.x, dir.x }
  76. };
  77. const int idx = ((dir.z != 0.0f) && (-dir.x != dir.y));
  78. Vector3 right = arr[idx];
  79. normalize(right);
  80. const f32 incr = 360.0f / (f32)(segments >= 3 ? segments : 3);
  81. f32 deg0 = 0.0f;
  82. for (u32 ss = 0; ss < segments; ++ss, deg0 += incr)
  83. {
  84. const f32 rad0 = to_rad(deg0);
  85. const f32 rad1 = to_rad(deg0 + incr);
  86. const Vector3 from0 = right*cos(-rad0) + cross(dir, right)*sin(-rad0) + dir*dot(dir, right)*(1.0f-cos(-rad0));
  87. const Vector3 from1 = right*cos(-rad1) + cross(dir, right)*sin(-rad1) + dir*dot(dir, right)*(1.0f-cos(-rad1));
  88. add_line(from + radius*from0, to, color);
  89. add_line(from + radius*from0, from + radius*from1, color);
  90. }
  91. }
  92. void DebugLine::add_sphere(const Vector3& center, const f32 radius, const Color4& color, u32 segments)
  93. {
  94. add_circle(center, radius, VECTOR3_XAXIS, color, segments);
  95. add_circle(center, radius, VECTOR3_YAXIS, color, segments);
  96. add_circle(center, radius, VECTOR3_ZAXIS, color, segments);
  97. }
  98. void DebugLine::add_obb(const Matrix4x4& tm, const Vector3& half_extents, const Color4& color)
  99. {
  100. const Vector3 o = vector3(tm.t.x, tm.t.y, tm.t.z);
  101. const Vector3 x = vector3(tm.x.x, tm.x.y, tm.x.z) * half_extents.x;
  102. const Vector3 y = vector3(tm.y.x, tm.y.y, tm.y.z) * half_extents.y;
  103. const Vector3 z = vector3(tm.z.x, tm.z.y, tm.z.z) * half_extents.z;
  104. // Back face
  105. add_line(o - x - y - z, o + x - y - z, color);
  106. add_line(o + x - y - z, o + x + y - z, color);
  107. add_line(o + x + y - z, o - x + y - z, color);
  108. add_line(o - x + y - z, o - x - y - z, color);
  109. add_line(o - x - y + z, o + x - y + z, color);
  110. add_line(o + x - y + z, o + x + y + z, color);
  111. add_line(o + x + y + z, o - x + y + z, color);
  112. add_line(o - x + y + z, o - x - y + z, color);
  113. add_line(o - x - y - z, o - x - y + z, color);
  114. add_line(o + x - y - z, o + x - y + z, color);
  115. add_line(o + x + y - z, o + x + y + z, color);
  116. add_line(o - x + y - z, o - x + y + z, color);
  117. }
  118. void DebugLine::reset()
  119. {
  120. _num = 0;
  121. }
  122. void DebugLine::submit()
  123. {
  124. if (!_num)
  125. return;
  126. if (!checkAvailTransientVertexBuffer(_num * 2, _vertex_decl))
  127. return;
  128. bgfx::TransientVertexBuffer tvb;
  129. bgfx::allocTransientVertexBuffer(&tvb, _num * 2, _vertex_decl);
  130. memcpy(tvb.data, _lines, sizeof(Line) * _num);
  131. const ShaderData& sd = device()->shader_manager()->get(_shader);
  132. bgfx::setVertexBuffer(&tvb, 0, _num * 2);
  133. bgfx::setState(sd.state);
  134. bgfx::submit(1, sd.program);
  135. }
  136. } // namespace crown