BsDrawHelper3D.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. #include "BsDrawHelper3D.h"
  2. #include "BsRectF.h"
  3. #include "BsMesh.h"
  4. #include "BsTime.h"
  5. #include "BsVector2.h"
  6. #include "BsMaterial.h"
  7. #include "BsPass.h"
  8. #include "BsCoreApplication.h"
  9. #include "BsRenderQueue.h"
  10. #include "BsException.h"
  11. #include "BsCamera.h"
  12. #include "BsBuiltinResources.h"
  13. #include "BsVertexDataDesc.h"
  14. namespace BansheeEngine
  15. {
  16. DrawHelper3D::DrawHelper3D()
  17. {
  18. mVertexDesc = bs_shared_ptr<VertexDataDesc>();
  19. mVertexDesc->addVertElem(VET_FLOAT2, VES_POSITION);
  20. mVertexDesc->addVertElem(VET_COLOR, VES_COLOR);
  21. }
  22. void DrawHelper3D::aabox(const AABox& box, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
  23. {
  24. UINT32* indexData = meshData->getIndices32();
  25. UINT8* positionData = meshData->getElementData(VES_POSITION);
  26. assert((vertexOffset + 8) <= meshData->getNumVertices());
  27. assert((indexOffset + 36) <= meshData->getNumIndices());
  28. aabox(box, positionData, vertexOffset, meshData->getVertexDesc()->getVertexStride(), indexData, indexOffset);
  29. }
  30. void DrawHelper3D::line_Pixel(const Vector3& a, const Vector3& b, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
  31. {
  32. DrawHelperTemplate<Vector3>::line_Pixel(a, b, color, meshData, vertexOffset, indexOffset);
  33. }
  34. void DrawHelper3D::line_AA(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth,
  35. const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
  36. {
  37. DrawHelperTemplate<Vector3>::line_AA(a, b, up, width, borderWidth, color, meshData, vertexOffset, indexOffset);
  38. }
  39. void DrawHelper3D::lineList_Pixel(const Vector<Vector3>& linePoints, const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
  40. {
  41. DrawHelperTemplate<Vector3>::lineList_Pixel(linePoints, color, meshData, vertexOffset, indexOffset);
  42. }
  43. void DrawHelper3D::lineList_AA(const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth,
  44. const Color& color, const MeshDataPtr& meshData, UINT32 vertexOffset, UINT32 indexOffset)
  45. {
  46. DrawHelperTemplate<Vector3>::lineList_AA(linePoints, up, width, borderWidth, color, meshData, vertexOffset, indexOffset);
  47. }
  48. /************************************************************************/
  49. /* DRAW */
  50. /************************************************************************/
  51. void DrawHelper3D::drawLine_Pixel(const HCamera& camera, const Vector3& a, const Vector3& b, const Color& color, float timeout)
  52. {
  53. const Viewport* viewport = camera->getViewport().get();
  54. Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
  55. commands.push_back(DebugDrawCommand());
  56. DebugDrawCommand& dbgCmd = commands.back();
  57. dbgCmd.endTime = gTime().getTime() + timeout;
  58. MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(2, 2, mVertexDesc);
  59. line_Pixel(a, b, color, meshData, 0, 0);
  60. UINT8* positionData = meshData->getElementData(VES_POSITION);
  61. dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
  62. HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
  63. dbgCmd.mesh = mesh;
  64. dbgCmd.type = DebugDrawType::WorldSpace;
  65. dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
  66. }
  67. void DrawHelper3D::drawLine_AA(const HCamera& camera, const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, float timeout)
  68. {
  69. const Viewport* viewport = camera->getViewport().get();
  70. Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
  71. commands.push_back(DebugDrawCommand());
  72. DebugDrawCommand& dbgCmd = commands.back();
  73. dbgCmd.endTime = gTime().getTime() + timeout;
  74. MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(8, 30, mVertexDesc);
  75. line_AA(a, b, up, width, borderWidth, color, meshData, 0, 0);
  76. UINT8* positionData = meshData->getElementData(VES_POSITION);
  77. dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
  78. HMesh mesh = Mesh::create(meshData);
  79. dbgCmd.mesh = mesh;
  80. dbgCmd.type = DebugDrawType::WorldSpace;
  81. dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
  82. }
  83. void DrawHelper3D::drawLineList_Pixel(const HCamera& camera, const Vector<Vector3>& linePoints, const Color& color, float timeout)
  84. {
  85. const Viewport* viewport = camera->getViewport().get();
  86. Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
  87. commands.push_back(DebugDrawCommand());
  88. DebugDrawCommand& dbgCmd = commands.back();
  89. dbgCmd.endTime = gTime().getTime() + timeout;
  90. MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(
  91. (UINT32)(linePoints.size() * 2), (UINT32)(linePoints.size() * 2), mVertexDesc);
  92. lineList_Pixel(linePoints, color, meshData, 0, 0);
  93. UINT8* positionData = meshData->getElementData(VES_POSITION);
  94. dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
  95. HMesh mesh = Mesh::create(meshData, MeshBufferType::Static, DOT_LINE_LIST);
  96. dbgCmd.mesh = mesh;
  97. dbgCmd.type = DebugDrawType::WorldSpace;
  98. dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
  99. }
  100. void DrawHelper3D::drawLineList_AA(const HCamera& camera, const Vector<Vector3>& linePoints, const Vector3& up, float width, float borderWidth,
  101. const Color& color, float timeout)
  102. {
  103. const Viewport* viewport = camera->getViewport().get();
  104. Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
  105. commands.push_back(DebugDrawCommand());
  106. DebugDrawCommand& dbgCmd = commands.back();
  107. dbgCmd.endTime = gTime().getTime() + timeout;
  108. MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>((UINT32)(linePoints.size() * 4), (UINT32)(linePoints.size() * 15), mVertexDesc);
  109. lineList_AA(linePoints, up, width, borderWidth, color, meshData, 0, 0);
  110. UINT8* positionData = meshData->getElementData(VES_POSITION);
  111. dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
  112. HMesh mesh = Mesh::create(meshData);
  113. dbgCmd.mesh = mesh;
  114. dbgCmd.type = DebugDrawType::WorldSpace;
  115. dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
  116. }
  117. void DrawHelper3D::drawAABox(const HCamera& camera, const AABox& box, const Color& color, float timeout)
  118. {
  119. const Viewport* viewport = camera->getViewport().get();
  120. Vector<DebugDrawCommand>& commands = mCommandsPerViewport[viewport];
  121. commands.push_back(DebugDrawCommand());
  122. DebugDrawCommand& dbgCmd = commands.back();
  123. dbgCmd.endTime = gTime().getTime() + timeout;
  124. MeshDataPtr meshData = bs_shared_ptr<MeshData, ScratchAlloc>(8, 36, mVertexDesc);
  125. aabox(box, meshData, 0, 0);
  126. UINT32 vertexStride = mVertexDesc->getVertexStride();
  127. UINT8* colorData = meshData->getElementData(VES_COLOR);
  128. for(UINT32 i = 0; i < meshData->getNumVertices(); i++)
  129. {
  130. UINT32* colors = (UINT32*)colorData;
  131. (*colors) = color.getAsRGBA();
  132. colorData += vertexStride;
  133. }
  134. UINT8* positionData = meshData->getElementData(VES_POSITION);
  135. dbgCmd.worldCenter = calcCenter(positionData, meshData->getNumVertices(), mVertexDesc->getVertexStride());
  136. HMesh mesh = Mesh::create(meshData);
  137. dbgCmd.mesh = mesh;
  138. dbgCmd.type = DebugDrawType::WorldSpace;
  139. dbgCmd.matInfo3D = BuiltinResources::instance().createDebugDraw3DMaterial();
  140. }
  141. void DrawHelper3D::aabox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
  142. {
  143. outVertices += (vertexOffset * vertexStride);
  144. Vector3 pt;
  145. pt = box.getCorner(AABox::FAR_LEFT_BOTTOM);
  146. memcpy(outVertices, &pt, sizeof(pt));
  147. outVertices += vertexStride;
  148. pt = box.getCorner(AABox::FAR_RIGHT_BOTTOM);
  149. memcpy(outVertices, &pt, sizeof(pt));
  150. outVertices += vertexStride;
  151. pt = box.getCorner(AABox::FAR_LEFT_TOP);
  152. memcpy(outVertices, &pt, sizeof(pt));
  153. outVertices += vertexStride;
  154. pt = box.getCorner(AABox::FAR_RIGHT_TOP);
  155. memcpy(outVertices, &pt, sizeof(pt));
  156. outVertices += vertexStride;
  157. pt = box.getCorner(AABox::NEAR_LEFT_BOTTOM);
  158. memcpy(outVertices, &pt, sizeof(pt));
  159. outVertices += vertexStride;
  160. pt = box.getCorner(AABox::NEAR_RIGHT_BOTTOM);
  161. memcpy(outVertices, &pt, sizeof(pt));
  162. outVertices += vertexStride;
  163. pt = box.getCorner(AABox::NEAR_LEFT_TOP);
  164. memcpy(outVertices, &pt, sizeof(pt));
  165. outVertices += vertexStride;
  166. pt = box.getCorner(AABox::NEAR_RIGHT_TOP);
  167. memcpy(outVertices, &pt, sizeof(pt));
  168. outVertices += vertexStride;
  169. outIndices += indexOffset;
  170. // Front
  171. outIndices[0] = vertexOffset + 6;
  172. outIndices[1] = vertexOffset + 7;
  173. outIndices[2] = vertexOffset + 5;
  174. outIndices[3] = vertexOffset + 6;
  175. outIndices[4] = vertexOffset + 5;
  176. outIndices[5] = vertexOffset + 4;
  177. // Back
  178. outIndices[6] = vertexOffset + 2;
  179. outIndices[7] = vertexOffset + 1;
  180. outIndices[8] = vertexOffset + 3;
  181. outIndices[9] = vertexOffset + 2;
  182. outIndices[10] = vertexOffset + 0;
  183. outIndices[11] = vertexOffset + 1;
  184. // Left
  185. outIndices[12] = vertexOffset + 2;
  186. outIndices[13] = vertexOffset + 6;
  187. outIndices[14] = vertexOffset + 4;
  188. outIndices[15] = vertexOffset + 2;
  189. outIndices[16] = vertexOffset + 4;
  190. outIndices[17] = vertexOffset + 0;
  191. // Right
  192. outIndices[18] = vertexOffset + 7;
  193. outIndices[19] = vertexOffset + 3;
  194. outIndices[20] = vertexOffset + 1;
  195. outIndices[21] = vertexOffset + 7;
  196. outIndices[22] = vertexOffset + 1;
  197. outIndices[23] = vertexOffset + 5;
  198. // Top
  199. outIndices[24] = vertexOffset + 6;
  200. outIndices[25] = vertexOffset + 2;
  201. outIndices[26] = vertexOffset + 3;
  202. outIndices[27] = vertexOffset + 6;
  203. outIndices[28] = vertexOffset + 3;
  204. outIndices[29] = vertexOffset + 7;
  205. // Bottom
  206. outIndices[30] = vertexOffset + 5;
  207. outIndices[31] = vertexOffset + 1;
  208. outIndices[32] = vertexOffset + 0;
  209. outIndices[33] = vertexOffset + 5;
  210. outIndices[34] = vertexOffset + 0;
  211. outIndices[35] = vertexOffset + 4;
  212. }
  213. Vector3 DrawHelper3D::calcCenter(UINT8* vertices, UINT32 numVertices, UINT32 vertexStride)
  214. {
  215. Vector3 center = Vector3::ZERO;
  216. for(UINT32 i = 0; i < numVertices; i++)
  217. {
  218. Vector3* curVert = (Vector3*)vertices;
  219. center += *curVert;
  220. vertices += vertexStride;
  221. }
  222. center /= (float)numVertices;
  223. return center;
  224. }
  225. void DrawHelper3D::line_AA(const Vector3& a, const Vector3& b, const Vector3& up, float width, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
  226. UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
  227. {
  228. Vector3 dir = b - a;
  229. dir.normalize();
  230. Vector3 right = dir.cross(up);
  231. right.normalize();
  232. Vector<Vector3> points(4);
  233. float r = width * 0.5f;
  234. dir = dir * r;
  235. right = right * r;
  236. Vector3 v0 = a - dir - right;
  237. Vector3 v1 = a - dir + right;
  238. Vector3 v2 = b + dir + right;
  239. Vector3 v3 = b + dir - right;
  240. points[0] = v0;
  241. points[1] = v1;
  242. points[2] = v2;
  243. points[3] = v3;
  244. polygon_AA(points, up, borderWidth, color, outVertices, outColors, vertexOffset, vertexStride, outIndices, indexOffset);
  245. }
  246. void DrawHelper3D::polygon_AA(const Vector<Vector3>& points, const Vector3& up, float borderWidth, const Color& color, UINT8* outVertices, UINT8* outColors,
  247. UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
  248. {
  249. UINT32 numCoords = (UINT32)points.size();
  250. outVertices += vertexOffset * vertexStride;
  251. outColors += vertexOffset * vertexStride;
  252. Vector<Vector3> tempNormals(numCoords);
  253. for (UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
  254. {
  255. const Vector3& v0 = points[j];
  256. const Vector3& v1 = points[i];
  257. Vector3 dir = v1 - v0;
  258. Vector3 right = dir.cross(up);
  259. right.normalize();
  260. tempNormals[j] = right;
  261. // Also start populating the vertex array
  262. Vector3* vertices = (Vector3*)outVertices;
  263. *vertices = v1;
  264. UINT32* colors = (UINT32*)outColors;
  265. *colors = color.getAsRGBA();
  266. outVertices += vertexStride;
  267. outColors += vertexStride;
  268. }
  269. Color transparentColor = color;
  270. transparentColor.a = 0.0f;
  271. for (UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
  272. {
  273. const Vector3& n0 = tempNormals[j];
  274. const Vector3& n1 = tempNormals[i];
  275. Vector3 avgNrm = (n0 + n1) * 0.5f;
  276. float magSqrd = avgNrm.squaredLength();
  277. if (magSqrd > 0.000001f)
  278. {
  279. float scale = 1.0f / magSqrd;
  280. if (scale > 10.0f)
  281. scale = 10.0f;
  282. avgNrm = avgNrm * scale;
  283. }
  284. Vector3 tempCoord = points[i] + avgNrm * borderWidth;
  285. // Move it to the vertex array
  286. Vector3* vertices = (Vector3*)outVertices;
  287. *vertices = tempCoord;
  288. UINT32* colors = (UINT32*)outColors;
  289. *colors = transparentColor.getAsRGBA();
  290. outVertices += vertexStride;
  291. outColors += vertexStride;
  292. }
  293. // Populate index buffer
  294. outIndices += indexOffset;
  295. UINT32 idxCnt = 0;
  296. for (UINT32 i = 0, j = numCoords - 1; i < numCoords; j = i++)
  297. {
  298. outIndices[idxCnt++] = vertexOffset + i;
  299. outIndices[idxCnt++] = vertexOffset + j;
  300. outIndices[idxCnt++] = vertexOffset + numCoords + j;
  301. outIndices[idxCnt++] = vertexOffset + numCoords + j;
  302. outIndices[idxCnt++] = vertexOffset + numCoords + i;
  303. outIndices[idxCnt++] = vertexOffset + i;
  304. }
  305. for (UINT32 i = 2; i < numCoords; ++i)
  306. {
  307. outIndices[idxCnt++] = vertexOffset + 0;
  308. outIndices[idxCnt++] = vertexOffset + i - 1;
  309. outIndices[idxCnt++] = vertexOffset + i;
  310. }
  311. }
  312. }