DebugDrawer.cpp 16 KB

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