BsMeshUtility.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. namespace bs
  6. {
  7. /** @addtogroup Utility-Core
  8. * @{
  9. */
  10. /** Normal packed in a 32-bit structure. */
  11. union PackedNormal
  12. {
  13. struct
  14. {
  15. UINT8 x;
  16. UINT8 y;
  17. UINT8 z;
  18. UINT8 w;
  19. };
  20. UINT32 packed;
  21. };
  22. /** Performs various operations on mesh geometry. */
  23. class BS_CORE_EXPORT MeshUtility
  24. {
  25. public:
  26. /**
  27. * Calculates per-vertex normals based on the provided vertices and indices.
  28. *
  29. * @param[in] vertices Set of vertices containing vertex positions.
  30. * @param[in] indices Set of indices containing indexes into vertex array for each triangle.
  31. * @param[in] numVertices Number of vertices in the @p vertices array.
  32. * @param[in] numIndices Number of indices in the @p indices array. Must be a multiple of three.
  33. * @param[out] normals Pre-allocated buffer that will contain the calculated normals. Must be the same size
  34. * as the vertex array.
  35. * @param[in] indexSize Size of a single index in the indices array, in bytes.
  36. *
  37. * @note
  38. * Vertices should be split before calling this method if there are any discontinuities. (for example a vertex on a
  39. * corner of a cube should be split into three vertices used by three triangles in order for the normals to be
  40. * valid.)
  41. */
  42. static void calculateNormals(Vector3* vertices, UINT8* indices, UINT32 numVertices,
  43. UINT32 numIndices, Vector3* normals, UINT32 indexSize = 4);
  44. /**
  45. * Calculates per-vertex tangents and bitangents based on the provided vertices, uv coordinates and indices.
  46. *
  47. * @param[in] vertices Set of vertices containing vertex positions.
  48. * @param[in] normals Set of normals to use when calculating tangents. Must the the same length as the
  49. * number of vertices.
  50. * @param[in] uv Set of UV coordinates to use when calculating tangents. Must the the same length as
  51. * the number of vertices.
  52. * @param[in] indices Set of indices containing indexes into vertex array for each triangle.
  53. * @param[in] numVertices Number of vertices in the @p vertices, @p normals and @p uv arrays.
  54. * @param[in] numIndices Number of indices in the @p indices array. Must be a multiple of three.
  55. * @param[out] tangents Pre-allocated buffer that will contain the calculated tangents. Must be the same
  56. * size as the vertex array.
  57. * @param[out] bitangents Pre-allocated buffer that will contain the calculated bitangents. Must be the same
  58. * size as the vertex array.
  59. * @param[in] indexSize Size of a single index in the indices array, in bytes.
  60. * @param[in] vertexStride Number of bytes to advance the @p vertices, @p normals and @p uv arrays with each
  61. * vertex. If set to zero them each array is advanced according to its own size.
  62. *
  63. * @note
  64. * Vertices should be split before calling this method if there are any discontinuities. (for example a vertex on a
  65. * corner of a cube should be split into three vertices used by three triangles in order for the normals to be
  66. * valid.)
  67. */
  68. static void calculateTangents(Vector3* vertices, Vector3* normals, Vector2* uv, UINT8* indices, UINT32 numVertices,
  69. UINT32 numIndices, Vector3* tangents, Vector3* bitangents, UINT32 indexSize = 4, UINT32 vertexStride = 0);
  70. /**
  71. * Calculates per-vertex tangent space (normal, tangent, bitangent) based on the provided vertices, uv coordinates
  72. * and indices.
  73. *
  74. * @param[in] vertices Set of vertices containing vertex positions.
  75. * @param[in] uv Set of UV coordinates to use when calculating tangents.
  76. * @param[in] indices Set of indices containing indexes into vertex array for each triangle.
  77. * @param[in] numVertices Number of vertices in the "vertices" array.
  78. * @param[in] numIndices Number of indices in the "indices" array. Must be a multiple of three.
  79. * @param[out] normals Pre-allocated buffer that will contain the calculated normals. Must be the same size
  80. * as the vertex array.
  81. * @param[out] tangents Pre-allocated buffer that will contain the calculated tangents. Must be the same size
  82. * as the vertex array.
  83. * @param[out] bitangents Pre-allocated buffer that will contain the calculated bitangents. Must be the same size
  84. * as the vertex array.
  85. * @param[in] indexSize Size of a single index in the indices array, in bytes.
  86. *
  87. * @note
  88. * Vertices should be split before calling this method if there are any discontinuities. (for example. a vertex on
  89. * a corner of a cube should be split into three vertices used by three triangles in order for the normals to be
  90. * valid.)
  91. */
  92. static void calculateTangentSpace(Vector3* vertices, Vector2* uv, UINT8* indices, UINT32 numVertices,
  93. UINT32 numIndices, Vector3* normals, Vector3* tangents, Vector3* bitangents, UINT32 indexSize = 4);
  94. /**
  95. * Clips a set of two-dimensional vertices and uv coordinates against a set of arbitrary planes.
  96. *
  97. * @param[in] vertices A set of vertices in Vector2 format. Each vertex should be @p vertexStride bytes
  98. * from each other.
  99. * @param[in] uvs A set of UV coordinates in Vector2 format. Each coordinate should be
  100. * @p vertexStride bytes from each other. Can be null if UV is not needed.
  101. * @param[in] numTris Number of triangles to clip (must be number of vertices/uvs / 3).
  102. * @param[in] vertexStride Distance in bytes between two separate vertex or UV values in the provided
  103. * @p vertices and @p uvs buffers.
  104. * @param[in] clipPlanes A set of planes to clip the vertices against. Since the vertices are
  105. * two-dimensional the plane's Z coordinate should be zero.
  106. * @param[in] writeCallback Callback that will be triggered when clipped vertices and UV coordinates are
  107. * generated and need to be stored. Vertices are always generate in tuples of
  108. * three, forming a single triangle.
  109. */
  110. static void clip2D(UINT8* vertices, UINT8* uvs, UINT32 numTris, UINT32 vertexStride, const Vector<Plane>& clipPlanes,
  111. const std::function<void(Vector2*, Vector2*, UINT32)>& writeCallback);
  112. /**
  113. * Clips a set of three-dimensional vertices and uv coordinates against a set of arbitrary planes.
  114. *
  115. * @param[in] vertices A set of vertices in Vector3 format. Each vertex should be @p vertexStride bytes
  116. * from each other.
  117. * @param[in] uvs A set of UV coordinates in Vector2 format. Each coordinate should be
  118. * @p vertexStride bytes from each other. Can be null if UV is not needed.
  119. * @param[in] numTris Number of triangles to clip (must be number of vertices/uvs / 3).
  120. * @param[in] vertexStride Distance in bytes between two separate vertex or UV values in the provided
  121. * @p vertices and @p uvs buffers.
  122. * @param[in] clipPlanes A set of planes to clip the vertices against.
  123. * @param[in] writeCallback Callback that will be triggered when clipped vertices and UV coordinates are
  124. * generated and need to be stored. Vertices are always generate in tuples of
  125. * three, forming a single triangle.
  126. */
  127. static void clip3D(UINT8* vertices, UINT8* uvs, UINT32 numTris, UINT32 vertexStride, const Vector<Plane>& clipPlanes,
  128. const std::function<void(Vector3*, Vector2*, UINT32)>& writeCallback);
  129. /**
  130. * Encodes normals from 32-bit float format into 4D 8-bit packed format.
  131. *
  132. * @param[in] source Buffer containing data to encode. Must have @p count entries.
  133. * @param[out] destination Buffer to output the data to. Must have @p count entries, each 32-bits.
  134. * @param[in] count Number of entries in the @p source and @p destination arrays.
  135. * @param[in] inStride Distance between two entries in the @p source buffer, in bytes.
  136. * @param[in] outStride Distance between two entries in the @p destination buffer, in bytes.
  137. */
  138. static void packNormals(Vector3* source, UINT8* destination, UINT32 count, UINT32 inStride, UINT32 outStride);
  139. /**
  140. * Encodes normals from 32-bit float format into 4D 8-bit packed format.
  141. *
  142. * @param[in] source Buffer containing data to encode. Must have @p count entries.
  143. * @param[out] destination Buffer to output the data to. Must have @p count entries, each 32-bits.
  144. * @param[in] count Number of entries in the @p source and @p destination arrays.
  145. * @param[in] inStride Distance between two entries in the @p source buffer, in bytes.
  146. * @param[in] outStride Distance between two entries in the @p destination buffer, in bytes.
  147. */
  148. static void packNormals(Vector4* source, UINT8* destination, UINT32 count, UINT32 inStride, UINT32 outStride);
  149. /**
  150. * Decodes normals from 4D 8-bit packed format into a 32-bit float format.
  151. *
  152. * @param[in] source Buffer containing data to encode. Must have @p count entries, each 32-bits.
  153. * @param[out] destination Buffer to output the data to. Must have @p count entries.
  154. * @param[in] count Number of entries in the @p source and @p destination arrays.
  155. * @param[in] stride Distance between two entries in the @p source buffer, in bytes.
  156. */
  157. static void unpackNormals(UINT8* source, Vector3* destination, UINT32 count, UINT32 stride);
  158. /**
  159. * Decodes normals from 4D 8-bit packed format into a 32-bit float format.
  160. *
  161. * @param[in] source Buffer containing data to encode. Must have @p count entries, each 32-bits.
  162. * @param[out] destination Buffer to output the data to. Must have @p count entries.
  163. * @param[in] count Number of entries in the @p source and @p destination arrays.
  164. * @param[in] stride Distance between two entries in the @p source buffer, in bytes.
  165. */
  166. static void unpackNormals(UINT8* source, Vector4* destination, UINT32 count, UINT32 stride);
  167. };
  168. /** @} */
  169. }