Drawer.cpp 13 KB

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