2
0

Drawer.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. #include "anki/renderer/Drawer.h"
  2. #include "anki/resource/ShaderProgram.h"
  3. #include "anki/physics/Convertors.h"
  4. namespace anki {
  5. //==============================================================================
  6. // DebugDrawer =
  7. //==============================================================================
  8. //==============================================================================
  9. DebugDrawer::DebugDrawer()
  10. {
  11. sProg.load("shaders/Dbg.glsl");
  12. positionsVbo.create(GL_ARRAY_BUFFER, sizeof(positions), NULL,
  13. GL_DYNAMIC_DRAW);
  14. colorsVbo.create(GL_ARRAY_BUFFER, sizeof(colors), NULL, GL_DYNAMIC_DRAW);
  15. vao.create();
  16. const int positionAttribLoc = 0;
  17. vao.attachArrayBufferVbo(positionsVbo, positionAttribLoc, 3, GL_FLOAT,
  18. GL_FALSE, 0, NULL);
  19. const int colorAttribLoc = 1;
  20. vao.attachArrayBufferVbo(colorsVbo, colorAttribLoc, 3, GL_FLOAT, GL_FALSE,
  21. 0, NULL);
  22. pointIndex = 0;
  23. modelMat.setIdentity();
  24. crntCol = Vec3(1.0, 0.0, 0.0);
  25. }
  26. //==============================================================================
  27. void DebugDrawer::drawLine(const Vec3& from, const Vec3& to, const Vec4& color)
  28. {
  29. setColor(color);
  30. begin();
  31. pushBackVertex(from);
  32. pushBackVertex(to);
  33. end();
  34. }
  35. //==============================================================================
  36. void DebugDrawer::drawGrid()
  37. {
  38. Vec4 col0(0.5, 0.5, 0.5, 1.0);
  39. Vec4 col1(0.0, 0.0, 1.0, 1.0);
  40. Vec4 col2(1.0, 0.0, 0.0, 1.0);
  41. const float SPACE = 1.0; // space between lines
  42. const int NUM = 57; // lines number. must be odd
  43. const float GRID_HALF_SIZE = ((NUM - 1) * SPACE / 2);
  44. setColor(col0);
  45. begin();
  46. for(int x = - NUM / 2 * SPACE; x < NUM / 2 * SPACE; x += SPACE)
  47. {
  48. setColor(col0);
  49. // if the middle line then change color
  50. if(x == 0)
  51. {
  52. setColor(col1);
  53. }
  54. // line in z
  55. pushBackVertex(Vec3(x, 0.0, -GRID_HALF_SIZE));
  56. pushBackVertex(Vec3(x, 0.0, GRID_HALF_SIZE));
  57. // if middle line change col so you can highlight the x-axis
  58. if(x == 0)
  59. {
  60. setColor(col2);
  61. }
  62. // line in the x
  63. pushBackVertex(Vec3(-GRID_HALF_SIZE, 0.0, x));
  64. pushBackVertex(Vec3(GRID_HALF_SIZE, 0.0, x));
  65. }
  66. // render
  67. end();
  68. }
  69. //==============================================================================
  70. void DebugDrawer::drawSphere(float radius, int complexity)
  71. {
  72. std::vector<Vec3>* sphereLines;
  73. // Pre-calculate the sphere points5
  74. //
  75. std::map<uint, std::vector<Vec3> >::iterator it =
  76. complexityToPreCalculatedSphere.find(complexity);
  77. if(it != complexityToPreCalculatedSphere.end()) // Found
  78. {
  79. sphereLines = &(it->second);
  80. }
  81. else // Not found
  82. {
  83. complexityToPreCalculatedSphere[complexity] = std::vector<Vec3>();
  84. sphereLines = &complexityToPreCalculatedSphere[complexity];
  85. float fi = Math::PI / complexity;
  86. Vec3 prev(1.0, 0.0, 0.0);
  87. for(float th = fi; th < Math::PI * 2.0 + fi; th += fi)
  88. {
  89. Vec3 p = Mat3(Euler(0.0, th, 0.0)) * Vec3(1.0, 0.0, 0.0);
  90. for(float th2 = 0.0; th2 < Math::PI; th2 += fi)
  91. {
  92. Mat3 rot(Euler(th2, 0.0, 0.0));
  93. Vec3 rotPrev = rot * prev;
  94. Vec3 rotP = rot * p;
  95. sphereLines->push_back(rotPrev);
  96. sphereLines->push_back(rotP);
  97. Mat3 rot2(Euler(0.0, 0.0, Math::PI / 2));
  98. sphereLines->push_back(rot2 * rotPrev);
  99. sphereLines->push_back(rot2 * rotP);
  100. }
  101. prev = p;
  102. }
  103. }
  104. // Render
  105. //
  106. modelMat = modelMat * Mat4(Vec3(0.0), Mat3::getIdentity(), radius);
  107. begin();
  108. for(const Vec3& p : *sphereLines)
  109. {
  110. if(pointIndex >= MAX_POINTS_PER_DRAW)
  111. {
  112. end();
  113. begin();
  114. }
  115. pushBackVertex(p);
  116. }
  117. end();
  118. }
  119. //==============================================================================
  120. void DebugDrawer::drawCube(float size)
  121. {
  122. Vec3 maxPos = Vec3(0.5 * size);
  123. Vec3 minPos = Vec3(-0.5 * size);
  124. std::array<Vec3, 8> points = {{
  125. Vec3(maxPos.x(), maxPos.y(), maxPos.z()), // right top front
  126. Vec3(minPos.x(), maxPos.y(), maxPos.z()), // left top front
  127. Vec3(minPos.x(), minPos.y(), maxPos.z()), // left bottom front
  128. Vec3(maxPos.x(), minPos.y(), maxPos.z()), // right bottom front
  129. Vec3(maxPos.x(), maxPos.y(), minPos.z()), // right top back
  130. Vec3(minPos.x(), maxPos.y(), minPos.z()), // left top back
  131. Vec3(minPos.x(), minPos.y(), minPos.z()), // left bottom back
  132. Vec3(maxPos.x(), minPos.y(), minPos.z()) // right bottom back
  133. }};
  134. std::array<uint, 24> indeces = {{0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6,
  135. 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7}};
  136. begin();
  137. for(uint id : indeces)
  138. {
  139. pushBackVertex(points[id]);
  140. }
  141. end();
  142. }
  143. //==============================================================================
  144. void DebugDrawer::setModelMat(const Mat4& modelMat_)
  145. {
  146. ANKI_ASSERT(pointIndex == 0
  147. && "The func called after begin and before end");
  148. modelMat = modelMat_;
  149. }
  150. //==============================================================================
  151. void DebugDrawer::begin()
  152. {
  153. ANKI_ASSERT(pointIndex == 0);
  154. }
  155. //==============================================================================
  156. void DebugDrawer::end()
  157. {
  158. ANKI_ASSERT(pointIndex != 0);
  159. positionsVbo.write(&positions[0], 0, sizeof(Vec3) * pointIndex);
  160. colorsVbo.write(&colors[0], 0, sizeof(Vec3) * pointIndex);
  161. Mat4 pmv = r.getViewProjectionMat() * modelMat;
  162. sProg->findUniformVariableByName("modelViewProjectionMat").set(pmv);
  163. vao.bind();
  164. glDrawArrays(GL_LINES, 0, pointIndex);
  165. vao.unbind();
  166. // Cleanup
  167. pointIndex = 0;
  168. }
  169. //==============================================================================
  170. void DebugDrawer::pushBackVertex(const Vec3& pos)
  171. {
  172. positions[pointIndex] = pos;
  173. colors[pointIndex] = crntCol;
  174. ++pointIndex;
  175. }
  176. //==============================================================================
  177. // CollisionDbgDrawer =
  178. //==============================================================================
  179. //==============================================================================
  180. void CollisionDbgDrawer::visit(const Sphere& sphere)
  181. {
  182. dbg->setModelMat(Mat4(sphere.getCenter(), Mat3::getIdentity(), 1.0));
  183. dbg->drawSphere(sphere.getRadius());
  184. }
  185. //==============================================================================
  186. void CollisionDbgDrawer::visit(const Obb& obb)
  187. {
  188. Mat4 scale(Mat4::getIdentity());
  189. scale(0, 0) = obb.getExtend().x();
  190. scale(1, 1) = obb.getExtend().y();
  191. scale(2, 2) = obb.getExtend().z();
  192. Mat4 rot(obb.getRotation());
  193. Mat4 trs(obb.getCenter());
  194. Mat4 tsl;
  195. tsl = Mat4::combineTransformations(rot, scale);
  196. tsl = Mat4::combineTransformations(trs, tsl);
  197. dbg->setModelMat(tsl);
  198. dbg->setColor(Vec3(1.0, 1.0, 0.0));
  199. dbg->drawCube(2.0);
  200. }
  201. //==============================================================================
  202. void CollisionDbgDrawer::visit(const Plane& plane)
  203. {
  204. const Vec3& n = plane.getNormal();
  205. const float& o = plane.getOffset();
  206. Quat q;
  207. q.setFrom2Vec3(Vec3(0.0, 0.0, 1.0), n);
  208. Mat3 rot(q);
  209. rot.rotateXAxis(Math::PI / 2);
  210. Mat4 trf(n * o, rot);
  211. dbg->setModelMat(trf);
  212. dbg->renderGrid();
  213. }
  214. //==============================================================================
  215. void CollisionDbgDrawer::visit(const Aabb& aabb)
  216. {
  217. const Vec3& min = aabb.getMin();
  218. const Vec3& max = aabb.getMax();
  219. Mat4 trf = Mat4::getIdentity();
  220. // Scale
  221. for(uint i = 0; i < 3; ++i)
  222. {
  223. trf(i, i) = max[i] - min[i];
  224. }
  225. // Translation
  226. trf.setTranslationPart((max + min) / 2.0);
  227. dbg->setModelMat(trf);
  228. dbg->drawCube();
  229. }
  230. //==============================================================================
  231. void CollisionDbgDrawer::visit(const Frustum& f)
  232. {
  233. switch(f.getFrustumType())
  234. {
  235. case Frustum::FT_ORTHOGRAPHIC:
  236. visit(static_cast<const OrthographicFrustum&>(f).getObb());
  237. break;
  238. case Frustum::FT_PERSPECTIVE:
  239. {
  240. dbg->setColor(Vec4(1.0, 0.0, 1.0, 1.0));
  241. const PerspectiveFrustum& pf =
  242. static_cast<const PerspectiveFrustum&>(f);
  243. float camLen = pf.getFar();
  244. float tmp0 = camLen / tan((Math::PI - pf.getFovX()) * 0.5) + 0.001;
  245. float tmp1 = camLen * tan(pf.getFovY() * 0.5) + 0.001;
  246. Vec3 points[] = {
  247. Vec3(0.0, 0.0, 0.0), // 0: eye point
  248. Vec3(-tmp0, tmp1, -camLen), // 1: top left
  249. Vec3(-tmp0, -tmp1, -camLen), // 2: bottom left
  250. Vec3(tmp0, -tmp1, -camLen), // 3: bottom right
  251. Vec3(tmp0, tmp1, -camLen) // 4: top right
  252. };
  253. const uint indeces[] = {0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2,
  254. 3, 3, 4, 4, 1};
  255. dbg->begin();
  256. for(uint i = 0; i < sizeof(indeces) / sizeof(uint); i++)
  257. {
  258. dbg->pushBackVertex(points[indeces[i]]);
  259. }
  260. dbg->end();
  261. break;
  262. }
  263. }
  264. }
  265. //==============================================================================
  266. // PhysicsDebugDrawer =
  267. //==============================================================================
  268. //==============================================================================
  269. void PhysicsDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
  270. const btVector3& color)
  271. {
  272. dbg->drawLine(toAnki(from), toAnki(to), Vec4(toAnki(color), 1.0));
  273. }
  274. //==============================================================================
  275. void PhysicsDebugDrawer::drawSphere(btScalar radius,
  276. const btTransform& transform,
  277. const btVector3& color)
  278. {
  279. dbg->setColor(toAnki(color));
  280. dbg->setModelMat(Mat4(toAnki(transform)));
  281. dbg->drawSphere(radius);
  282. }
  283. //==============================================================================
  284. void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
  285. const btVector3& color)
  286. {
  287. Mat4 trf(Mat4::getIdentity());
  288. trf(0, 0) = max.getX() - min.getX();
  289. trf(1, 1) = max.getY() - min.getY();
  290. trf(2, 2) = max.getZ() - min.getZ();
  291. trf(0, 3) = (max.getX() + min.getX()) / 2.0;
  292. trf(1, 3) = (max.getY() + min.getY()) / 2.0;
  293. trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
  294. dbg->setModelMat(trf);
  295. dbg->setColor(toAnki(color));
  296. dbg->drawCube(1.0);
  297. }
  298. //==============================================================================
  299. void PhysicsDebugDrawer::drawBox(const btVector3& min, const btVector3& max,
  300. const btTransform& trans, const btVector3& color)
  301. {
  302. Mat4 trf(Mat4::getIdentity());
  303. trf(0, 0) = max.getX() - min.getX();
  304. trf(1, 1) = max.getY() - min.getY();
  305. trf(2, 2) = max.getZ() - min.getZ();
  306. trf(0, 3) = (max.getX() + min.getX()) / 2.0;
  307. trf(1, 3) = (max.getY() + min.getY()) / 2.0;
  308. trf(2, 3) = (max.getZ() + min.getZ()) / 2.0;
  309. trf = Mat4::combineTransformations(Mat4(toAnki(trans)), trf);
  310. dbg->setModelMat(trf);
  311. dbg->setColor(toAnki(color));
  312. dbg->drawCube(1.0);
  313. }
  314. //==============================================================================
  315. void PhysicsDebugDrawer::drawContactPoint(const btVector3& /*pointOnB*/,
  316. const btVector3& /*normalOnB*/,
  317. btScalar /*distance*/, int /*lifeTime*/, const btVector3& /*color*/)
  318. {
  319. //ANKI_WARNING("Unimplemented");
  320. }
  321. //==============================================================================
  322. void PhysicsDebugDrawer::reportErrorWarning(const char* warningString)
  323. {
  324. throw ANKI_EXCEPTION(warningString);
  325. }
  326. //==============================================================================
  327. void PhysicsDebugDrawer::draw3dText(const btVector3& /*location*/,
  328. const char* /*textString*/)
  329. {
  330. //ANKI_WARNING("Unimplemented");
  331. }
  332. //==============================================================================
  333. // SceneDebugDrawer =
  334. //==============================================================================
  335. //==============================================================================
  336. void SceneDebugDrawer::draw(const SceneNode& node)
  337. {
  338. if(isFlagEnabled(DF_FRUSTUMABLE) && node.getFrustumable())
  339. {
  340. draw(*node.getFrustumable());
  341. }
  342. if(isFlagEnabled(DF_SPATIAL) && node.getSpatial())
  343. {
  344. draw(*node.getSpatial());
  345. }
  346. }
  347. //==============================================================================
  348. void SceneDebugDrawer::draw(const Frustumable& fr) const
  349. {
  350. const Frustum& fs = fr.getFrustum();
  351. CollisionDbgDrawer coldraw(dbg);
  352. fs.accept(coldraw);
  353. }
  354. //==============================================================================
  355. void SceneDebugDrawer::draw(const Spatial& x) const
  356. {
  357. const CollisionShape& cs = x.getSpatialCollisionShape();
  358. CollisionDbgDrawer coldraw(dbg);
  359. cs.accept(coldraw);
  360. }
  361. //==============================================================================
  362. void SceneDebugDrawer::draw(const Octree& octree) const
  363. {
  364. dbg->setColor(Vec3(1.0));
  365. draw(octree.getRoot(), 0, octree);
  366. }
  367. //==============================================================================
  368. void SceneDebugDrawer::draw(const OctreeNode& octnode, uint depth,
  369. const Octree& octree) const
  370. {
  371. Vec3 color = Vec3(1.0 - float(depth) / float(octree.getMaxDepth()));
  372. dbg->setColor(color);
  373. CollisionDbgDrawer v(dbg);
  374. octnode.getAabb().accept(v);
  375. // Children
  376. for(uint i = 0; i < 8; ++i)
  377. {
  378. if(octnode.getChildren()[i] != NULL)
  379. {
  380. draw(*octnode.getChildren()[i], depth + 1, octree);
  381. }
  382. }
  383. }
  384. } // namespace anki