DebugDrawer.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. #include "anki/renderer/DebugDrawer.h"
  2. #include "anki/resource/ShaderProgramResource.h"
  3. #include "anki/physics/Converters.h"
  4. #include "anki/collision/Collision.h"
  5. #include "anki/scene/Frustumable.h"
  6. #include "anki/scene/Octree.h"
  7. #include "anki/resource/Material.h"
  8. #include "anki/scene/Renderable.h"
  9. #include "anki/scene/Camera.h"
  10. #include "anki/scene/ModelNode.h"
  11. #include "anki/resource/TextureResource.h"
  12. #include "anki/renderer/Renderer.h"
  13. namespace anki {
  14. //==============================================================================
  15. // DebugDrawer =
  16. //==============================================================================
  17. //==============================================================================
  18. DebugDrawer::DebugDrawer()
  19. {
  20. prog.load("shaders/Dbg.glsl");
  21. vbo.create(GL_ARRAY_BUFFER, sizeof(clientVerts), nullptr,
  22. GL_DYNAMIC_DRAW);
  23. vao.create();
  24. vao.attachArrayBufferVbo(
  25. &vbo, prog->findAttributeVariable("position"), 3, GL_FLOAT,
  26. false, sizeof(Vertex), 0);
  27. vao.attachArrayBufferVbo(
  28. &vbo, prog->findAttributeVariable("color"), 3, GL_FLOAT,
  29. false, sizeof(Vertex), sizeof(Vec4));
  30. GLint loc =
  31. prog->findAttributeVariable("modelViewProjectionMat").getLocation();
  32. vao.attachArrayBufferVbo(
  33. &vbo, loc, 4, GL_FLOAT, false, sizeof(Vertex),
  34. 2 * sizeof(Vec4));
  35. vao.attachArrayBufferVbo(
  36. &vbo, loc + 1, 4, GL_FLOAT, false, sizeof(Vertex),
  37. 3 * sizeof(Vec4));
  38. vao.attachArrayBufferVbo(
  39. &vbo, loc + 2, 4, GL_FLOAT, false, sizeof(Vertex),
  40. 4 * sizeof(Vec4));
  41. vao.attachArrayBufferVbo(
  42. &vbo, loc + 3, 4, GL_FLOAT, false, sizeof(Vertex),
  43. 5 * sizeof(Vec4));
  44. vertexPointer = 0;
  45. mMat.setIdentity();
  46. vpMat.setIdentity();
  47. mvpMat.setIdentity();
  48. crntCol = Vec3(1.0, 0.0, 0.0);
  49. }
  50. //==============================================================================
  51. DebugDrawer::~DebugDrawer()
  52. {}
  53. //==============================================================================
  54. void DebugDrawer::setModelMatrix(const Mat4& m)
  55. {
  56. mMat = m;
  57. mvpMat = vpMat * mMat;
  58. }
  59. //==============================================================================
  60. void DebugDrawer::setViewProjectionMatrix(const Mat4& m)
  61. {
  62. vpMat = m;
  63. mvpMat = vpMat * mMat;
  64. }
  65. //==============================================================================
  66. void DebugDrawer::begin()
  67. {
  68. // Do nothing. Keep for compatibility
  69. }
  70. //==============================================================================
  71. void DebugDrawer::end()
  72. {
  73. if(vertexPointer % 2 != 0)
  74. {
  75. // push back the previous vertex to close the loop
  76. pushBackVertex(clientVerts[vertexPointer].position.xyz());
  77. }
  78. }
  79. //==============================================================================
  80. void DebugDrawer::flush()
  81. {
  82. if(vertexPointer == 0)
  83. {
  84. // Early exit
  85. return;
  86. }
  87. vbo.write(&clientVerts[0], 0, sizeof(clientVerts));
  88. prog->bind();
  89. vao.bind();
  90. glDrawArrays(GL_LINES, 0, vertexPointer);
  91. vertexPointer = 0;
  92. }
  93. //==============================================================================
  94. void DebugDrawer::pushBackVertex(const Vec3& pos)
  95. {
  96. clientVerts[vertexPointer].position = Vec4(pos, 1.0);
  97. clientVerts[vertexPointer].color = Vec4(crntCol, 1.0);
  98. clientVerts[vertexPointer].matrix = mvpMat.getTransposed();
  99. ++vertexPointer;
  100. if(vertexPointer == MAX_POINTS_PER_DRAW)
  101. {
  102. flush();
  103. }
  104. }
  105. //==============================================================================
  106. void DebugDrawer::drawLine(const Vec3& from, const Vec3& to, const Vec4& color)
  107. {
  108. setColor(color);
  109. begin();
  110. pushBackVertex(from);
  111. pushBackVertex(to);
  112. end();
  113. }
  114. //==============================================================================
  115. void DebugDrawer::drawGrid()
  116. {
  117. Vec4 col0(0.5, 0.5, 0.5, 1.0);
  118. Vec4 col1(0.0, 0.0, 1.0, 1.0);
  119. Vec4 col2(1.0, 0.0, 0.0, 1.0);
  120. const F32 SPACE = 1.0; // space between lines
  121. const U NUM = 57; // lines number. must be odd
  122. const F32 GRID_HALF_SIZE = ((NUM - 1) * SPACE / 2);
  123. setColor(col0);
  124. begin();
  125. for(U x = - NUM / 2 * SPACE; x < NUM / 2 * SPACE; x += SPACE)
  126. {
  127. setColor(col0);
  128. // if the middle line then change color
  129. if(x == 0)
  130. {
  131. setColor(col1);
  132. }
  133. // line in z
  134. pushBackVertex(Vec3(x, 0.0, -GRID_HALF_SIZE));
  135. pushBackVertex(Vec3(x, 0.0, GRID_HALF_SIZE));
  136. // if middle line change col so you can highlight the x-axis
  137. if(x == 0)
  138. {
  139. setColor(col2);
  140. }
  141. // line in the x
  142. pushBackVertex(Vec3(-GRID_HALF_SIZE, 0.0, x));
  143. pushBackVertex(Vec3(GRID_HALF_SIZE, 0.0, x));
  144. }
  145. // render
  146. end();
  147. }
  148. //==============================================================================
  149. void DebugDrawer::drawSphere(F32 radius, int complexity)
  150. {
  151. Vector<Vec3>* sphereLines;
  152. // Pre-calculate the sphere points5
  153. //
  154. std::unordered_map<U32, Vector<Vec3>>::iterator it =
  155. complexityToPreCalculatedSphere.find(complexity);
  156. if(it != complexityToPreCalculatedSphere.end()) // Found
  157. {
  158. sphereLines = &(it->second);
  159. }
  160. else // Not found
  161. {
  162. complexityToPreCalculatedSphere[complexity] = Vector<Vec3>();
  163. sphereLines = &complexityToPreCalculatedSphere[complexity];
  164. F32 fi = getPi<F32>() / complexity;
  165. Vec3 prev(1.0, 0.0, 0.0);
  166. for(F32 th = fi; th < getPi<F32>() * 2.0 + fi; th += fi)
  167. {
  168. Vec3 p = Mat3(Euler(0.0, th, 0.0)) * Vec3(1.0, 0.0, 0.0);
  169. for(F32 th2 = 0.0; th2 < getPi<F32>(); th2 += fi)
  170. {
  171. Mat3 rot(Euler(th2, 0.0, 0.0));
  172. Vec3 rotPrev = rot * prev;
  173. Vec3 rotP = rot * p;
  174. sphereLines->push_back(rotPrev);
  175. sphereLines->push_back(rotP);
  176. Mat3 rot2(Euler(0.0, 0.0, getPi<F32>() / 2));
  177. sphereLines->push_back(rot2 * rotPrev);
  178. sphereLines->push_back(rot2 * rotP);
  179. }
  180. prev = p;
  181. }
  182. }
  183. // Render
  184. //
  185. Mat4 oldMMat = mMat;
  186. Mat4 oldVpMat = vpMat;
  187. setModelMatrix(mMat * Mat4(Vec3(0.0), Mat3::getIdentity(), radius));
  188. begin();
  189. for(const Vec3& p : *sphereLines)
  190. {
  191. pushBackVertex(p);
  192. }
  193. end();
  194. // restore
  195. mMat = oldMMat;
  196. vpMat = oldVpMat;
  197. }
  198. //==============================================================================
  199. void DebugDrawer::drawCube(F32 size)
  200. {
  201. Vec3 maxPos = Vec3(0.5 * size);
  202. Vec3 minPos = Vec3(-0.5 * size);
  203. Array<Vec3, 8> points = {{
  204. Vec3(maxPos.x(), maxPos.y(), maxPos.z()), // right top front
  205. Vec3(minPos.x(), maxPos.y(), maxPos.z()), // left top front
  206. Vec3(minPos.x(), minPos.y(), maxPos.z()), // left bottom front
  207. Vec3(maxPos.x(), minPos.y(), maxPos.z()), // right bottom front
  208. Vec3(maxPos.x(), maxPos.y(), minPos.z()), // right top back
  209. Vec3(minPos.x(), maxPos.y(), minPos.z()), // left top back
  210. Vec3(minPos.x(), minPos.y(), minPos.z()), // left bottom back
  211. Vec3(maxPos.x(), minPos.y(), minPos.z()) // right bottom back
  212. }};
  213. static const Array<uint, 24> indeces = {{
  214. 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6,
  215. 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7}};
  216. begin();
  217. for(uint id : indeces)
  218. {
  219. pushBackVertex(points[id]);
  220. }
  221. end();
  222. }
  223. //==============================================================================
  224. // CollisionDebugDrawer =
  225. //==============================================================================
  226. //==============================================================================
  227. void CollisionDebugDrawer::visit(const Sphere& sphere)
  228. {
  229. dbg->setModelMatrix(Mat4(sphere.getCenter(), Mat3::getIdentity(), 1.0));
  230. dbg->drawSphere(sphere.getRadius());
  231. }
  232. //==============================================================================
  233. void CollisionDebugDrawer::visit(const Obb& obb)
  234. {
  235. Mat4 scale(Mat4::getIdentity());
  236. scale(0, 0) = obb.getExtend().x();
  237. scale(1, 1) = obb.getExtend().y();
  238. scale(2, 2) = obb.getExtend().z();
  239. Mat4 rot(obb.getRotation());
  240. Mat4 trs(obb.getCenter());
  241. Mat4 tsl;
  242. tsl = Mat4::combineTransformations(rot, scale);
  243. tsl = Mat4::combineTransformations(trs, tsl);
  244. dbg->setModelMatrix(tsl);
  245. dbg->setColor(Vec3(1.0, 1.0, 0.0));
  246. dbg->drawCube(2.0);
  247. }
  248. //==============================================================================
  249. void CollisionDebugDrawer::visit(const Plane& plane)
  250. {
  251. const Vec3& n = plane.getNormal();
  252. const F32& o = plane.getOffset();
  253. Quat q;
  254. q.setFrom2Vec3(Vec3(0.0, 0.0, 1.0), n);
  255. Mat3 rot(q);
  256. rot.rotateXAxis(getPi<F32>() / 2.0);
  257. Mat4 trf(n * o, rot);
  258. dbg->setModelMatrix(trf);
  259. dbg->drawGrid();
  260. }
  261. //==============================================================================
  262. void CollisionDebugDrawer::visit(const Aabb& aabb)
  263. {
  264. const Vec3& min = aabb.getMin();
  265. const Vec3& max = aabb.getMax();
  266. Mat4 trf = Mat4::getIdentity();
  267. // Scale
  268. for(uint i = 0; i < 3; ++i)
  269. {
  270. trf(i, i) = max[i] - min[i];
  271. }
  272. // Translation
  273. trf.setTranslationPart((max + min) / 2.0);
  274. dbg->setModelMatrix(trf);
  275. dbg->drawCube();
  276. }
  277. //==============================================================================
  278. void CollisionDebugDrawer::visit(const Frustum& f)
  279. {
  280. switch(f.getFrustumType())
  281. {
  282. case Frustum::FT_ORTHOGRAPHIC:
  283. visit(static_cast<const OrthographicFrustum&>(f).getObb());
  284. break;
  285. case Frustum::FT_PERSPECTIVE:
  286. {
  287. dbg->setColor(Vec4(0.5, 0.0, 0.5, 1.0));
  288. const PerspectiveFrustum& pf =
  289. static_cast<const PerspectiveFrustum&>(f);
  290. F32 camLen = pf.getFar();
  291. F32 tmp0 = camLen / tan((getPi<F32>() - pf.getFovX()) * 0.5)
  292. + 0.001;
  293. F32 tmp1 = camLen * tan(pf.getFovY() * 0.5) + 0.001;
  294. Vec3 points[] = {
  295. Vec3(0.0, 0.0, 0.0), // 0: eye point
  296. Vec3(-tmp0, tmp1, -camLen), // 1: top left
  297. Vec3(-tmp0, -tmp1, -camLen), // 2: bottom left
  298. Vec3(tmp0, -tmp1, -camLen), // 3: bottom right
  299. Vec3(tmp0, tmp1, -camLen) // 4: top right
  300. };
  301. const uint indeces[] = {0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2,
  302. 3, 3, 4, 4, 1};
  303. dbg->begin();
  304. for(uint i = 0; i < sizeof(indeces) / sizeof(uint); i++)
  305. {
  306. dbg->pushBackVertex(points[indeces[i]]);
  307. }
  308. dbg->end();
  309. break;
  310. }
  311. }
  312. }
  313. //==============================================================================
  314. // PhysicsDebugDrawer =
  315. //==============================================================================
  316. //==============================================================================
  317. void PhysicsDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
  318. const btVector3& color)
  319. {
  320. dbg->drawLine(toAnki(from), toAnki(to), Vec4(toAnki(color), 1.0));
  321. }
  322. //==============================================================================
  323. void PhysicsDebugDrawer::drawSphere(btScalar radius,
  324. const btTransform& transform,
  325. const btVector3& color)
  326. {
  327. dbg->setColor(toAnki(color));
  328. dbg->setModelMatrix(Mat4(toAnki(transform)));
  329. dbg->drawSphere(radius);
  330. }
  331. //==============================================================================
  332. void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
  333. const btVector3& color)
  334. {
  335. Mat4 trf(Mat4::getIdentity());
  336. trf(0, 0) = max.getX() - min.getX();
  337. trf(1, 1) = max.getY() - min.getY();
  338. trf(2, 2) = max.getZ() - min.getZ();
  339. trf(0, 3) = (max.getX() + min.getX()) / 2.0;
  340. trf(1, 3) = (max.getY() + min.getY()) / 2.0;
  341. trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
  342. dbg->setModelMatrix(trf);
  343. dbg->setColor(toAnki(color));
  344. dbg->drawCube(1.0);
  345. }
  346. //==============================================================================
  347. void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
  348. const btTransform& trans, const btVector3& color)
  349. {
  350. Mat4 trf(Mat4::getIdentity());
  351. trf(0, 0) = max.getX() - min.getX();
  352. trf(1, 1) = max.getY() - min.getY();
  353. trf(2, 2) = max.getZ() - min.getZ();
  354. trf(0, 3) = (max.getX() + min.getX()) / 2.0;
  355. trf(1, 3) = (max.getY() + min.getY()) / 2.0;
  356. trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
  357. trf = Mat4::combineTransformations(Mat4(toAnki(trans)), trf);
  358. dbg->setModelMatrix(trf);
  359. dbg->setColor(toAnki(color));
  360. dbg->drawCube(1.0);
  361. }
  362. //==============================================================================
  363. void PhysicsDebugDrawer::drawContactPoint(const btVector3& /*pointOnB*/,
  364. const btVector3& /*normalOnB*/,
  365. btScalar /*distance*/, int /*lifeTime*/, const btVector3& /*color*/)
  366. {
  367. //ANKI_LOGW("Unimplemented");
  368. }
  369. //==============================================================================
  370. void PhysicsDebugDrawer::reportErrorWarning(const char* warningString)
  371. {
  372. throw ANKI_EXCEPTION(warningString);
  373. }
  374. //==============================================================================
  375. void PhysicsDebugDrawer::draw3dText(const btVector3& /*location*/,
  376. const char* /*textString*/)
  377. {
  378. //ANKI_LOGW("Unimplemented");
  379. }
  380. //==============================================================================
  381. // SceneDebugDrawer =
  382. //==============================================================================
  383. //==============================================================================
  384. void SceneDebugDrawer::draw(SceneNode& node)
  385. {
  386. // Nothing to render?
  387. if(getFlagsBitmask() == 0)
  388. {
  389. return;
  390. }
  391. Movable* mv = node.getMovable();
  392. if(mv)
  393. {
  394. dbg->setModelMatrix(Mat4(mv->getWorldTransform()));
  395. }
  396. else
  397. {
  398. dbg->setModelMatrix(Mat4::getIdentity());
  399. }
  400. Frustumable* fr;
  401. if(isFlagEnabled(DF_FRUSTUMABLE) && (fr = node.getFrustumable()))
  402. {
  403. draw(*fr);
  404. }
  405. Spatial* sp;
  406. if(isFlagEnabled(DF_SPATIAL) && (sp = node.getSpatial())
  407. && sp->isFlagEnabled(Spatial::SF_VISIBLE_CAMERA))
  408. {
  409. draw(*sp);
  410. }
  411. }
  412. //==============================================================================
  413. void SceneDebugDrawer::draw(Frustumable& fr) const
  414. {
  415. const Frustum& fs = fr.getFrustum();
  416. CollisionDebugDrawer coldraw(dbg);
  417. fs.accept(coldraw);
  418. }
  419. //==============================================================================
  420. void SceneDebugDrawer::draw(Spatial& x) const
  421. {
  422. CollisionDebugDrawer coldraw(dbg);
  423. x.getAabb().accept(coldraw);
  424. }
  425. //==============================================================================
  426. void SceneDebugDrawer::draw(const Octree& octree) const
  427. {
  428. dbg->setColor(Vec3(1.0));
  429. draw(octree.getRoot(), 0, octree);
  430. }
  431. //==============================================================================
  432. void SceneDebugDrawer::draw(const OctreeNode& octnode, U32 depth,
  433. const Octree& octree) const
  434. {
  435. PtrSize nodesCount =
  436. octnode.getSceneNodesEnd() - octnode.getSceneNodesBegin();
  437. // Draw if it has spatials
  438. if(nodesCount != 0)
  439. {
  440. //Vec3 color = Vec3(1.0 - F32(depth) / F32(octree.getMaxDepth()));
  441. Vec3 color(1.0);
  442. dbg->setColor(color);
  443. CollisionDebugDrawer v(dbg);
  444. octnode.getAabb().accept(v);
  445. }
  446. // Children
  447. for(U32 i = 0; i < 8; ++i)
  448. {
  449. if(octnode.getChild(i) != nullptr)
  450. {
  451. draw(*octnode.getChild(i), depth + 1, octree);
  452. }
  453. }
  454. }
  455. } // end namespace anki