metaballs.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. /*
  2. * Copyright 2011-2025 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  4. */
  5. #include "common.h"
  6. #include "bgfx_utils.h"
  7. #include "imgui/imgui.h"
  8. #include <bgfx/embedded_shader.h>
  9. // embedded shaders
  10. #include "vs_metaballs.bin.h"
  11. #include "fs_metaballs.bin.h"
  12. namespace
  13. {
  14. static const bgfx::EmbeddedShader s_embeddedShaders[] =
  15. {
  16. BGFX_EMBEDDED_SHADER(vs_metaballs),
  17. BGFX_EMBEDDED_SHADER(fs_metaballs),
  18. BGFX_EMBEDDED_SHADER_END()
  19. };
  20. struct PosNormalColorVertex
  21. {
  22. float m_pos[3];
  23. float m_normal[3];
  24. uint32_t m_abgr;
  25. static void init()
  26. {
  27. ms_layout
  28. .begin()
  29. .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
  30. .add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float)
  31. .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
  32. .end();
  33. };
  34. static bgfx::VertexLayout ms_layout;
  35. };
  36. bgfx::VertexLayout PosNormalColorVertex::ms_layout;
  37. struct Grid
  38. {
  39. Grid()
  40. : m_val(0.0f)
  41. {
  42. m_normal[0] = 0.0f;
  43. m_normal[1] = 0.0f;
  44. m_normal[2] = 0.0f;
  45. }
  46. float m_val;
  47. float m_normal[3];
  48. };
  49. // Reference(s):
  50. // - Polygonising a scalar field
  51. // https://web.archive.org/web/20181127124338/http://paulbourke.net/geometry/polygonise/
  52. static const uint16_t s_edges[256] =
  53. {
  54. 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
  55. 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
  56. 0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
  57. 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
  58. 0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c,
  59. 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
  60. 0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac,
  61. 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
  62. 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
  63. 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
  64. 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc,
  65. 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
  66. 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c,
  67. 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
  68. 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc,
  69. 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
  70. 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
  71. 0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
  72. 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
  73. 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
  74. 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
  75. 0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
  76. 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
  77. 0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
  78. 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
  79. 0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
  80. 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
  81. 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
  82. 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
  83. 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
  84. 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
  85. 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000,
  86. };
  87. static const int8_t s_indices[256][16] =
  88. {
  89. { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  90. { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  91. { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  92. { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  93. { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  94. { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  95. { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  96. { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
  97. { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  98. { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  99. { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  100. { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
  101. { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  102. { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
  103. { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
  104. { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  105. { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  106. { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  107. { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  108. { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
  109. { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  110. { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 },
  111. { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
  112. { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
  113. { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  114. { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
  115. { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
  116. { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 },
  117. { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 },
  118. { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 },
  119. { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
  120. { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
  121. { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  122. { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  123. { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  124. { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
  125. { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  126. { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
  127. { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
  128. { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 },
  129. { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  130. { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
  131. { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
  132. { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 },
  133. { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 },
  134. { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 },
  135. { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
  136. { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
  137. { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  138. { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
  139. { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
  140. { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  141. { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 },
  142. { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 },
  143. { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 },
  144. { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
  145. { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 },
  146. { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
  147. { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 },
  148. { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
  149. { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 },
  150. { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 },
  151. { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 },
  152. { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  153. { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  154. { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  155. { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  156. { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
  157. { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  158. { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 },
  159. { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
  160. { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 },
  161. { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  162. { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
  163. { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
  164. { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 },
  165. { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
  166. { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
  167. { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 },
  168. { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
  169. { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  170. { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 },
  171. { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
  172. { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
  173. { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 },
  174. { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 },
  175. { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 },
  176. { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 },
  177. { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
  178. { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
  179. { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 },
  180. { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 },
  181. { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
  182. { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 },
  183. { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 },
  184. { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 },
  185. { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  186. { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 },
  187. { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
  188. { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
  189. { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
  190. { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 },
  191. { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  192. { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
  193. { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 },
  194. { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 },
  195. { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
  196. { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 },
  197. { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 },
  198. { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 },
  199. { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
  200. { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  201. { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
  202. { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 },
  203. { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 },
  204. { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
  205. { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
  206. { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 },
  207. { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
  208. { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  209. { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
  210. { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 },
  211. { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 },
  212. { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 },
  213. { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 },
  214. { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  215. { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 },
  216. { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  217. { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  218. { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  219. { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  220. { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
  221. { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  222. { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
  223. { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
  224. { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 },
  225. { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  226. { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
  227. { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 },
  228. { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 },
  229. { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
  230. { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 },
  231. { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 },
  232. { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
  233. { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  234. { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
  235. { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 },
  236. { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 },
  237. { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 },
  238. { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 },
  239. { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 },
  240. { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 },
  241. { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
  242. { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  243. { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 },
  244. { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
  245. { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 },
  246. { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
  247. { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 },
  248. { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  249. { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  250. { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
  251. { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
  252. { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 },
  253. { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
  254. { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 },
  255. { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 },
  256. { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 },
  257. { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 },
  258. { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 },
  259. { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 },
  260. { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 },
  261. { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 },
  262. { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 },
  263. { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 },
  264. { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 },
  265. { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
  266. { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 },
  267. { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 },
  268. { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
  269. { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 },
  270. { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 },
  271. { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 },
  272. { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 },
  273. { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 },
  274. { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
  275. { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 },
  276. { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  277. { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 },
  278. { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 },
  279. { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  280. { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  281. { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  282. { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 },
  283. { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 },
  284. { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 },
  285. { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
  286. { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 },
  287. { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 },
  288. { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 },
  289. { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
  290. { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 },
  291. { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 },
  292. { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 },
  293. { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  294. { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
  295. { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
  296. { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  297. { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
  298. { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 },
  299. { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 },
  300. { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 },
  301. { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 },
  302. { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 },
  303. { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 },
  304. { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  305. { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 },
  306. { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
  307. { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 },
  308. { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 },
  309. { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
  310. { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  311. { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 },
  312. { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  313. { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
  314. { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 },
  315. { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 },
  316. { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 },
  317. { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 },
  318. { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 },
  319. { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
  320. { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 },
  321. { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 },
  322. { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 },
  323. { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 },
  324. { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  325. { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
  326. { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 },
  327. { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  328. { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  329. { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  330. { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
  331. { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
  332. { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  333. { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
  334. { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 },
  335. { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  336. { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  337. { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
  338. { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  339. { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 },
  340. { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  341. { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  342. { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  343. { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  344. { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
  345. };
  346. static const float s_cube[8][3] =
  347. {
  348. { 0.0f, 1.0f, 1.0f }, // 0
  349. { 1.0f, 1.0f, 1.0f }, // 1
  350. { 1.0f, 1.0f, 0.0f }, // 2
  351. { 0.0f, 1.0f, 0.0f }, // 3
  352. { 0.0f, 0.0f, 1.0f }, // 4
  353. { 1.0f, 0.0f, 1.0f }, // 5
  354. { 1.0f, 0.0f, 0.0f }, // 6
  355. { 0.0f, 0.0f, 0.0f }, // 7
  356. };
  357. float vertLerp(float* _result, float _iso, uint32_t _idx0, float _v0, uint32_t _idx1, float _v1)
  358. {
  359. const float* edge0 = s_cube[_idx0];
  360. const float* edge1 = s_cube[_idx1];
  361. if (bx::abs(_iso-_v1) < 0.00001f)
  362. {
  363. _result[0] = edge1[0];
  364. _result[1] = edge1[1];
  365. _result[2] = edge1[2];
  366. return 1.0f;
  367. }
  368. if (bx::abs(_iso-_v0) < 0.00001f
  369. || bx::abs(_v0-_v1) < 0.00001f)
  370. {
  371. _result[0] = edge0[0];
  372. _result[1] = edge0[1];
  373. _result[2] = edge0[2];
  374. return 0.0f;
  375. }
  376. float lerp = (_iso - _v0) / (_v1 - _v0);
  377. _result[0] = edge0[0] + lerp * (edge1[0] - edge0[0]);
  378. _result[1] = edge0[1] + lerp * (edge1[1] - edge0[1]);
  379. _result[2] = edge0[2] + lerp * (edge1[2] - edge0[2]);
  380. return lerp;
  381. }
  382. uint32_t triangulate(
  383. uint8_t* _result
  384. , uint32_t _stride
  385. , const float* _rgb
  386. , const float* _xyz
  387. , const Grid* _val[8]
  388. , float _iso
  389. , float _scale
  390. )
  391. {
  392. uint8_t cubeindex = 0;
  393. cubeindex |= (_val[0]->m_val < _iso) ? 0x01 : 0;
  394. cubeindex |= (_val[1]->m_val < _iso) ? 0x02 : 0;
  395. cubeindex |= (_val[2]->m_val < _iso) ? 0x04 : 0;
  396. cubeindex |= (_val[3]->m_val < _iso) ? 0x08 : 0;
  397. cubeindex |= (_val[4]->m_val < _iso) ? 0x10 : 0;
  398. cubeindex |= (_val[5]->m_val < _iso) ? 0x20 : 0;
  399. cubeindex |= (_val[6]->m_val < _iso) ? 0x40 : 0;
  400. cubeindex |= (_val[7]->m_val < _iso) ? 0x80 : 0;
  401. if (0 == s_edges[cubeindex])
  402. {
  403. return 0;
  404. }
  405. float verts[12][6];
  406. uint16_t flags = s_edges[cubeindex];
  407. for (uint32_t ii = 0; ii < 12; ++ii)
  408. {
  409. if (flags & (1<<ii) )
  410. {
  411. uint32_t idx0 = ii&7;
  412. uint32_t idx1 = "\x1\x2\x3\x0\x5\x6\x7\x4\x4\x5\x6\x7"[ii];
  413. float* vertex = verts[ii];
  414. float lerp = vertLerp(vertex, _iso, idx0, _val[idx0]->m_val, idx1, _val[idx1]->m_val);
  415. const float* na = _val[idx0]->m_normal;
  416. const float* nb = _val[idx1]->m_normal;
  417. vertex[3] = na[0] + lerp * (nb[0] - na[0]);
  418. vertex[4] = na[1] + lerp * (nb[1] - na[1]);
  419. vertex[5] = na[2] + lerp * (nb[2] - na[2]);
  420. }
  421. }
  422. const float dr = _rgb[3] - _rgb[0];
  423. const float dg = _rgb[4] - _rgb[1];
  424. const float db = _rgb[5] - _rgb[2];
  425. uint32_t num = 0;
  426. const int8_t* indices = s_indices[cubeindex];
  427. for (uint32_t ii = 0; indices[ii] != -1; ++ii)
  428. {
  429. const float* vertex = verts[uint8_t(indices[ii])];
  430. float* xyz = (float*)_result;
  431. xyz[0] = _xyz[0] + vertex[0]*_scale;
  432. xyz[1] = _xyz[1] + vertex[1]*_scale;
  433. xyz[2] = _xyz[2] + vertex[2]*_scale;
  434. xyz[3] = vertex[3]*_scale;
  435. xyz[4] = vertex[4]*_scale;
  436. xyz[5] = vertex[5]*_scale;
  437. uint32_t rr = uint8_t( (_rgb[0] + vertex[0]*dr)*255.0f);
  438. uint32_t gg = uint8_t( (_rgb[1] + vertex[1]*dg)*255.0f);
  439. uint32_t bb = uint8_t( (_rgb[2] + vertex[2]*db)*255.0f);
  440. uint32_t* abgr = (uint32_t*)&_result[24];
  441. *abgr = 0xff000000
  442. | (bb<<16)
  443. | (gg<<8)
  444. | rr
  445. ;
  446. _result += _stride;
  447. ++num;
  448. }
  449. return num;
  450. }
  451. constexpr uint32_t kMaxDims = 32;
  452. constexpr float kMaxDimsF = float(kMaxDims);
  453. class ExampleMetaballs : public entry::AppI
  454. {
  455. public:
  456. ExampleMetaballs(const char* _name, const char* _description, const char* _url)
  457. : entry::AppI(_name, _description, _url)
  458. {
  459. }
  460. void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
  461. {
  462. Args args(_argc, _argv);
  463. m_width = _width;
  464. m_height = _height;
  465. m_debug = BGFX_DEBUG_NONE;
  466. m_reset = BGFX_RESET_VSYNC;
  467. bgfx::Init init;
  468. init.type = args.m_type;
  469. init.vendorId = args.m_pciId;
  470. init.platformData.nwh = entry::getNativeWindowHandle(entry::kDefaultWindowHandle);
  471. init.platformData.ndt = entry::getNativeDisplayHandle();
  472. init.platformData.type = entry::getNativeWindowHandleType();
  473. init.resolution.width = m_width;
  474. init.resolution.height = m_height;
  475. init.resolution.reset = m_reset;
  476. bgfx::init(init);
  477. // Enable debug text.
  478. bgfx::setDebug(m_debug);
  479. // Set view 0 clear state.
  480. bgfx::setViewClear(0
  481. , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
  482. , 0x303030ff
  483. , 1.0f
  484. , 0
  485. );
  486. // Create vertex stream declaration.
  487. PosNormalColorVertex::init();
  488. bgfx::RendererType::Enum type = bgfx::getRendererType();
  489. bgfx::ShaderHandle vsh = bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_metaballs");
  490. bgfx::ShaderHandle fsh = bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_metaballs");
  491. // Create program from shaders.
  492. m_program = bgfx::createProgram(vsh, fsh, true /* destroy shaders when program is destroyed */);
  493. m_grid = new Grid[kMaxDims*kMaxDims*kMaxDims];
  494. m_timeOffset = bx::getHPCounter();
  495. imguiCreate();
  496. }
  497. int shutdown() override
  498. {
  499. imguiDestroy();
  500. delete [] m_grid;
  501. // Cleanup.
  502. bgfx::destroy(m_program);
  503. // Shutdown bgfx.
  504. bgfx::shutdown();
  505. return 0;
  506. }
  507. bool update() override
  508. {
  509. const uint32_t ypitch = kMaxDims;
  510. const uint32_t zpitch = kMaxDims*kMaxDims;
  511. if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
  512. {
  513. imguiBeginFrame(m_mouseState.m_mx
  514. , m_mouseState.m_my
  515. , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
  516. | (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
  517. | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
  518. , m_mouseState.m_mz
  519. , uint16_t(m_width)
  520. , uint16_t(m_height)
  521. );
  522. showExampleDialog(this);
  523. ImGui::SetNextWindowPos(
  524. ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f)
  525. , ImGuiCond_FirstUseEver
  526. );
  527. ImGui::SetNextWindowSize(
  528. ImVec2(m_width / 5.0f, m_height / 7.0f)
  529. , ImGuiCond_FirstUseEver
  530. );
  531. ImGui::Begin("Settings"
  532. , NULL
  533. , 0
  534. );
  535. static float iso = 0.75f;
  536. ImGui::SliderFloat("ISO", &iso, 0.1f, 4.0f);
  537. static uint32_t numDims = kMaxDims;
  538. ImGui::SliderInt("Size", (int*)&numDims, 8, kMaxDims);
  539. ImGui::End();
  540. const float numDimsF = float(numDims);
  541. const float scale = kMaxDimsF/numDimsF;
  542. const float invDim = 1.0f/(numDimsF-1.0f);
  543. // Set view 0 default viewport.
  544. bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
  545. // This dummy draw call is here to make sure that view 0 is cleared
  546. // if no other draw calls are submitted to view 0.
  547. bgfx::touch(0);
  548. int64_t now = bx::getHPCounter();
  549. static int64_t last = now;
  550. const int64_t frameTime = now - last;
  551. last = now;
  552. const double freq = double(bx::getHPFrequency() );
  553. const double toMs = 1000.0/freq;
  554. float time = (float)( (now - m_timeOffset)/double(bx::getHPFrequency() ) );
  555. const bx::Vec3 at = { 0.0f, 0.0f, 0.0f };
  556. const bx::Vec3 eye = { 0.0f, 0.0f, -50.0f };
  557. // Set view and projection matrix for view 0.
  558. {
  559. float view[16];
  560. bx::mtxLookAt(view, eye, at);
  561. float proj[16];
  562. bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth);
  563. bgfx::setViewTransform(0, view, proj);
  564. // Set view 0 default viewport.
  565. bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
  566. }
  567. // Stats.
  568. uint32_t numVertices = 0;
  569. int64_t profUpdate = 0;
  570. int64_t profNormal = 0;
  571. int64_t profTriangulate = 0;
  572. // Allocate 32K vertices in transient vertex buffer.
  573. uint32_t maxVertices = (32<<10);
  574. bgfx::TransientVertexBuffer tvb;
  575. bgfx::allocTransientVertexBuffer(&tvb, maxVertices, PosNormalColorVertex::ms_layout);
  576. const uint32_t numSpheres = 16;
  577. float sphere[numSpheres][4];
  578. for (uint32_t ii = 0; ii < numSpheres; ++ii)
  579. {
  580. sphere[ii][0] = bx::sin(time*(ii*0.21f)+ii*0.37f) * (kMaxDimsF * 0.5f - 8.0f);
  581. sphere[ii][1] = bx::sin(time*(ii*0.37f)+ii*0.67f) * (kMaxDimsF * 0.5f - 8.0f);
  582. sphere[ii][2] = bx::cos(time*(ii*0.11f)+ii*0.13f) * (kMaxDimsF * 0.5f - 8.0f);
  583. sphere[ii][3] = 1.0f/(3.0f + (bx::sin(time*(ii*0.13f) )*0.5f+0.5f)*0.9f );
  584. }
  585. profUpdate = bx::getHPCounter();
  586. for (uint32_t zz = 0; zz < numDims; ++zz)
  587. {
  588. for (uint32_t yy = 0; yy < numDims; ++yy)
  589. {
  590. uint32_t offset = (zz*kMaxDims+yy)*kMaxDims;
  591. for (uint32_t xx = 0; xx < numDims; ++xx)
  592. {
  593. uint32_t xoffset = offset + xx;
  594. float dist = 0.0f;
  595. float prod = 1.0f;
  596. for (uint32_t ii = 0; ii < numSpheres; ++ii)
  597. {
  598. const float* pos = sphere[ii];
  599. float dx = pos[0] - (-kMaxDimsF*0.5f + float(xx)*scale);
  600. float dy = pos[1] - (-kMaxDimsF*0.5f + float(yy)*scale);
  601. float dz = pos[2] - (-kMaxDimsF*0.5f + float(zz)*scale);
  602. float invR = pos[3];
  603. float dot = dx*dx + dy*dy + dz*dz;
  604. dot *= bx::square(invR);
  605. dist *= dot;
  606. dist += prod;
  607. prod *= dot;
  608. }
  609. m_grid[xoffset].m_val = dist / prod - 1.0f;
  610. }
  611. }
  612. }
  613. profUpdate = bx::getHPCounter() - profUpdate;
  614. profNormal = bx::getHPCounter();
  615. for (uint32_t zz = 1; zz < numDims-1; ++zz)
  616. {
  617. for (uint32_t yy = 1; yy < numDims-1; ++yy)
  618. {
  619. uint32_t offset = (zz*kMaxDims+yy)*kMaxDims;
  620. for (uint32_t xx = 1; xx < numDims-1; ++xx)
  621. {
  622. uint32_t xoffset = offset + xx;
  623. Grid* grid = m_grid;
  624. const bx::Vec3 normal =
  625. {
  626. grid[xoffset-1 ].m_val - grid[xoffset+1 ].m_val,
  627. grid[xoffset-ypitch].m_val - grid[xoffset+ypitch].m_val,
  628. grid[xoffset-zpitch].m_val - grid[xoffset+zpitch].m_val,
  629. };
  630. bx::store(grid[xoffset].m_normal, bx::normalize(normal) );
  631. }
  632. }
  633. }
  634. profNormal = bx::getHPCounter() - profNormal;
  635. profTriangulate = bx::getHPCounter();
  636. PosNormalColorVertex* vertex = (PosNormalColorVertex*)tvb.data;
  637. for (uint32_t zz = 0; zz < numDims-1 && numVertices+12 < maxVertices; ++zz)
  638. {
  639. float rgb[6];
  640. rgb[2] = zz*invDim;
  641. rgb[5] = (zz+1)*invDim;
  642. for (uint32_t yy = 0; yy < numDims-1 && numVertices+12 < maxVertices; ++yy)
  643. {
  644. uint32_t offset = (zz*kMaxDims+yy)*kMaxDims;
  645. rgb[1] = yy*invDim;
  646. rgb[4] = (yy+1)*invDim;
  647. for (uint32_t xx = 0; xx < numDims-1 && numVertices+12 < maxVertices; ++xx)
  648. {
  649. uint32_t xoffset = offset + xx;
  650. rgb[0] = xx*invDim;
  651. rgb[3] = (xx+1)*invDim;
  652. float pos[3] =
  653. {
  654. -kMaxDimsF*0.5f + float(xx)*scale,
  655. -kMaxDimsF*0.5f + float(yy)*scale,
  656. -kMaxDimsF*0.5f + float(zz)*scale,
  657. };
  658. const Grid* grid = m_grid;
  659. const Grid* val[8] = {
  660. &grid[xoffset+zpitch+ypitch ],
  661. &grid[xoffset+zpitch+ypitch+1],
  662. &grid[xoffset+ypitch+1 ],
  663. &grid[xoffset+ypitch ],
  664. &grid[xoffset+zpitch ],
  665. &grid[xoffset+zpitch+1 ],
  666. &grid[xoffset+1 ],
  667. &grid[xoffset ],
  668. };
  669. uint32_t num = triangulate(
  670. (uint8_t*)vertex
  671. , PosNormalColorVertex::ms_layout.getStride()
  672. , rgb
  673. , pos
  674. , val
  675. , iso
  676. , scale
  677. );
  678. vertex += num;
  679. numVertices += num;
  680. }
  681. }
  682. }
  683. profTriangulate = bx::getHPCounter() - profTriangulate;
  684. float mtx[16];
  685. bx::mtxRotateXY(mtx, time*0.67f, time);
  686. // Set model matrix for rendering.
  687. bgfx::setTransform(mtx);
  688. // Set vertex and index buffer.
  689. bgfx::setVertexBuffer(0, &tvb, 0, numVertices);
  690. // Set render states.
  691. bgfx::setState(BGFX_STATE_DEFAULT);
  692. // Submit primitive for rendering to view 0.
  693. bgfx::submit(0, m_program);
  694. // Display stats.
  695. ImGui::SetNextWindowPos(
  696. ImVec2(m_width - m_width / 5.0f - 10.0f, m_height / 7.0f + 30.0f)
  697. , ImGuiCond_FirstUseEver
  698. );
  699. ImGui::SetNextWindowSize(
  700. ImVec2(m_width / 5.0f, m_height / 4.0f)
  701. , ImGuiCond_FirstUseEver
  702. );
  703. ImGui::Begin("Stats"
  704. , NULL
  705. , 0
  706. );
  707. ImGui::Text("Num vertices:"); ImGui::SameLine(100); ImGui::Text("%5d (%6.4f%%)", numVertices, float(numVertices)/maxVertices * 100);
  708. ImGui::Text("Update:"); ImGui::SameLine(100); ImGui::Text("% 7.3f[ms]", double(profUpdate)*toMs);
  709. ImGui::Text("Calc normals:"); ImGui::SameLine(100); ImGui::Text("% 7.3f[ms]", double(profNormal)*toMs);
  710. ImGui::Text("Triangulate:"); ImGui::SameLine(100); ImGui::Text("% 7.3f[ms]", double(profTriangulate)*toMs);
  711. ImGui::Text("Frame:"); ImGui::SameLine(100); ImGui::Text("% 7.3f[ms]", double(frameTime)*toMs);
  712. ImGui::End();
  713. imguiEndFrame();
  714. // Advance to next frame. Rendering thread will be kicked to
  715. // process submitted rendering primitives.
  716. bgfx::frame();
  717. return true;
  718. }
  719. return false;
  720. }
  721. entry::MouseState m_mouseState;
  722. uint32_t m_width;
  723. uint32_t m_height;
  724. uint32_t m_debug;
  725. uint32_t m_reset;
  726. bgfx::ProgramHandle m_program;
  727. Grid* m_grid;
  728. int64_t m_timeOffset;
  729. };
  730. } // namespace
  731. ENTRY_IMPLEMENT_MAIN(
  732. ExampleMetaballs
  733. , "02-metaball"
  734. , "Rendering with transient buffers and embedding shaders."
  735. , "https://bkaradzic.github.io/bgfx/examples.html#metaballs"
  736. );