RuntimeMeshGenericVertex.h 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  1. // Copyright 2016 Chris Conway (Koderz). All Rights Reserved.
  2. #pragma once
  3. #include "RuntimeMeshCore.h"
  4. //////////////////////////////////////////////////////////////////////////
  5. //
  6. // This file contains a generic vertex structure capable of efficiently representing a vertex
  7. // with any combination of position, normal, tangent, color, and 0-8 uv channels.
  8. //
  9. // To get around an issue with MSVC and potentially other compilers not performing
  10. // empty base class optimizations (EBO) to children in multiple inheritance,
  11. // this vertex is built via a tree of inheritance using partial specializations.
  12. //
  13. // At each tier of this tree partial specialization will choose which components
  14. // we need to add in, thereby removing entire inherited classes when we don't need them.
  15. //
  16. // Structure:
  17. // FRuntimeMeshVertex
  18. // / \
  19. // FRuntimeMeshPositionNormalTangentComponentCombiner FRuntimeMeshColorUVComponentCombiner
  20. // / \ / \
  21. // FRuntimeMeshPositionComponent \ FRuntimeMeshColorComponent \
  22. // \ \
  23. // FRuntimeMeshNormalTangentComponents FRuntimeMeshUVComponents
  24. //
  25. //
  26. //
  27. //
  28. //
  29. // Example use: (This defines a vertex with all components and 1 UV with default precision for normal/tangent and UV)
  30. //
  31. // using MyVertex = FRuntimeMeshVertex<true, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::Default>;
  32. //
  33. // MyVertex Vertex;
  34. // Vertex.Position = FVector(0,0,0);
  35. // Vertex.Normal = FVector(0,0,0);
  36. // Vertex.UV0 = FVector2D(0,0);
  37. //
  38. //
  39. //////////////////////////////////////////////////////////////////////////
  40. template<int32 TextureChannels, bool HalfPrecisionUVs, bool HasPositionComponent>
  41. RuntimeMeshVertexStructure CreateVertexStructure(const FVertexBuffer& VertexBuffer);
  42. //////////////////////////////////////////////////////////////////////////
  43. // Texture Component Type Selector
  44. //////////////////////////////////////////////////////////////////////////
  45. enum class ERuntimeMeshVertexUVType
  46. {
  47. Default = 1,
  48. HighPrecision = 2,
  49. };
  50. template<ERuntimeMeshVertexUVType UVType>
  51. struct FRuntimeMeshVertexUVsTypeSelector;
  52. template<>
  53. struct FRuntimeMeshVertexUVsTypeSelector<ERuntimeMeshVertexUVType::Default>
  54. {
  55. typedef FVector2DHalf UVsType;
  56. static const EVertexElementType VertexElementType1Channel = VET_Half2;
  57. static const EVertexElementType VertexElementType2Channel = VET_Half4;
  58. };
  59. template<>
  60. struct FRuntimeMeshVertexUVsTypeSelector<ERuntimeMeshVertexUVType::HighPrecision>
  61. {
  62. typedef FVector2D UVsType;
  63. static const EVertexElementType VertexElementType1Channel = VET_Float2;
  64. static const EVertexElementType VertexElementType2Channel = VET_Float4;
  65. };
  66. //////////////////////////////////////////////////////////////////////////
  67. // Texture Component
  68. //////////////////////////////////////////////////////////////////////////
  69. /* Defines the UV coordinates for a vertex (Defaulted to 0 channels) */
  70. template<int32 TextureChannels, typename UVType> struct FRuntimeMeshUVComponents
  71. {
  72. static_assert(TextureChannels >= 0 && TextureChannels <= 8, "You must have between 0 and 8 (inclusive) UV channels");
  73. };
  74. /* Defines the UV coordinates for a vertex (Specialized to 0 channels) */
  75. template<typename UVType> struct FRuntimeMeshUVComponents<0, UVType>
  76. {
  77. FRuntimeMeshUVComponents() { }
  78. FRuntimeMeshUVComponents(EForceInit) { }
  79. };
  80. /* Defines the UV coordinates for a vertex (Specialized to 1 channels) */
  81. template<typename UVType> struct FRuntimeMeshUVComponents<1, UVType>
  82. {
  83. UVType UV0;
  84. FRuntimeMeshUVComponents() { }
  85. FRuntimeMeshUVComponents(EForceInit) : UV0(0, 0) { }
  86. FRuntimeMeshUVComponents(const FVector2D& InUV0) : UV0(InUV0) { }
  87. };
  88. /* Defines the UV coordinates for a vertex (Specialized to 2 channels) */
  89. template<typename UVType> struct FRuntimeMeshUVComponents<2, UVType>
  90. {
  91. UVType UV0;
  92. UVType UV1;
  93. FRuntimeMeshUVComponents() { }
  94. FRuntimeMeshUVComponents(EForceInit) : UV0(0, 0), UV1(0, 0) { }
  95. FRuntimeMeshUVComponents(const FVector2D& InUV0) : UV0(InUV0), UV1(0, 0) { }
  96. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) : UV0(InUV0), UV1(InUV1) { }
  97. };
  98. /* Defines the UV coordinates for a vertex (Specialized to 3 channels) */
  99. template<typename UVType> struct FRuntimeMeshUVComponents<3, UVType>
  100. {
  101. UVType UV0;
  102. UVType UV1;
  103. UVType UV2;
  104. FRuntimeMeshUVComponents() { }
  105. FRuntimeMeshUVComponents(EForceInit) :
  106. UV0(0, 0), UV1(0, 0), UV2(0, 0) { }
  107. FRuntimeMeshUVComponents(const FVector2D& InUV0) :
  108. UV0(InUV0), UV1(0, 0), UV2(0, 0) { }
  109. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
  110. UV0(InUV0), UV1(InUV1), UV2(0, 0) { }
  111. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
  112. UV0(InUV0), UV1(InUV1), UV2(InUV2) { }
  113. };
  114. /* Defines the UV coordinates for a vertex (Specialized to 4 channels) */
  115. template<typename UVType> struct FRuntimeMeshUVComponents<4, UVType>
  116. {
  117. UVType UV0;
  118. UVType UV1;
  119. UVType UV2;
  120. UVType UV3;
  121. FRuntimeMeshUVComponents() { }
  122. FRuntimeMeshUVComponents(EForceInit) :
  123. UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0) { }
  124. FRuntimeMeshUVComponents(const FVector2D& InUV0) :
  125. UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0) { }
  126. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
  127. UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0) { }
  128. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
  129. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0) { }
  130. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
  131. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3) { }
  132. };
  133. /* Defines the UV coordinates for a vertex (Specialized to 5 channels) */
  134. template<typename UVType> struct FRuntimeMeshUVComponents<5, UVType>
  135. {
  136. UVType UV0;
  137. UVType UV1;
  138. UVType UV2;
  139. UVType UV3;
  140. UVType UV4;
  141. FRuntimeMeshUVComponents() { }
  142. FRuntimeMeshUVComponents(EForceInit) :
  143. UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0) { }
  144. FRuntimeMeshUVComponents(const FVector2D& InUV0) :
  145. UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0) { }
  146. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
  147. UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0), UV4(0, 0) { }
  148. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
  149. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0), UV4(0, 0) { }
  150. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
  151. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(0, 0) { }
  152. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  153. const FVector2D& InUV4) : UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4) { }
  154. };
  155. /* Defines the UV coordinates for a vertex (Specialized to 6 channels, Half Precision) */
  156. template<typename UVType> struct FRuntimeMeshUVComponents<6, UVType>
  157. {
  158. UVType UV0;
  159. UVType UV1;
  160. UVType UV2;
  161. UVType UV3;
  162. UVType UV4;
  163. UVType UV5;
  164. FRuntimeMeshUVComponents() { }
  165. FRuntimeMeshUVComponents(EForceInit) :
  166. UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0) { }
  167. FRuntimeMeshUVComponents(const FVector2D& InUV0) :
  168. UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0) { }
  169. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
  170. UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0) { }
  171. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
  172. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0), UV4(0, 0), UV5(0, 0) { }
  173. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
  174. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(0, 0), UV5(0, 0) { }
  175. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  176. const FVector2D& InUV4) :
  177. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(0, 0) { }
  178. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  179. const FVector2D& InUV4, const FVector2D& InUV5) :
  180. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5) { }
  181. };
  182. /* Defines the UV coordinates for a vertex (Specialized to 7 channels) */
  183. template<typename UVType> struct FRuntimeMeshUVComponents<7, UVType>
  184. {
  185. UVType UV0;
  186. UVType UV1;
  187. UVType UV2;
  188. UVType UV3;
  189. UVType UV4;
  190. UVType UV5;
  191. UVType UV6;
  192. FRuntimeMeshUVComponents() { }
  193. FRuntimeMeshUVComponents(EForceInit) :
  194. UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
  195. FRuntimeMeshUVComponents(const FVector2D& InUV0) :
  196. UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
  197. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
  198. UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
  199. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
  200. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
  201. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
  202. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(0, 0), UV5(0, 0), UV6(0, 0) { }
  203. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  204. const FVector2D& InUV4) :
  205. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(0, 0), UV6(0, 0) { }
  206. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  207. const FVector2D& InUV4, const FVector2D& InUV5) :
  208. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(0, 0) { }
  209. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  210. const FVector2D& InUV4, const FVector2D& InUV5, const FVector2D& InUV6) :
  211. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(InUV6) { }
  212. };
  213. /* Defines the UV coordinates for a vertex (Specialized to 8 channels) */
  214. template<typename UVType> struct FRuntimeMeshUVComponents<8, UVType>
  215. {
  216. UVType UV0;
  217. UVType UV1;
  218. UVType UV2;
  219. UVType UV3;
  220. UVType UV4;
  221. UVType UV5;
  222. UVType UV6;
  223. UVType UV7;
  224. FRuntimeMeshUVComponents() { }
  225. FRuntimeMeshUVComponents(EForceInit) :
  226. UV0(0, 0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
  227. FRuntimeMeshUVComponents(const FVector2D& InUV0) :
  228. UV0(InUV0), UV1(0, 0), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
  229. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1) :
  230. UV0(InUV0), UV1(InUV1), UV2(0, 0), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
  231. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2) :
  232. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(0, 0), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
  233. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3) :
  234. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(0, 0), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
  235. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  236. const FVector2D& InUV4) :
  237. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(0, 0), UV6(0, 0), UV7(0, 0) { }
  238. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  239. const FVector2D& InUV4, const FVector2D& InUV5) :
  240. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(0, 0), UV7(0, 0) { }
  241. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  242. const FVector2D& InUV4, const FVector2D& InUV5, const FVector2D& InUV6) :
  243. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(InUV6), UV7(0, 0) { }
  244. FRuntimeMeshUVComponents(const FVector2D& InUV0, const FVector2D& InUV1, const FVector2D& InUV2, const FVector2D& InUV3,
  245. const FVector2D& InUV4, const FVector2D& InUV5, const FVector2D& InUV6, const FVector2D& InUV7) :
  246. UV0(InUV0), UV1(InUV1), UV2(InUV2), UV3(InUV3), UV4(InUV4), UV5(InUV5), UV6(InUV6), UV7(InUV7) { }
  247. };
  248. //////////////////////////////////////////////////////////////////////////
  249. // Tangent Basis Component Type Selector
  250. //////////////////////////////////////////////////////////////////////////
  251. enum class ERuntimeMeshVertexTangentBasisType
  252. {
  253. Default = 1,
  254. HighPrecision = 2,
  255. };
  256. template<ERuntimeMeshVertexTangentBasisType TangentBasisType>
  257. struct FRuntimeMeshVertexTangentTypeSelector;
  258. template<>
  259. struct FRuntimeMeshVertexTangentTypeSelector<ERuntimeMeshVertexTangentBasisType::Default>
  260. {
  261. typedef FPackedNormal TangentType;
  262. static const EVertexElementType VertexElementType = VET_PackedNormal;
  263. };
  264. template<>
  265. struct FRuntimeMeshVertexTangentTypeSelector<ERuntimeMeshVertexTangentBasisType::HighPrecision>
  266. {
  267. typedef FPackedRGBA16N TangentType;
  268. static const EVertexElementType VertexElementType = VET_UShort4N;
  269. };
  270. //////////////////////////////////////////////////////////////////////////
  271. // Tangent Basis Components
  272. //////////////////////////////////////////////////////////////////////////
  273. template<bool WantsNormal, bool WantsTangent, typename TangentType>
  274. struct FRuntimeMeshNormalTangentComponents;
  275. struct RuntimeMeshNormalUtil
  276. {
  277. static void SetNormalW(FPackedNormal& Target, float Determinant)
  278. {
  279. Target.Vector.W = Determinant < 0.0f ? 0 : 255;
  280. }
  281. static void SetNormalW(FPackedRGBA16N& Target, float Determinant)
  282. {
  283. Target.W = Determinant < 0.0f ? 0 : 65535;
  284. }
  285. };
  286. template<typename TangentType>
  287. struct FRuntimeMeshNormalTangentComponents<true, false, TangentType>
  288. {
  289. TangentType Normal;
  290. FRuntimeMeshNormalTangentComponents() { }
  291. FRuntimeMeshNormalTangentComponents(EForceInit) : Normal(FVector4(0.0f, 0.0f, 1.0f, 1.0f)) { }
  292. void SetNormalAndTangent(const FVector& InNormal, const FRuntimeMeshTangent& InTangent)
  293. {
  294. Normal = InNormal;
  295. InTangent.AdjustNormal(Normal);
  296. }
  297. void SetNormalAndTangent(const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ)
  298. {
  299. Normal = InTangentZ;
  300. // store determinant of basis in w component of normal vector
  301. RuntimeMeshNormalUtil::SetNormalW(Normal, GetBasisDeterminantSign(InTangentX, InTangentY, InTangentZ));
  302. }
  303. };
  304. template<typename TangentType>
  305. struct FRuntimeMeshNormalTangentComponents<false, true, TangentType>
  306. {
  307. TangentType Tangent;
  308. FRuntimeMeshNormalTangentComponents() { }
  309. FRuntimeMeshNormalTangentComponents(EForceInit) : Tangent(FVector(1.0f, 0.0f, 0.0f)) { }
  310. void SetNormalAndTangent(const FVector& InNormal, const FRuntimeMeshTangent& InTangent)
  311. {
  312. Tangent = InTangent.TangentX;
  313. }
  314. void SetNormalAndTangent(const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ)
  315. {
  316. Tangent = InTangentX;
  317. }
  318. };
  319. template<typename TangentType>
  320. struct FRuntimeMeshNormalTangentComponents<true, true, TangentType>
  321. {
  322. TangentType Normal;
  323. TangentType Tangent;
  324. FRuntimeMeshNormalTangentComponents() { }
  325. FRuntimeMeshNormalTangentComponents(EForceInit) : Normal(FVector4(0.0f, 0.0f, 1.0f, 1.0f)), Tangent(FVector(1.0f, 0.0f, 0.0f)) { }
  326. void SetNormalAndTangent(const FVector& InNormal, const FRuntimeMeshTangent& InTangent)
  327. {
  328. Normal = InNormal;
  329. Tangent = InTangent.TangentX;
  330. InTangent.AdjustNormal(Normal);
  331. }
  332. void SetNormalAndTangent(const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ)
  333. {
  334. Normal = InTangentZ;
  335. Tangent = InTangentX;
  336. // store determinant of basis in w component of normal vector
  337. RuntimeMeshNormalUtil::SetNormalW(Normal, GetBasisDeterminantSign(InTangentX, InTangentY, InTangentZ));
  338. }
  339. };
  340. //////////////////////////////////////////////////////////////////////////
  341. // Position Component
  342. //////////////////////////////////////////////////////////////////////////
  343. template<bool WantsPosition>
  344. struct FRuntimeMeshPositionComponent;
  345. template<>
  346. struct FRuntimeMeshPositionComponent<true>
  347. {
  348. FVector Position;
  349. FRuntimeMeshPositionComponent() { }
  350. FRuntimeMeshPositionComponent(EForceInit) : Position(0.0f, 0.0f, 0.0f) { }
  351. };
  352. //////////////////////////////////////////////////////////////////////////
  353. // Color Component
  354. //////////////////////////////////////////////////////////////////////////
  355. template<bool WantsColor>
  356. struct FRuntimeMeshColorComponent;
  357. template<>
  358. struct FRuntimeMeshColorComponent<true>
  359. {
  360. FColor Color;
  361. FRuntimeMeshColorComponent() { }
  362. FRuntimeMeshColorComponent(EForceInit) : Color(FColor::White) { }
  363. };
  364. //////////////////////////////////////////////////////////////////////////
  365. // Position Normal Tangent Combiner
  366. //////////////////////////////////////////////////////////////////////////
  367. template<bool WantsPosition, bool WantsNormal, bool WantsTangent, typename TangentBasisType>
  368. struct FRuntimeMeshPositionNormalTangentComponentCombiner :
  369. public FRuntimeMeshPositionComponent<WantsPosition>,
  370. public FRuntimeMeshNormalTangentComponents<WantsNormal, WantsTangent, TangentBasisType>
  371. {
  372. FRuntimeMeshPositionNormalTangentComponentCombiner() { }
  373. FRuntimeMeshPositionNormalTangentComponentCombiner(EForceInit)
  374. : FRuntimeMeshPositionComponent<WantsPosition>(EForceInit::ForceInit)
  375. , FRuntimeMeshNormalTangentComponents<WantsNormal, WantsTangent, TangentBasisType>(EForceInit::ForceInit)
  376. { }
  377. };
  378. template<bool WantsPosition, typename TangentBasisType>
  379. struct FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, false, false, TangentBasisType> :
  380. public FRuntimeMeshPositionComponent<WantsPosition>
  381. {
  382. FRuntimeMeshPositionNormalTangentComponentCombiner() { }
  383. FRuntimeMeshPositionNormalTangentComponentCombiner(EForceInit)
  384. : FRuntimeMeshPositionComponent<WantsPosition>(EForceInit::ForceInit)
  385. { }
  386. };
  387. template<bool WantsNormal, bool WantsTangent, typename TangentBasisType>
  388. struct FRuntimeMeshPositionNormalTangentComponentCombiner<false, WantsNormal, WantsTangent, TangentBasisType> :
  389. public FRuntimeMeshNormalTangentComponents<WantsNormal, WantsTangent, TangentBasisType>
  390. {
  391. FRuntimeMeshPositionNormalTangentComponentCombiner() { }
  392. FRuntimeMeshPositionNormalTangentComponentCombiner(EForceInit)
  393. : FRuntimeMeshNormalTangentComponents<WantsNormal, WantsTangent, TangentBasisType>(EForceInit::ForceInit)
  394. { }
  395. };
  396. template<typename TangentBasisType>
  397. struct FRuntimeMeshPositionNormalTangentComponentCombiner<false, false, false, TangentBasisType>;
  398. //////////////////////////////////////////////////////////////////////////
  399. // Color UV Combiner
  400. //////////////////////////////////////////////////////////////////////////
  401. template<bool WantsColor, int32 NumWantedUVChannels, typename UVType>
  402. struct FRuntimeMeshColorUVComponentCombiner :
  403. public FRuntimeMeshColorComponent<WantsColor>,
  404. public FRuntimeMeshUVComponents<NumWantedUVChannels, UVType>
  405. {
  406. FRuntimeMeshColorUVComponentCombiner() { }
  407. FRuntimeMeshColorUVComponentCombiner(EForceInit)
  408. : FRuntimeMeshColorComponent<WantsColor>(EForceInit::ForceInit)
  409. , FRuntimeMeshUVComponents<NumWantedUVChannels, UVType>(EForceInit::ForceInit)
  410. { }
  411. };
  412. template<int32 NumWantedUVChannels, typename UVType>
  413. struct FRuntimeMeshColorUVComponentCombiner<false, NumWantedUVChannels, UVType> :
  414. public FRuntimeMeshUVComponents<NumWantedUVChannels, UVType>
  415. {
  416. FRuntimeMeshColorUVComponentCombiner() { }
  417. FRuntimeMeshColorUVComponentCombiner(EForceInit)
  418. : FRuntimeMeshUVComponents<NumWantedUVChannels, UVType>(EForceInit::ForceInit)
  419. { }
  420. };
  421. template<bool WantsColor, typename UVType>
  422. struct FRuntimeMeshColorUVComponentCombiner<WantsColor, 0, UVType> :
  423. public FRuntimeMeshColorComponent<WantsColor>
  424. {
  425. FRuntimeMeshColorUVComponentCombiner() { }
  426. FRuntimeMeshColorUVComponentCombiner(EForceInit)
  427. : FRuntimeMeshColorComponent<WantsColor>(EForceInit::ForceInit)
  428. { }
  429. };
  430. template<typename UVType>
  431. struct FRuntimeMeshColorUVComponentCombiner<false, 0, UVType>;
  432. //////////////////////////////////////////////////////////////////////////
  433. // Template Vertex Type Info Structure
  434. //////////////////////////////////////////////////////////////////////////
  435. template<bool WantsPosition, bool WantsNormal, bool WantsTangent, bool WantsColor, int32 NumWantedUVChannels,
  436. ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
  437. struct FRuntimeMeshVertexTypeInfo_GenericVertex : public FRuntimeMeshVertexTypeInfo
  438. {
  439. FRuntimeMeshVertexTypeInfo_GenericVertex(FString VertexName) :
  440. FRuntimeMeshVertexTypeInfo(
  441. FString::Printf(TEXT("RuntimeMeshVertex<%d, %d, %d, %d, %d, %d, %d>"), WantsPosition, WantsNormal, WantsTangent, WantsColor, NumWantedUVChannels, (int32)NormalTangentType, (int32)UVType),
  442. GetVertexGuid(VertexName)) { }
  443. static FGuid GetVertexGuid(FString VertexName)
  444. {
  445. uint32 TypeID = 0;
  446. TypeID = (TypeID << 1) | (WantsPosition ? 1 : 0);
  447. TypeID = (TypeID << 1) | (WantsNormal ? 1 : 0);
  448. TypeID = (TypeID << 1) | (WantsTangent ? 1 : 0);
  449. TypeID = (TypeID << 3) | (uint32)NormalTangentType;
  450. TypeID = (TypeID << 1) | (WantsColor ? 1 : 0);
  451. TypeID = (TypeID << 6) | (NumWantedUVChannels & 0xFF);
  452. TypeID = (TypeID << 3) | (uint32)UVType;
  453. FGuid Guid = FGuid(0x00FFEB44, 0x31094597, /*0x93918032*/ GetTypeHash(VertexName), (0x78C3 << 16) | TypeID);
  454. return Guid;
  455. }
  456. };
  457. //////////////////////////////////////////////////////////////////////////
  458. // Macros to create a custom vertex type based on the generic vertex and implement some common constructors
  459. //////////////////////////////////////////////////////////////////////////
  460. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_POSITION_true Position = FVector(0.0f, 0.0f, 0.0f);
  461. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_POSITION_false
  462. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_POSITION(HasPosition) RUNTIMEMESH_VERTEX_DEFAULTINIT_POSITION_##HasPosition
  463. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL_true Normal = FVector4(0.0f, 0.0f, 1.0f, 1.0f);
  464. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL_false
  465. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL(HasNormal) RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL_##HasNormal
  466. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT_true Tangent = FVector(1.0f, 0.0f, 0.0f);
  467. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT_false
  468. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT(HasTangent) RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT_##HasTangent
  469. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR_true Color = FColor::White;
  470. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR_false
  471. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(HasColor) RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR_##HasColor
  472. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_0
  473. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_1 \
  474. UV0 = FVector2D(0.0f, 0.0f);
  475. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_2 \
  476. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_1 \
  477. UV1 = FVector2D(0.0f, 0.0f);
  478. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_3 \
  479. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_2 \
  480. UV2 = FVector2D(0.0f, 0.0f);
  481. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_4 \
  482. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_3 \
  483. UV3 = FVector2D(0.0f, 0.0f);
  484. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_5 \
  485. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_4 \
  486. UV4 = FVector2D(0.0f, 0.0f);
  487. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_6 \
  488. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_5 \
  489. UV5 = FVector2D(0.0f, 0.0f);
  490. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_7 \
  491. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_6 \
  492. UV6 = FVector2D(0.0f, 0.0f);
  493. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_8 \
  494. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_7 \
  495. UV7 = FVector2D(0.0f, 0.0f);
  496. #define RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNELS(NumChannels) RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNEL_##NumChannels
  497. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_0
  498. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_1 , const FVector2D& InUV0 = FVector2D::ZeroVector
  499. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_2 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_1 , const FVector2D& InUV1 = FVector2D::ZeroVector
  500. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_3 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_2 , const FVector2D& InUV2 = FVector2D::ZeroVector
  501. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_4 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_3 , const FVector2D& InUV3 = FVector2D::ZeroVector
  502. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_5 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_4 , const FVector2D& InUV4 = FVector2D::ZeroVector
  503. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_6 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_5 , const FVector2D& InUV5 = FVector2D::ZeroVector
  504. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_7 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_6 , const FVector2D& InUV6 = FVector2D::ZeroVector
  505. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_8 RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_7 , const FVector2D& InUV7 = FVector2D::ZeroVector
  506. #define RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(NumChannels) RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNEL_##NumChannels
  507. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_0
  508. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_1 \
  509. UV0 = InUV0;
  510. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_2 \
  511. RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_1 \
  512. UV1 = InUV1;
  513. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_3 \
  514. RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_2 \
  515. UV2 = InUV2;
  516. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_4 \
  517. RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_3 \
  518. UV3 = InUV3;
  519. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_5 \
  520. RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_4 \
  521. UV4 = InUV4;
  522. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_6 \
  523. RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_5 \
  524. UV5 = InUV5;
  525. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_7 \
  526. RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_6 \
  527. UV6 = InUV6;
  528. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_8 \
  529. RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_7 \
  530. UV7 = InUV7;
  531. #define RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(NumChannels) RUNTIMEMESH_VERTEX_INIT_UVCHANNEL_##NumChannels
  532. #define RUNTIMEMESH_VERTEX_PARAMETER_POSITION_true const FVector& InPosition,
  533. #define RUNTIMEMESH_VERTEX_PARAMETER_POSITION_false
  534. #define RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) RUNTIMEMESH_VERTEX_PARAMETER_POSITION_##NeedsPosition
  535. #define RUNTIMEMESH_VERTEX_INIT_POSITION_true Position = InPosition;
  536. #define RUNTIMEMESH_VERTEX_INIT_POSITION_false
  537. #define RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) RUNTIMEMESH_VERTEX_INIT_POSITION_##NeedsPosition
  538. // PreProcessor IF with pass through for all the constructor arguments
  539. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, Condition, IfTrue) \
  540. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF_##Condition(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, IfTrue)
  541. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF_false(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, IfTrue)
  542. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF_true(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, IfTrue) IfTrue
  543. // Implementation of Position only Constructor
  544. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  545. VertexName(const FVector& InPosition) \
  546. { \
  547. RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
  548. RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL(NeedsNormal) \
  549. RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT(NeedsTangent) \
  550. RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(NeedsColor) \
  551. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNELS(UVChannelCount) \
  552. }
  553. // Defines the Position Constuctor if it's wanted
  554. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  555. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsPosition, \
  556. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  557. )
  558. // Implementation of Position/Normal Constructor
  559. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  560. VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InNormal) \
  561. { \
  562. RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
  563. Normal = InNormal; \
  564. RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT(NeedsTangent) \
  565. RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(NeedsColor) \
  566. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNELS(UVChannelCount) \
  567. }
  568. // Defines the Position/Normal Constuctor if it's wanted
  569. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  570. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
  571. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  572. )
  573. // Implementation of Position/Color Constructor
  574. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  575. VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FColor& InColor) \
  576. { \
  577. RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
  578. RUNTIMEMESH_VERTEX_DEFAULTINIT_NORMAL(NeedsNormal) \
  579. RUNTIMEMESH_VERTEX_DEFAULTINIT_TANGENT(NeedsTangent) \
  580. Color = InColor; \
  581. RUNTIMEMESH_VERTEX_DEFAULTINIT_UVCHANNELS(UVChannelCount) \
  582. }
  583. // Defines the Position/Color Constructor if it's wanted
  584. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  585. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsColor, \
  586. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  587. )
  588. // Implementation of Position/Normal/Tangent Constructor
  589. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  590. VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InNormal, const FRuntimeMeshTangent& InTangent RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(UVChannelCount)) \
  591. { \
  592. RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
  593. Normal = InNormal; \
  594. Tangent = InTangent.TangentX; \
  595. InTangent.AdjustNormal(Normal); \
  596. RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(NeedsColor) \
  597. RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(UVChannelCount) \
  598. }
  599. // Defines the Position/Normal/Tangent Constructor if it's wanted
  600. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  601. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
  602. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsTangent, \
  603. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  604. ) \
  605. )
  606. // Implementation of Position/TangentX/TangentY/TangentZ Constructor
  607. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  608. VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(UVChannelCount)) \
  609. { \
  610. RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
  611. SetNormalAndTangent(InTangentX, InTangentY, InTangentZ); \
  612. RUNTIMEMESH_VERTEX_DEFAULTINIT_COLOR(NeedsColor) \
  613. RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(UVChannelCount) \
  614. }
  615. // Defines the Position/TangentX/TangentY/TangentZ Constructor if it's wanted
  616. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  617. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
  618. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsTangent, \
  619. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  620. ) \
  621. )
  622. // Implementation of Position/Normal/Tangent Constructor
  623. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  624. VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InNormal, const FRuntimeMeshTangent& InTangent, const FColor& InColor RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(UVChannelCount)) \
  625. { \
  626. RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
  627. Normal = InNormal; \
  628. Tangent = InTangent.TangentX; \
  629. InTangent.AdjustNormal(Normal); \
  630. Color = InColor; \
  631. RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(UVChannelCount) \
  632. }
  633. // Defines the Position/Normal/Tangent Constructor if it's wanted
  634. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  635. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
  636. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsTangent, \
  637. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsColor, \
  638. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  639. ) \
  640. ) \
  641. )
  642. // Implementation of Position/TangentX/TangentY/TangentZ Constructor
  643. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  644. VertexName(RUNTIMEMESH_VERTEX_PARAMETER_POSITION(NeedsPosition) const FVector& InTangentX, const FVector& InTangentY, const FVector& InTangentZ, const FColor& InColor RUNTIMEMESH_VERTEX_PARAMETER_UVCHANNELS(UVChannelCount)) \
  645. { \
  646. RUNTIMEMESH_VERTEX_INIT_POSITION(NeedsPosition) \
  647. SetNormalAndTangent(InTangentX, InTangentY, InTangentZ); \
  648. Color = InColor; \
  649. RUNTIMEMESH_VERTEX_INIT_UVCHANNELS(UVChannelCount) \
  650. }
  651. // Defines the Position/TangentX/TangentY/TangentZ Constructor if it's wanted
  652. #define RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  653. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsNormal, \
  654. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsTangent, \
  655. RUNTIMEMESH_VERTEX_CONSTRUCTOR_DEFINITION_IF(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, NeedsColor, \
  656. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_COLOR_IMPLEMENTATION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  657. ) \
  658. ) \
  659. )
  660. #define RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION_true Ar << V.Position;
  661. #define RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION_false
  662. #define RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION(NeedsPosition) RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION_##NeedsPosition
  663. #define RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL_true Ar << V.Normal;
  664. #define RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL_false
  665. #define RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL(NeedsNormal) RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL_##NeedsNormal
  666. #define RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT_true Ar << V.Tangent;
  667. #define RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT_false
  668. #define RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT(NeedsTangent) RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT_##NeedsTangent
  669. #define RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR_true Ar << V.Color;
  670. #define RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR_false
  671. #define RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR(NeedsColor) RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR_##NeedsColor
  672. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_0
  673. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_1 \
  674. Ar << V.UV0;
  675. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_2 \
  676. RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_1 \
  677. Ar << V.UV1;
  678. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_3 \
  679. RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_2 \
  680. Ar << V.UV2;
  681. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_4 \
  682. RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_3 \
  683. Ar << V.UV3;
  684. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_5 \
  685. RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_4 \
  686. Ar << V.UV4;
  687. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_6 \
  688. RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_5 \
  689. Ar << V.UV5;
  690. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_7 \
  691. RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_6 \
  692. Ar << V.UV6;
  693. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_8 \
  694. RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_7 \
  695. Ar << V.UV7;
  696. #define RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNELS(NumChannels) RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNEL_##NumChannels
  697. #define RUNTIMEMESH_VERTEX_SERIALIZER(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount) \
  698. friend FArchive& operator<<(FArchive& Ar, VertexName & V) \
  699. { \
  700. RUNTIMEMESH_VERTEX_SERIALIZATION_POSITION(NeedsPosition) \
  701. RUNTIMEMESH_VERTEX_SERIALIZATION_NORMAL(NeedsNormal) \
  702. RUNTIMEMESH_VERTEX_SERIALIZATION_TANGENT(NeedsTangent) \
  703. RUNTIMEMESH_VERTEX_SERIALIZATION_COLOR(NeedsColor) \
  704. RUNTIMEMESH_VERTEX_SERIALIZATION_UVCHANNELS(UVChannelCount) \
  705. return Ar; \
  706. }
  707. #define DECLARE_RUNTIME_MESH_VERTEXINTERNAL(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, APIQUALIFIER) \
  708. struct APIQUALIFIER FRuntimeMeshVertexTypeInfo_##VertexName \
  709. : public FRuntimeMeshVertexTypeInfo_GenericVertex<NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType> \
  710. { \
  711. FRuntimeMeshVertexTypeInfo_##VertexName() \
  712. : FRuntimeMeshVertexTypeInfo_GenericVertex<NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType>(TEXT("")) { } \
  713. \
  714. virtual class FRuntimeMeshSectionInterface* CreateSection(bool bInNeedsPositionOnlyBuffer) const override; \
  715. }; \
  716. struct APIQUALIFIER VertexName : public FRuntimeMeshVertex<NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType> \
  717. { \
  718. static const FRuntimeMeshVertexTypeInfo_##VertexName TypeInfo; \
  719. \
  720. typedef FRuntimeMeshVertex<NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType> Super; \
  721. \
  722. VertexName() { } \
  723. \
  724. VertexName(EForceInit) : Super(EForceInit::ForceInit) { } \
  725. \
  726. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  727. \
  728. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  729. \
  730. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  731. \
  732. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  733. \
  734. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  735. \
  736. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_NORMAL_TANGENT_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  737. \
  738. RUNTIMEMESH_VERTEX_CONSTRUCTOR_POSITION_TANGENTX_TANGENTY_TANGENTZ_COLOR(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  739. \
  740. RUNTIMEMESH_VERTEX_SERIALIZER(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount) \
  741. };
  742. #define DECLARE_RUNTIME_MESH_VERTEX(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType) \
  743. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(VertexName, NeedsPosition, NeedsNormal, NeedsTangent, NeedsColor, UVChannelCount, TangentsType, UVChannelType, /**/)
  744. /* Used only for the generic vertex to create the type registration */
  745. #define DEFINE_RUNTIME_MESH_VERTEX(VertexName) \
  746. const FRuntimeMeshVertexTypeInfo_##VertexName VertexName::TypeInfo; \
  747. FRuntimeMeshVertexTypeRegistration< VertexName > FRuntimeMeshVertexTypeInfoRegistration_##VertexName; \
  748. FRuntimeMeshSectionInterface* FRuntimeMeshVertexTypeInfo_##VertexName::CreateSection(bool bInNeedsPositionOnlyBuffer) const \
  749. { \
  750. return new FRuntimeMeshSection< VertexName >(bInNeedsPositionOnlyBuffer); \
  751. }
  752. //////////////////////////////////////////////////////////////////////////
  753. // Template Vertex
  754. //////////////////////////////////////////////////////////////////////////
  755. // This version uses both sub combiners since there's at least 1 thing we need from both.
  756. template<bool WantsPosition, bool WantsNormal, bool WantsTangent, bool WantsColor, int32 NumWantedUVChannels,
  757. ERuntimeMeshVertexTangentBasisType NormalTangentType = ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType UVType = ERuntimeMeshVertexUVType::Default>
  758. struct FRuntimeMeshVertex :
  759. public FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, WantsNormal, WantsTangent, typename FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::TangentType>,
  760. public FRuntimeMeshColorUVComponentCombiner<WantsColor, NumWantedUVChannels, typename FRuntimeMeshVertexUVsTypeSelector<UVType>::UVsType>
  761. {
  762. // Make sure something is enabled
  763. static_assert((WantsPosition || WantsNormal || WantsTangent || WantsColor || NumWantedUVChannels > 0), "Invalid configuration... You must have at least 1 component enabled.");
  764. // Get vertex structure
  765. static RuntimeMeshVertexStructure GetVertexStructure(const FVertexBuffer& VertexBuffer);
  766. FRuntimeMeshVertex() { }
  767. FRuntimeMeshVertex(EForceInit)
  768. : FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, WantsNormal, WantsTangent, typename FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::TangentType>(EForceInit::ForceInit)
  769. , FRuntimeMeshColorUVComponentCombiner<WantsColor, NumWantedUVChannels, typename FRuntimeMeshVertexUVsTypeSelector<UVType>::UVsType>(EForceInit::ForceInit)
  770. { }
  771. };
  772. // This version only uses the position/normal/tangent combiner as we don't need anything from the other
  773. template<bool WantsPosition, bool WantsNormal, bool WantsTangent, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
  774. struct FRuntimeMeshVertex<WantsPosition, WantsNormal, WantsTangent, false, 0, NormalTangentType, UVType> :
  775. public FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, WantsNormal, WantsTangent, typename FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::TangentType>
  776. {
  777. // Get vertex structure
  778. static RuntimeMeshVertexStructure GetVertexStructure(const FVertexBuffer& VertexBuffer);
  779. FRuntimeMeshVertex() { }
  780. FRuntimeMeshVertex(EForceInit)
  781. : FRuntimeMeshPositionNormalTangentComponentCombiner<WantsPosition, WantsNormal, WantsTangent, typename FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::TangentType>(EForceInit::ForceInit)
  782. { }
  783. };
  784. // This version only uses the color/uv combiner as we don't need anything from the other
  785. template<bool WantsColor, int32 NumWantedUVChannels, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
  786. struct FRuntimeMeshVertex<false, false, false, WantsColor, NumWantedUVChannels, NormalTangentType, UVType> :
  787. public FRuntimeMeshColorUVComponentCombiner<WantsColor, NumWantedUVChannels, typename FRuntimeMeshVertexUVsTypeSelector<UVType>::UVsType>
  788. {
  789. // Get vertex structure
  790. static RuntimeMeshVertexStructure GetVertexStructure(const FVertexBuffer& VertexBuffer);
  791. FRuntimeMeshVertex() { }
  792. FRuntimeMeshVertex(EForceInit)
  793. : FRuntimeMeshColorUVComponentCombiner<WantsColor, NumWantedUVChannels, typename FRuntimeMeshVertexUVsTypeSelector<UVType>::UVsType>(EForceInit::ForceInit)
  794. { }
  795. };
  796. //////////////////////////////////////////////////////////////////////////
  797. // Vertex Structure Generator
  798. //////////////////////////////////////////////////////////////////////////
  799. struct FRuntimeMeshVertexUtilities
  800. {
  801. //////////////////////////////////////////////////////////////////////////
  802. // Position Component
  803. //////////////////////////////////////////////////////////////////////////
  804. template<typename RuntimeVertexType, bool WantsPosition>
  805. struct FRuntimeMeshPositionComponentUtilities
  806. {
  807. static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  808. {
  809. VertexStructure.PositionComponent = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Position, VET_Float3);
  810. }
  811. };
  812. template<typename RuntimeVertexType>
  813. struct FRuntimeMeshPositionComponentUtilities<RuntimeVertexType, false>
  814. {
  815. static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  816. {
  817. }
  818. };
  819. //////////////////////////////////////////////////////////////////////////
  820. // Normal/Tangent Components
  821. //////////////////////////////////////////////////////////////////////////
  822. template<typename RuntimeVertexType, bool WantsNormal, bool WantsTangent, ERuntimeMeshVertexTangentBasisType NormalTangentType>
  823. struct FRuntimeMeshNormalTangentComponentVertexStructure
  824. {
  825. static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  826. {
  827. VertexStructure.TangentBasisComponents[1] = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Normal,
  828. FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::VertexElementType);
  829. VertexStructure.TangentBasisComponents[0] = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Tangent,
  830. FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::VertexElementType);
  831. }
  832. };
  833. template<typename RuntimeVertexType, ERuntimeMeshVertexTangentBasisType NormalTangentType>
  834. struct FRuntimeMeshNormalTangentComponentVertexStructure<RuntimeVertexType, true, false, NormalTangentType>
  835. {
  836. static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  837. {
  838. VertexStructure.TangentBasisComponents[1] = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Normal,
  839. FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::VertexElementType);
  840. }
  841. };
  842. template<typename RuntimeVertexType, ERuntimeMeshVertexTangentBasisType NormalTangentType>
  843. struct FRuntimeMeshNormalTangentComponentVertexStructure<RuntimeVertexType, false, true, NormalTangentType>
  844. {
  845. static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  846. {
  847. VertexStructure.TangentBasisComponents[0] = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Tangent,
  848. FRuntimeMeshVertexTangentTypeSelector<NormalTangentType>::VertexElementType);
  849. }
  850. };
  851. template<typename RuntimeVertexType, ERuntimeMeshVertexTangentBasisType NormalTangentType>
  852. struct FRuntimeMeshNormalTangentComponentVertexStructure<RuntimeVertexType, false, false, NormalTangentType>
  853. {
  854. static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  855. {
  856. }
  857. };
  858. //////////////////////////////////////////////////////////////////////////
  859. // Color Component
  860. //////////////////////////////////////////////////////////////////////////
  861. template<typename RuntimeVertexType, bool WantsColor>
  862. struct FRuntimeMeshColorComponentVertexStructure
  863. {
  864. static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  865. {
  866. VertexStructure.ColorComponent = RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, Color, VET_Color);
  867. }
  868. };
  869. template<typename RuntimeVertexType>
  870. struct FRuntimeMeshColorComponentVertexStructure<RuntimeVertexType, false>
  871. {
  872. static void AddComponent(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  873. {
  874. }
  875. };
  876. //////////////////////////////////////////////////////////////////////////
  877. // UV Components
  878. //////////////////////////////////////////////////////////////////////////
  879. template<typename RuntimeVertexType, int32 NumWantedUVChannels, ERuntimeMeshVertexUVType UVType>
  880. struct FRuntimeMeshTextureChannelsVertexStructure
  881. {
  882. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  883. {
  884. }
  885. };
  886. template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
  887. struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 1, UVType>
  888. {
  889. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  890. {
  891. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType1Channel));
  892. }
  893. };
  894. template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
  895. struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 2, UVType>
  896. {
  897. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  898. {
  899. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  900. }
  901. };
  902. template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
  903. struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 3, UVType>
  904. {
  905. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  906. {
  907. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  908. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType1Channel));
  909. }
  910. };
  911. template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
  912. struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 4, UVType>
  913. {
  914. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  915. {
  916. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  917. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  918. }
  919. };
  920. template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
  921. struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 5, UVType>
  922. {
  923. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  924. {
  925. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  926. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  927. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV4, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType1Channel));
  928. }
  929. };
  930. template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
  931. struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 6, UVType>
  932. {
  933. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  934. {
  935. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  936. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  937. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV4, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  938. }
  939. };
  940. template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
  941. struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 7, UVType>
  942. {
  943. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  944. {
  945. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  946. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  947. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV4, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  948. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV6, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType1Channel));
  949. }
  950. };
  951. template<typename RuntimeVertexType, ERuntimeMeshVertexUVType UVType>
  952. struct FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, 8, UVType>
  953. {
  954. static void AddChannels(const FVertexBuffer& VertexBuffer, RuntimeMeshVertexStructure& VertexStructure)
  955. {
  956. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV0, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  957. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV2, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  958. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV4, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  959. VertexStructure.TextureCoordinates.Add(RUNTIMEMESH_VERTEXCOMPONENT(VertexBuffer, RuntimeVertexType, UV6, FRuntimeMeshVertexUVsTypeSelector<UVType>::VertexElementType2Channel));
  960. }
  961. };
  962. //////////////////////////////////////////////////////////////////////////
  963. // Vertex Structure Helper
  964. //////////////////////////////////////////////////////////////////////////
  965. template<bool WantsPosition, bool WantsNormal, bool WantsTangent, bool WantsColor, int32 NumWantedUVChannels,
  966. ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
  967. static RuntimeMeshVertexStructure CreateVertexStructure(const FVertexBuffer& VertexBuffer)
  968. {
  969. typedef FRuntimeMeshVertex<WantsPosition, WantsNormal, WantsTangent, WantsColor, NumWantedUVChannels, NormalTangentType, UVType> RuntimeVertexType;
  970. RuntimeMeshVertexStructure VertexStructure;
  971. // Add Position component if necessary
  972. FRuntimeMeshPositionComponentUtilities<RuntimeVertexType, WantsPosition>::AddComponent(VertexBuffer, VertexStructure);
  973. // Add normal and tangent components if necessary
  974. FRuntimeMeshNormalTangentComponentVertexStructure<RuntimeVertexType, WantsNormal, WantsTangent, NormalTangentType>::AddComponent(VertexBuffer, VertexStructure);
  975. // Add color component if necessary
  976. FRuntimeMeshColorComponentVertexStructure<RuntimeVertexType, WantsColor>::AddComponent(VertexBuffer, VertexStructure);
  977. // Add all texture channels
  978. FRuntimeMeshTextureChannelsVertexStructure<RuntimeVertexType, NumWantedUVChannels, UVType>::AddChannels(VertexBuffer, VertexStructure);
  979. return VertexStructure;
  980. }
  981. };
  982. // These need to be declared after FRuntimemeshVertexStructureHelper and RuntimeMeshVertexStructure to fix circular dependencies between the two
  983. template<bool WantsPosition, bool WantsNormal, bool WantsTangent, bool WantsColor, int32 NumWantedUVChannels, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
  984. RuntimeMeshVertexStructure FRuntimeMeshVertex<WantsPosition, WantsNormal, WantsTangent, WantsColor, NumWantedUVChannels, NormalTangentType, UVType>::GetVertexStructure(const FVertexBuffer& VertexBuffer)
  985. {
  986. return FRuntimeMeshVertexUtilities::CreateVertexStructure<WantsPosition, WantsNormal, WantsTangent, WantsColor, NumWantedUVChannels, NormalTangentType, UVType>(VertexBuffer);
  987. }
  988. template<bool WantsPosition, bool WantsNormal, bool WantsTangent, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
  989. RuntimeMeshVertexStructure FRuntimeMeshVertex<WantsPosition, WantsNormal, WantsTangent, false, 0, NormalTangentType, UVType>::GetVertexStructure(const FVertexBuffer& VertexBuffer)
  990. {
  991. return FRuntimeMeshVertexUtilities::CreateVertexStructure<WantsPosition, WantsNormal, WantsTangent, false, 0, NormalTangentType, UVType>(VertexBuffer);
  992. }
  993. template<bool WantsColor, int32 NumWantedUVChannels, ERuntimeMeshVertexTangentBasisType NormalTangentType, ERuntimeMeshVertexUVType UVType>
  994. RuntimeMeshVertexStructure FRuntimeMeshVertex<false, false, false, WantsColor, NumWantedUVChannels, NormalTangentType, UVType>::GetVertexStructure(const FVertexBuffer& VertexBuffer)
  995. {
  996. return FRuntimeMeshVertexUtilities::CreateVertexStructure<false, false, false, WantsColor, NumWantedUVChannels, NormalTangentType, UVType>(VertexBuffer);
  997. }
  998. //////////////////////////////////////////////////////////////////////////
  999. // Name Vertex Configurations
  1000. //////////////////////////////////////////////////////////////////////////
  1001. /** Simple vertex with 1 UV channel */
  1002. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexSimple, true, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
  1003. /** Simple vertex with 2 UV channels */
  1004. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexDualUV, true, true, true, true, 2, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
  1005. /** Simple vertex with 1 UV channel and NO position component (Meant to be used with separate position buffer) */
  1006. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexNoPosition, false, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
  1007. /** Simple vertex with 2 UV channels and NO position component (Meant to be used with separate position buffer) */
  1008. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexNoPositionDualUV, false, true, true, true, 2, ERuntimeMeshVertexTangentBasisType::Default, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
  1009. /** Simple vertex with 1 UV channel */
  1010. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexHiPrecisionNormals, true, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::HighPrecision, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
  1011. /** Simple vertex with 2 UV channels */
  1012. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexDualUVHiPrecisionNormals, true, true, true, true, 2, ERuntimeMeshVertexTangentBasisType::HighPrecision, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
  1013. /** Simple vertex with 1 UV channel and NO position component (Meant to be used with separate position buffer) */
  1014. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexNoPositionHiPrecisionNormals, false, true, true, true, 1, ERuntimeMeshVertexTangentBasisType::HighPrecision, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)
  1015. /** Simple vertex with 2 UV channels and NO position component (Meant to be used with separate position buffer) */
  1016. DECLARE_RUNTIME_MESH_VERTEXINTERNAL(FRuntimeMeshVertexNoPositionDualUVHiPrecisionNormals, false, true, true, true, 2, ERuntimeMeshVertexTangentBasisType::HighPrecision, ERuntimeMeshVertexUVType::HighPrecision, RUNTIMEMESHCOMPONENT_API)