SSkinMeshBuffer.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #pragma once
  5. #include "IMeshBuffer.h"
  6. #include "CVertexBuffer.h"
  7. #include "CIndexBuffer.h"
  8. #include "S3DVertex.h"
  9. namespace irr
  10. {
  11. namespace scene
  12. {
  13. //! A mesh buffer able to choose between S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
  14. struct SSkinMeshBuffer final : public IMeshBuffer
  15. {
  16. //! Default constructor
  17. SSkinMeshBuffer(video::E_VERTEX_TYPE vt = video::EVT_STANDARD) :
  18. VertexType(vt), PrimitiveType(EPT_TRIANGLES),
  19. BoundingBoxNeedsRecalculated(true)
  20. {
  21. #ifdef _DEBUG
  22. setDebugName("SSkinMeshBuffer");
  23. #endif
  24. Vertices_Tangents = new SVertexBufferTangents();
  25. Vertices_2TCoords = new SVertexBufferLightMap();
  26. Vertices_Standard = new SVertexBuffer();
  27. Indices = new SIndexBuffer();
  28. }
  29. //! Constructor for standard vertices
  30. SSkinMeshBuffer(std::vector<video::S3DVertex> &&vertices, std::vector<u16> &&indices) :
  31. SSkinMeshBuffer()
  32. {
  33. Vertices_Standard->Data = std::move(vertices);
  34. Indices->Data = std::move(indices);
  35. }
  36. ~SSkinMeshBuffer()
  37. {
  38. Vertices_Tangents->drop();
  39. Vertices_2TCoords->drop();
  40. Vertices_Standard->drop();
  41. Indices->drop();
  42. }
  43. //! Get Material of this buffer.
  44. const video::SMaterial &getMaterial() const override
  45. {
  46. return Material;
  47. }
  48. //! Get Material of this buffer.
  49. video::SMaterial &getMaterial() override
  50. {
  51. return Material;
  52. }
  53. const scene::IVertexBuffer *getVertexBuffer() const override
  54. {
  55. switch (VertexType) {
  56. case video::EVT_2TCOORDS:
  57. return Vertices_2TCoords;
  58. case video::EVT_TANGENTS:
  59. return Vertices_Tangents;
  60. default:
  61. return Vertices_Standard;
  62. }
  63. }
  64. scene::IVertexBuffer *getVertexBuffer() override
  65. {
  66. switch (VertexType) {
  67. case video::EVT_2TCOORDS:
  68. return Vertices_2TCoords;
  69. case video::EVT_TANGENTS:
  70. return Vertices_Tangents;
  71. default:
  72. return Vertices_Standard;
  73. }
  74. }
  75. const scene::IIndexBuffer *getIndexBuffer() const override
  76. {
  77. return Indices;
  78. }
  79. scene::IIndexBuffer *getIndexBuffer() override
  80. {
  81. return Indices;
  82. }
  83. //! Get standard vertex at given index
  84. virtual video::S3DVertex *getVertex(u32 index)
  85. {
  86. switch (VertexType) {
  87. case video::EVT_2TCOORDS:
  88. return &Vertices_2TCoords->Data[index];
  89. case video::EVT_TANGENTS:
  90. return &Vertices_Tangents->Data[index];
  91. default:
  92. return &Vertices_Standard->Data[index];
  93. }
  94. }
  95. //! Get bounding box
  96. const core::aabbox3d<f32> &getBoundingBox() const override
  97. {
  98. return BoundingBox;
  99. }
  100. //! Set bounding box
  101. void setBoundingBox(const core::aabbox3df &box) override
  102. {
  103. BoundingBox = box;
  104. }
  105. private:
  106. template <typename T> void recalculateBoundingBox(const CVertexBuffer<T> *buf)
  107. {
  108. if (!buf->getCount()) {
  109. BoundingBox.reset(0, 0, 0);
  110. } else {
  111. auto &vertices = buf->Data;
  112. BoundingBox.reset(vertices[0].Pos);
  113. for (size_t i = 1; i < vertices.size(); ++i)
  114. BoundingBox.addInternalPoint(vertices[i].Pos);
  115. }
  116. }
  117. template <typename T1, typename T2> static void copyVertex(const T1 &src, T2 &dst)
  118. {
  119. dst.Pos = src.Pos;
  120. dst.Normal = src.Normal;
  121. dst.Color = src.Color;
  122. dst.TCoords = src.TCoords;
  123. }
  124. public:
  125. //! Recalculate bounding box
  126. void recalculateBoundingBox() override
  127. {
  128. if (!BoundingBoxNeedsRecalculated)
  129. return;
  130. BoundingBoxNeedsRecalculated = false;
  131. switch (VertexType) {
  132. case video::EVT_STANDARD: {
  133. recalculateBoundingBox(Vertices_Standard);
  134. break;
  135. }
  136. case video::EVT_2TCOORDS: {
  137. recalculateBoundingBox(Vertices_2TCoords);
  138. break;
  139. }
  140. case video::EVT_TANGENTS: {
  141. recalculateBoundingBox(Vertices_Tangents);
  142. break;
  143. }
  144. }
  145. }
  146. //! Convert to 2tcoords vertex type
  147. void convertTo2TCoords()
  148. {
  149. if (VertexType == video::EVT_STANDARD) {
  150. video::S3DVertex2TCoords Vertex;
  151. for (const auto &Vertex_Standard : Vertices_Standard->Data) {
  152. copyVertex(Vertex_Standard, Vertex);
  153. Vertices_2TCoords->Data.push_back(Vertex);
  154. }
  155. Vertices_Standard->Data.clear();
  156. VertexType = video::EVT_2TCOORDS;
  157. }
  158. }
  159. //! Convert to tangents vertex type
  160. void convertToTangents()
  161. {
  162. if (VertexType == video::EVT_STANDARD) {
  163. video::S3DVertexTangents Vertex;
  164. for (const auto &Vertex_Standard : Vertices_Standard->Data) {
  165. copyVertex(Vertex_Standard, Vertex);
  166. Vertices_Tangents->Data.push_back(Vertex);
  167. }
  168. Vertices_Standard->Data.clear();
  169. VertexType = video::EVT_TANGENTS;
  170. } else if (VertexType == video::EVT_2TCOORDS) {
  171. video::S3DVertexTangents Vertex;
  172. for (const auto &Vertex_2TCoords : Vertices_2TCoords->Data) {
  173. copyVertex(Vertex_2TCoords, Vertex);
  174. Vertices_Tangents->Data.push_back(Vertex);
  175. }
  176. Vertices_2TCoords->Data.clear();
  177. VertexType = video::EVT_TANGENTS;
  178. }
  179. }
  180. //! append the vertices and indices to the current buffer
  181. void append(const void *const vertices, u32 numVertices, const u16 *const indices, u32 numIndices) override
  182. {
  183. _IRR_DEBUG_BREAK_IF(true);
  184. }
  185. //! Describe what kind of primitive geometry is used by the meshbuffer
  186. void setPrimitiveType(E_PRIMITIVE_TYPE type) override
  187. {
  188. PrimitiveType = type;
  189. }
  190. //! Get the kind of primitive geometry which is used by the meshbuffer
  191. E_PRIMITIVE_TYPE getPrimitiveType() const override
  192. {
  193. return PrimitiveType;
  194. }
  195. //! Call this after changing the positions of any vertex.
  196. void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }
  197. SVertexBufferTangents *Vertices_Tangents;
  198. SVertexBufferLightMap *Vertices_2TCoords;
  199. SVertexBuffer *Vertices_Standard;
  200. SIndexBuffer *Indices;
  201. core::matrix4 Transformation;
  202. video::SMaterial Material;
  203. video::E_VERTEX_TYPE VertexType;
  204. core::aabbox3d<f32> BoundingBox;
  205. //! Primitive type used for rendering (triangles, lines, ...)
  206. E_PRIMITIVE_TYPE PrimitiveType;
  207. bool BoundingBoxNeedsRecalculated;
  208. };
  209. } // end namespace scene
  210. } // end namespace irr