ocean.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509
  1. /*
  2. * ***** BEGIN GPL LICENSE BLOCK *****
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software Foundation,
  16. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. *
  18. * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  19. * All rights reserved.
  20. *
  21. * Contributors: Matt Ebb, Hamed Zaghaghi
  22. * Based on original code by Drew Whitehouse / Houdini Ocean Toolkit
  23. * OpenMP hints by Christian Schnellhammer
  24. *
  25. * ***** END GPL LICENSE BLOCK *****
  26. */
  27. /** \file blender/blenkernel/intern/ocean.c
  28. * \ingroup bke
  29. */
  30. #include <math.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "MEM_guardedalloc.h"
  34. #include "DNA_scene_types.h"
  35. #include "BLI_math.h"
  36. #include "BLI_path_util.h"
  37. #include "BLI_rand.h"
  38. #include "BLI_task.h"
  39. #include "BLI_threads.h"
  40. #include "BLI_utildefines.h"
  41. #include "BKE_image.h"
  42. #include "BKE_ocean.h"
  43. #include "IMB_imbuf.h"
  44. #include "IMB_imbuf_types.h"
  45. #include "RE_render_ext.h"
  46. #ifdef WITH_OCEANSIM
  47. /* Ocean code */
  48. #include "fftw3.h"
  49. #define GRAVITY 9.81f
  50. typedef struct Ocean {
  51. /* ********* input parameters to the sim ********* */
  52. float _V;
  53. float _l;
  54. float _w;
  55. float _A;
  56. float _damp_reflections;
  57. float _wind_alignment;
  58. float _depth;
  59. float _wx;
  60. float _wz;
  61. float _L;
  62. /* dimensions of computational grid */
  63. int _M;
  64. int _N;
  65. /* spatial size of computational grid */
  66. float _Lx;
  67. float _Lz;
  68. float normalize_factor; /* init w */
  69. float time;
  70. short _do_disp_y;
  71. short _do_normals;
  72. short _do_chop;
  73. short _do_jacobian;
  74. /* mutex for threaded texture access */
  75. ThreadRWMutex oceanmutex;
  76. /* ********* sim data arrays ********* */
  77. /* two dimensional arrays of complex */
  78. fftw_complex *_fft_in; /* init w sim w */
  79. fftw_complex *_fft_in_x; /* init w sim w */
  80. fftw_complex *_fft_in_z; /* init w sim w */
  81. fftw_complex *_fft_in_jxx; /* init w sim w */
  82. fftw_complex *_fft_in_jzz; /* init w sim w */
  83. fftw_complex *_fft_in_jxz; /* init w sim w */
  84. fftw_complex *_fft_in_nx; /* init w sim w */
  85. fftw_complex *_fft_in_nz; /* init w sim w */
  86. fftw_complex *_htilda; /* init w sim w (only once) */
  87. /* fftw "plans" */
  88. fftw_plan _disp_y_plan; /* init w sim r */
  89. fftw_plan _disp_x_plan; /* init w sim r */
  90. fftw_plan _disp_z_plan; /* init w sim r */
  91. fftw_plan _N_x_plan; /* init w sim r */
  92. fftw_plan _N_z_plan; /* init w sim r */
  93. fftw_plan _Jxx_plan; /* init w sim r */
  94. fftw_plan _Jxz_plan; /* init w sim r */
  95. fftw_plan _Jzz_plan; /* init w sim r */
  96. /* two dimensional arrays of float */
  97. double *_disp_y; /* init w sim w via plan? */
  98. double *_N_x; /* init w sim w via plan? */
  99. /* all member of this array has same values, so convert this array to a float to reduce memory usage (MEM01)*/
  100. /*float * _N_y; */
  101. double _N_y; /* sim w ********* can be rearranged? */
  102. double *_N_z; /* init w sim w via plan? */
  103. double *_disp_x; /* init w sim w via plan? */
  104. double *_disp_z; /* init w sim w via plan? */
  105. /* two dimensional arrays of float */
  106. /* Jacobian and minimum eigenvalue */
  107. double *_Jxx; /* init w sim w */
  108. double *_Jzz; /* init w sim w */
  109. double *_Jxz; /* init w sim w */
  110. /* one dimensional float array */
  111. float *_kx; /* init w sim r */
  112. float *_kz; /* init w sim r */
  113. /* two dimensional complex array */
  114. fftw_complex *_h0; /* init w sim r */
  115. fftw_complex *_h0_minus; /* init w sim r */
  116. /* two dimensional float array */
  117. float *_k; /* init w sim r */
  118. } Ocean;
  119. static float nextfr(RNG *rng, float min, float max)
  120. {
  121. return BLI_rng_get_float(rng) * (min - max) + max;
  122. }
  123. static float gaussRand(RNG *rng)
  124. {
  125. /* Note: to avoid numerical problems with very small numbers, we make these variables singe-precision floats,
  126. * but later we call the double-precision log() and sqrt() functions instead of logf() and sqrtf().
  127. */
  128. float x;
  129. float y;
  130. float length2;
  131. do {
  132. x = (float) (nextfr(rng, -1, 1));
  133. y = (float)(nextfr(rng, -1, 1));
  134. length2 = x * x + y * y;
  135. } while (length2 >= 1 || length2 == 0);
  136. return x * sqrtf(-2.0f * logf(length2) / length2);
  137. }
  138. /**
  139. * Some useful functions
  140. */
  141. MINLINE float catrom(float p0, float p1, float p2, float p3, float f)
  142. {
  143. return 0.5f * ((2.0f * p1) +
  144. (-p0 + p2) * f +
  145. (2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * f * f +
  146. (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * f * f * f);
  147. }
  148. MINLINE float omega(float k, float depth)
  149. {
  150. return sqrtf(GRAVITY * k * tanhf(k * depth));
  151. }
  152. /* modified Phillips spectrum */
  153. static float Ph(struct Ocean *o, float kx, float kz)
  154. {
  155. float tmp;
  156. float k2 = kx * kx + kz * kz;
  157. if (k2 == 0.0f) {
  158. return 0.0f; /* no DC component */
  159. }
  160. /* damp out the waves going in the direction opposite the wind */
  161. tmp = (o->_wx * kx + o->_wz * kz) / sqrtf(k2);
  162. if (tmp < 0) {
  163. tmp *= o->_damp_reflections;
  164. }
  165. return o->_A * expf(-1.0f / (k2 * (o->_L * o->_L))) * expf(-k2 * (o->_l * o->_l)) *
  166. powf(fabsf(tmp), o->_wind_alignment) / (k2 * k2);
  167. }
  168. static void compute_eigenstuff(struct OceanResult *ocr, float jxx, float jzz, float jxz)
  169. {
  170. float a, b, qplus, qminus;
  171. a = jxx + jzz;
  172. b = sqrt((jxx - jzz) * (jxx - jzz) + 4 * jxz * jxz);
  173. ocr->Jminus = 0.5f * (a - b);
  174. ocr->Jplus = 0.5f * (a + b);
  175. qplus = (ocr->Jplus - jxx) / jxz;
  176. qminus = (ocr->Jminus - jxx) / jxz;
  177. a = sqrt(1 + qplus * qplus);
  178. b = sqrt(1 + qminus * qminus);
  179. ocr->Eplus[0] = 1.0f / a;
  180. ocr->Eplus[1] = 0.0f;
  181. ocr->Eplus[2] = qplus / a;
  182. ocr->Eminus[0] = 1.0f / b;
  183. ocr->Eminus[1] = 0.0f;
  184. ocr->Eminus[2] = qminus / b;
  185. }
  186. /*
  187. * instead of Complex.h
  188. * in fftw.h "fftw_complex" typedefed as double[2]
  189. * below you can see functions are needed to work with such complex numbers.
  190. * */
  191. static void init_complex(fftw_complex cmpl, float real, float image)
  192. {
  193. cmpl[0] = real;
  194. cmpl[1] = image;
  195. }
  196. #if 0 /* unused */
  197. static void add_complex_f(fftw_complex res, fftw_complex cmpl, float f)
  198. {
  199. res[0] = cmpl[0] + f;
  200. res[1] = cmpl[1];
  201. }
  202. #endif
  203. static void add_comlex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2)
  204. {
  205. res[0] = cmpl1[0] + cmpl2[0];
  206. res[1] = cmpl1[1] + cmpl2[1];
  207. }
  208. static void mul_complex_f(fftw_complex res, fftw_complex cmpl, float f)
  209. {
  210. res[0] = cmpl[0] * (double)f;
  211. res[1] = cmpl[1] * (double)f;
  212. }
  213. static void mul_complex_c(fftw_complex res, fftw_complex cmpl1, fftw_complex cmpl2)
  214. {
  215. fftwf_complex temp;
  216. temp[0] = cmpl1[0] * cmpl2[0] - cmpl1[1] * cmpl2[1];
  217. temp[1] = cmpl1[0] * cmpl2[1] + cmpl1[1] * cmpl2[0];
  218. res[0] = temp[0];
  219. res[1] = temp[1];
  220. }
  221. static float real_c(fftw_complex cmpl)
  222. {
  223. return cmpl[0];
  224. }
  225. static float image_c(fftw_complex cmpl)
  226. {
  227. return cmpl[1];
  228. }
  229. static void conj_complex(fftw_complex res, fftw_complex cmpl1)
  230. {
  231. res[0] = cmpl1[0];
  232. res[1] = -cmpl1[1];
  233. }
  234. static void exp_complex(fftw_complex res, fftw_complex cmpl)
  235. {
  236. float r = expf(cmpl[0]);
  237. res[0] = cosf(cmpl[1]) * r;
  238. res[1] = sinf(cmpl[1]) * r;
  239. }
  240. float BKE_ocean_jminus_to_foam(float jminus, float coverage)
  241. {
  242. float foam = jminus * -0.005f + coverage;
  243. CLAMP(foam, 0.0f, 1.0f);
  244. return foam * foam;
  245. }
  246. void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
  247. {
  248. int i0, i1, j0, j1;
  249. float frac_x, frac_z;
  250. float uu, vv;
  251. /* first wrap the texture so 0 <= (u, v) < 1 */
  252. u = fmodf(u, 1.0f);
  253. v = fmodf(v, 1.0f);
  254. if (u < 0) u += 1.0f;
  255. if (v < 0) v += 1.0f;
  256. BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
  257. uu = u * oc->_M;
  258. vv = v * oc->_N;
  259. i0 = (int)floor(uu);
  260. j0 = (int)floor(vv);
  261. i1 = (i0 + 1);
  262. j1 = (j0 + 1);
  263. frac_x = uu - i0;
  264. frac_z = vv - j0;
  265. i0 = i0 % oc->_M;
  266. j0 = j0 % oc->_N;
  267. i1 = i1 % oc->_M;
  268. j1 = j1 % oc->_N;
  269. #define BILERP(m) (interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \
  270. interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \
  271. frac_z))
  272. {
  273. if (oc->_do_disp_y) {
  274. ocr->disp[1] = BILERP(oc->_disp_y);
  275. }
  276. if (oc->_do_normals) {
  277. ocr->normal[0] = BILERP(oc->_N_x);
  278. ocr->normal[1] = oc->_N_y /*BILERP(oc->_N_y) (MEM01)*/;
  279. ocr->normal[2] = BILERP(oc->_N_z);
  280. }
  281. if (oc->_do_chop) {
  282. ocr->disp[0] = BILERP(oc->_disp_x);
  283. ocr->disp[2] = BILERP(oc->_disp_z);
  284. }
  285. else {
  286. ocr->disp[0] = 0.0;
  287. ocr->disp[2] = 0.0;
  288. }
  289. if (oc->_do_jacobian) {
  290. compute_eigenstuff(ocr, BILERP(oc->_Jxx), BILERP(oc->_Jzz), BILERP(oc->_Jxz));
  291. }
  292. }
  293. #undef BILERP
  294. BLI_rw_mutex_unlock(&oc->oceanmutex);
  295. }
  296. /* use catmullrom interpolation rather than linear */
  297. void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
  298. {
  299. int i0, i1, i2, i3, j0, j1, j2, j3;
  300. float frac_x, frac_z;
  301. float uu, vv;
  302. /* first wrap the texture so 0 <= (u, v) < 1 */
  303. u = fmod(u, 1.0f);
  304. v = fmod(v, 1.0f);
  305. if (u < 0) u += 1.0f;
  306. if (v < 0) v += 1.0f;
  307. BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
  308. uu = u * oc->_M;
  309. vv = v * oc->_N;
  310. i1 = (int)floor(uu);
  311. j1 = (int)floor(vv);
  312. i2 = (i1 + 1);
  313. j2 = (j1 + 1);
  314. frac_x = uu - i1;
  315. frac_z = vv - j1;
  316. i1 = i1 % oc->_M;
  317. j1 = j1 % oc->_N;
  318. i2 = i2 % oc->_M;
  319. j2 = j2 % oc->_N;
  320. i0 = (i1 - 1);
  321. i3 = (i2 + 1);
  322. i0 = i0 < 0 ? i0 + oc->_M : i0;
  323. i3 = i3 >= oc->_M ? i3 - oc->_M : i3;
  324. j0 = (j1 - 1);
  325. j3 = (j2 + 1);
  326. j0 = j0 < 0 ? j0 + oc->_N : j0;
  327. j3 = j3 >= oc->_N ? j3 - oc->_N : j3;
  328. #define INTERP(m) catrom(catrom(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], \
  329. m[i2 * oc->_N + j0], m[i3 * oc->_N + j0], frac_x), \
  330. catrom(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], \
  331. m[i2 * oc->_N + j1], m[i3 * oc->_N + j1], frac_x), \
  332. catrom(m[i0 * oc->_N + j2], m[i1 * oc->_N + j2], \
  333. m[i2 * oc->_N + j2], m[i3 * oc->_N + j2], frac_x), \
  334. catrom(m[i0 * oc->_N + j3], m[i1 * oc->_N + j3], \
  335. m[i2 * oc->_N + j3], m[i3 * oc->_N + j3], frac_x), \
  336. frac_z)
  337. {
  338. if (oc->_do_disp_y) {
  339. ocr->disp[1] = INTERP(oc->_disp_y);
  340. }
  341. if (oc->_do_normals) {
  342. ocr->normal[0] = INTERP(oc->_N_x);
  343. ocr->normal[1] = oc->_N_y /*INTERP(oc->_N_y) (MEM01)*/;
  344. ocr->normal[2] = INTERP(oc->_N_z);
  345. }
  346. if (oc->_do_chop) {
  347. ocr->disp[0] = INTERP(oc->_disp_x);
  348. ocr->disp[2] = INTERP(oc->_disp_z);
  349. }
  350. else {
  351. ocr->disp[0] = 0.0;
  352. ocr->disp[2] = 0.0;
  353. }
  354. if (oc->_do_jacobian) {
  355. compute_eigenstuff(ocr, INTERP(oc->_Jxx), INTERP(oc->_Jzz), INTERP(oc->_Jxz));
  356. }
  357. }
  358. #undef INTERP
  359. BLI_rw_mutex_unlock(&oc->oceanmutex);
  360. }
  361. void BKE_ocean_eval_xz(struct Ocean *oc, struct OceanResult *ocr, float x, float z)
  362. {
  363. BKE_ocean_eval_uv(oc, ocr, x / oc->_Lx, z / oc->_Lz);
  364. }
  365. void BKE_ocean_eval_xz_catrom(struct Ocean *oc, struct OceanResult *ocr, float x, float z)
  366. {
  367. BKE_ocean_eval_uv_catrom(oc, ocr, x / oc->_Lx, z / oc->_Lz);
  368. }
  369. /* note that this doesn't wrap properly for i, j < 0, but its not really meant for that being just a way to get
  370. * the raw data out to save in some image format.
  371. */
  372. void BKE_ocean_eval_ij(struct Ocean *oc, struct OceanResult *ocr, int i, int j)
  373. {
  374. BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
  375. i = abs(i) % oc->_M;
  376. j = abs(j) % oc->_N;
  377. ocr->disp[1] = oc->_do_disp_y ? (float)oc->_disp_y[i * oc->_N + j] : 0.0f;
  378. if (oc->_do_chop) {
  379. ocr->disp[0] = oc->_disp_x[i * oc->_N + j];
  380. ocr->disp[2] = oc->_disp_z[i * oc->_N + j];
  381. }
  382. else {
  383. ocr->disp[0] = 0.0f;
  384. ocr->disp[2] = 0.0f;
  385. }
  386. if (oc->_do_normals) {
  387. ocr->normal[0] = oc->_N_x[i * oc->_N + j];
  388. ocr->normal[1] = oc->_N_y /* oc->_N_y[i * oc->_N + j] (MEM01) */;
  389. ocr->normal[2] = oc->_N_z[i * oc->_N + j];
  390. normalize_v3(ocr->normal);
  391. }
  392. if (oc->_do_jacobian) {
  393. compute_eigenstuff(ocr, oc->_Jxx[i * oc->_N + j], oc->_Jzz[i * oc->_N + j], oc->_Jxz[i * oc->_N + j]);
  394. }
  395. BLI_rw_mutex_unlock(&oc->oceanmutex);
  396. }
  397. typedef struct OceanSimulateData {
  398. Ocean *o;
  399. float t;
  400. float scale;
  401. float chop_amount;
  402. } OceanSimulateData;
  403. static void ocean_compute_htilda(void *userdata, const int i)
  404. {
  405. OceanSimulateData *osd = userdata;
  406. const Ocean *o = osd->o;
  407. const float scale = osd->scale;
  408. const float t = osd->t;
  409. int j;
  410. /* note the <= _N/2 here, see the fftw doco about the mechanics of the complex->real fft storage */
  411. for (j = 0; j <= o->_N / 2; ++j) {
  412. fftw_complex exp_param1;
  413. fftw_complex exp_param2;
  414. fftw_complex conj_param;
  415. init_complex(exp_param1, 0.0, omega(o->_k[i * (1 + o->_N / 2) + j], o->_depth) * t);
  416. init_complex(exp_param2, 0.0, -omega(o->_k[i * (1 + o->_N / 2) + j], o->_depth) * t);
  417. exp_complex(exp_param1, exp_param1);
  418. exp_complex(exp_param2, exp_param2);
  419. conj_complex(conj_param, o->_h0_minus[i * o->_N + j]);
  420. mul_complex_c(exp_param1, o->_h0[i * o->_N + j], exp_param1);
  421. mul_complex_c(exp_param2, conj_param, exp_param2);
  422. add_comlex_c(o->_htilda[i * (1 + o->_N / 2) + j], exp_param1, exp_param2);
  423. mul_complex_f(o->_fft_in[i * (1 + o->_N / 2) + j], o->_htilda[i * (1 + o->_N / 2) + j], scale);
  424. }
  425. }
  426. static void ocean_compute_displacement_y(TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid))
  427. {
  428. OceanSimulateData *osd = BLI_task_pool_userdata(pool);
  429. const Ocean *o = osd->o;
  430. fftw_execute(o->_disp_y_plan);
  431. }
  432. static void ocean_compute_displacement_x(TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid))
  433. {
  434. OceanSimulateData *osd = BLI_task_pool_userdata(pool);
  435. const Ocean *o = osd->o;
  436. const float scale = osd->scale;
  437. const float chop_amount = osd->chop_amount;
  438. int i, j;
  439. for (i = 0; i < o->_M; ++i) {
  440. for (j = 0; j <= o->_N / 2; ++j) {
  441. fftw_complex mul_param;
  442. fftw_complex minus_i;
  443. init_complex(minus_i, 0.0, -1.0);
  444. init_complex(mul_param, -scale, 0);
  445. mul_complex_f(mul_param, mul_param, chop_amount);
  446. mul_complex_c(mul_param, mul_param, minus_i);
  447. mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
  448. mul_complex_f(mul_param, mul_param,
  449. ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
  450. 0.0f :
  451. o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
  452. init_complex(o->_fft_in_x[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
  453. }
  454. }
  455. fftw_execute(o->_disp_x_plan);
  456. }
  457. static void ocean_compute_displacement_z(TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid))
  458. {
  459. OceanSimulateData *osd = BLI_task_pool_userdata(pool);
  460. const Ocean *o = osd->o;
  461. const float scale = osd->scale;
  462. const float chop_amount = osd->chop_amount;
  463. int i, j;
  464. for (i = 0; i < o->_M; ++i) {
  465. for (j = 0; j <= o->_N / 2; ++j) {
  466. fftw_complex mul_param;
  467. fftw_complex minus_i;
  468. init_complex(minus_i, 0.0, -1.0);
  469. init_complex(mul_param, -scale, 0);
  470. mul_complex_f(mul_param, mul_param, chop_amount);
  471. mul_complex_c(mul_param, mul_param, minus_i);
  472. mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
  473. mul_complex_f(mul_param, mul_param,
  474. ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
  475. 0.0f :
  476. o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
  477. init_complex(o->_fft_in_z[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
  478. }
  479. }
  480. fftw_execute(o->_disp_z_plan);
  481. }
  482. static void ocean_compute_jacobian_jxx(TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid))
  483. {
  484. OceanSimulateData *osd = BLI_task_pool_userdata(pool);
  485. const Ocean *o = osd->o;
  486. const float chop_amount = osd->chop_amount;
  487. int i, j;
  488. for (i = 0; i < o->_M; ++i) {
  489. for (j = 0; j <= o->_N / 2; ++j) {
  490. fftw_complex mul_param;
  491. /* init_complex(mul_param, -scale, 0); */
  492. init_complex(mul_param, -1, 0);
  493. mul_complex_f(mul_param, mul_param, chop_amount);
  494. mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
  495. mul_complex_f(mul_param, mul_param,
  496. ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
  497. 0.0f :
  498. o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
  499. init_complex(o->_fft_in_jxx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
  500. }
  501. }
  502. fftw_execute(o->_Jxx_plan);
  503. for (i = 0; i < o->_M; ++i) {
  504. for (j = 0; j < o->_N; ++j) {
  505. o->_Jxx[i * o->_N + j] += 1.0;
  506. }
  507. }
  508. }
  509. static void ocean_compute_jacobian_jzz(TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid))
  510. {
  511. OceanSimulateData *osd = BLI_task_pool_userdata(pool);
  512. const Ocean *o = osd->o;
  513. const float chop_amount = osd->chop_amount;
  514. int i, j;
  515. for (i = 0; i < o->_M; ++i) {
  516. for (j = 0; j <= o->_N / 2; ++j) {
  517. fftw_complex mul_param;
  518. /* init_complex(mul_param, -scale, 0); */
  519. init_complex(mul_param, -1, 0);
  520. mul_complex_f(mul_param, mul_param, chop_amount);
  521. mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
  522. mul_complex_f(mul_param, mul_param,
  523. ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
  524. 0.0f :
  525. o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
  526. init_complex(o->_fft_in_jzz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
  527. }
  528. }
  529. fftw_execute(o->_Jzz_plan);
  530. for (i = 0; i < o->_M; ++i) {
  531. for (j = 0; j < o->_N; ++j) {
  532. o->_Jzz[i * o->_N + j] += 1.0;
  533. }
  534. }
  535. }
  536. static void ocean_compute_jacobian_jxz(TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid))
  537. {
  538. OceanSimulateData *osd = BLI_task_pool_userdata(pool);
  539. const Ocean *o = osd->o;
  540. const float chop_amount = osd->chop_amount;
  541. int i, j;
  542. for (i = 0; i < o->_M; ++i) {
  543. for (j = 0; j <= o->_N / 2; ++j) {
  544. fftw_complex mul_param;
  545. /* init_complex(mul_param, -scale, 0); */
  546. init_complex(mul_param, -1, 0);
  547. mul_complex_f(mul_param, mul_param, chop_amount);
  548. mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
  549. mul_complex_f(mul_param, mul_param,
  550. ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
  551. 0.0f :
  552. o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
  553. init_complex(o->_fft_in_jxz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
  554. }
  555. }
  556. fftw_execute(o->_Jxz_plan);
  557. }
  558. static void ocean_compute_normal_x(TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid))
  559. {
  560. OceanSimulateData *osd = BLI_task_pool_userdata(pool);
  561. const Ocean *o = osd->o;
  562. int i, j;
  563. for (i = 0; i < o->_M; ++i) {
  564. for (j = 0; j <= o->_N / 2; ++j) {
  565. fftw_complex mul_param;
  566. init_complex(mul_param, 0.0, -1.0);
  567. mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
  568. mul_complex_f(mul_param, mul_param, o->_kx[i]);
  569. init_complex(o->_fft_in_nx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
  570. }
  571. }
  572. fftw_execute(o->_N_x_plan);
  573. }
  574. static void ocean_compute_normal_z(TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid))
  575. {
  576. OceanSimulateData *osd = BLI_task_pool_userdata(pool);
  577. const Ocean *o = osd->o;
  578. int i, j;
  579. for (i = 0; i < o->_M; ++i) {
  580. for (j = 0; j <= o->_N / 2; ++j) {
  581. fftw_complex mul_param;
  582. init_complex(mul_param, 0.0, -1.0);
  583. mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
  584. mul_complex_f(mul_param, mul_param, o->_kz[i]);
  585. init_complex(o->_fft_in_nz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
  586. }
  587. }
  588. fftw_execute(o->_N_z_plan);
  589. }
  590. void BKE_ocean_simulate(struct Ocean *o, float t, float scale, float chop_amount)
  591. {
  592. TaskScheduler *scheduler = BLI_task_scheduler_get();
  593. TaskPool *pool;
  594. OceanSimulateData osd;
  595. scale *= o->normalize_factor;
  596. osd.o = o;
  597. osd.t = t;
  598. osd.scale = scale;
  599. osd.chop_amount = chop_amount;
  600. pool = BLI_task_pool_create(scheduler, &osd);
  601. BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
  602. /* Note about multi-threading here: we have to run a first set of computations (htilda one) before we can run
  603. * all others, since they all depend on it.
  604. * So we make a first parallelized forloop run for htilda, and then pack all other computations into
  605. * a set of parallel tasks.
  606. * This is not optimal in all cases, but remains reasonably simple and should be OK most of the time. */
  607. /* compute a new htilda */
  608. BLI_task_parallel_range(0, o->_M, &osd, ocean_compute_htilda, o->_M > 16);
  609. if (o->_do_disp_y) {
  610. BLI_task_pool_push(pool, ocean_compute_displacement_y, NULL, false, TASK_PRIORITY_HIGH);
  611. }
  612. if (o->_do_chop) {
  613. BLI_task_pool_push(pool, ocean_compute_displacement_x, NULL, false, TASK_PRIORITY_HIGH);
  614. BLI_task_pool_push(pool, ocean_compute_displacement_z, NULL, false, TASK_PRIORITY_HIGH);
  615. }
  616. if (o->_do_jacobian) {
  617. BLI_task_pool_push(pool, ocean_compute_jacobian_jxx, NULL, false, TASK_PRIORITY_HIGH);
  618. BLI_task_pool_push(pool, ocean_compute_jacobian_jzz, NULL, false, TASK_PRIORITY_HIGH);
  619. BLI_task_pool_push(pool, ocean_compute_jacobian_jxz, NULL, false, TASK_PRIORITY_HIGH);
  620. }
  621. if (o->_do_normals) {
  622. BLI_task_pool_push(pool, ocean_compute_normal_x, NULL, false, TASK_PRIORITY_HIGH);
  623. BLI_task_pool_push(pool, ocean_compute_normal_z, NULL, false, TASK_PRIORITY_HIGH);
  624. #if 0
  625. for (i = 0; i < o->_M; ++i) {
  626. for (j = 0; j < o->_N; ++j) {
  627. o->_N_y[i * o->_N + j] = 1.0f / scale;
  628. }
  629. }
  630. (MEM01)
  631. #endif
  632. o->_N_y = 1.0f / scale;
  633. }
  634. BLI_task_pool_work_and_wait(pool);
  635. BLI_rw_mutex_unlock(&o->oceanmutex);
  636. BLI_task_pool_free(pool);
  637. }
  638. static void set_height_normalize_factor(struct Ocean *oc)
  639. {
  640. float res = 1.0;
  641. float max_h = 0.0;
  642. int i, j;
  643. if (!oc->_do_disp_y) return;
  644. oc->normalize_factor = 1.0;
  645. BKE_ocean_simulate(oc, 0.0, 1.0, 0);
  646. BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
  647. for (i = 0; i < oc->_M; ++i) {
  648. for (j = 0; j < oc->_N; ++j) {
  649. if (max_h < fabs(oc->_disp_y[i * oc->_N + j])) {
  650. max_h = fabs(oc->_disp_y[i * oc->_N + j]);
  651. }
  652. }
  653. }
  654. BLI_rw_mutex_unlock(&oc->oceanmutex);
  655. if (max_h == 0.0f)
  656. max_h = 0.00001f; /* just in case ... */
  657. res = 1.0f / (max_h);
  658. oc->normalize_factor = res;
  659. }
  660. struct Ocean *BKE_ocean_add(void)
  661. {
  662. Ocean *oc = MEM_callocN(sizeof(Ocean), "ocean sim data");
  663. BLI_rw_mutex_init(&oc->oceanmutex);
  664. return oc;
  665. }
  666. void BKE_ocean_init(struct Ocean *o, int M, int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
  667. float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals,
  668. short do_jacobian, int seed)
  669. {
  670. RNG *rng;
  671. int i, j, ii;
  672. BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
  673. o->_M = M;
  674. o->_N = N;
  675. o->_V = V;
  676. o->_l = l;
  677. o->_A = A;
  678. o->_w = w;
  679. o->_damp_reflections = 1.0f - damp;
  680. o->_wind_alignment = alignment;
  681. o->_depth = depth;
  682. o->_Lx = Lx;
  683. o->_Lz = Lz;
  684. o->_wx = cos(w);
  685. o->_wz = -sin(w); /* wave direction */
  686. o->_L = V * V / GRAVITY; /* largest wave for a given velocity V */
  687. o->time = time;
  688. o->_do_disp_y = do_height_field;
  689. o->_do_normals = do_normals;
  690. o->_do_chop = do_chop;
  691. o->_do_jacobian = do_jacobian;
  692. o->_k = (float *) MEM_mallocN(M * (1 + N / 2) * sizeof(float), "ocean_k");
  693. o->_h0 = (fftw_complex *) MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0");
  694. o->_h0_minus = (fftw_complex *) MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0_minus");
  695. o->_kx = (float *) MEM_mallocN(o->_M * sizeof(float), "ocean_kx");
  696. o->_kz = (float *) MEM_mallocN(o->_N * sizeof(float), "ocean_kz");
  697. /* make this robust in the face of erroneous usage */
  698. if (o->_Lx == 0.0f)
  699. o->_Lx = 0.001f;
  700. if (o->_Lz == 0.0f)
  701. o->_Lz = 0.001f;
  702. /* the +ve components and DC */
  703. for (i = 0; i <= o->_M / 2; ++i)
  704. o->_kx[i] = 2.0f * (float)M_PI * i / o->_Lx;
  705. /* the -ve components */
  706. for (i = o->_M - 1, ii = 0; i > o->_M / 2; --i, ++ii)
  707. o->_kx[i] = -2.0f * (float)M_PI * ii / o->_Lx;
  708. /* the +ve components and DC */
  709. for (i = 0; i <= o->_N / 2; ++i)
  710. o->_kz[i] = 2.0f * (float)M_PI * i / o->_Lz;
  711. /* the -ve components */
  712. for (i = o->_N - 1, ii = 0; i > o->_N / 2; --i, ++ii)
  713. o->_kz[i] = -2.0f * (float)M_PI * ii / o->_Lz;
  714. /* pre-calculate the k matrix */
  715. for (i = 0; i < o->_M; ++i)
  716. for (j = 0; j <= o->_N / 2; ++j)
  717. o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);
  718. /*srand(seed);*/
  719. rng = BLI_rng_new(seed);
  720. for (i = 0; i < o->_M; ++i) {
  721. for (j = 0; j < o->_N; ++j) {
  722. float r1 = gaussRand(rng);
  723. float r2 = gaussRand(rng);
  724. fftw_complex r1r2;
  725. init_complex(r1r2, r1, r2);
  726. mul_complex_f(o->_h0[i * o->_N + j], r1r2, (float)(sqrt(Ph(o, o->_kx[i], o->_kz[j]) / 2.0f)));
  727. mul_complex_f(o->_h0_minus[i * o->_N + j], r1r2, (float)(sqrt(Ph(o, -o->_kx[i], -o->_kz[j]) / 2.0f)));
  728. }
  729. }
  730. o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
  731. o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
  732. BLI_lock_thread(LOCK_FFTW);
  733. if (o->_do_disp_y) {
  734. o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
  735. o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
  736. }
  737. if (o->_do_normals) {
  738. o->_fft_in_nx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nx");
  739. o->_fft_in_nz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nz");
  740. o->_N_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
  741. /* o->_N_y = (float *) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01) */
  742. o->_N_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");
  743. o->_N_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nx, o->_N_x, FFTW_ESTIMATE);
  744. o->_N_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nz, o->_N_z, FFTW_ESTIMATE);
  745. }
  746. if (o->_do_chop) {
  747. o->_fft_in_x = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
  748. o->_fft_in_z = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");
  749. o->_disp_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
  750. o->_disp_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");
  751. o->_disp_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_x, o->_disp_x, FFTW_ESTIMATE);
  752. o->_disp_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_z, o->_disp_z, FFTW_ESTIMATE);
  753. }
  754. if (o->_do_jacobian) {
  755. o->_fft_in_jxx = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
  756. "ocean_fft_in_jxx");
  757. o->_fft_in_jzz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
  758. "ocean_fft_in_jzz");
  759. o->_fft_in_jxz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
  760. "ocean_fft_in_jxz");
  761. o->_Jxx = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
  762. o->_Jzz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
  763. o->_Jxz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");
  764. o->_Jxx_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxx, o->_Jxx, FFTW_ESTIMATE);
  765. o->_Jzz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jzz, o->_Jzz, FFTW_ESTIMATE);
  766. o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE);
  767. }
  768. BLI_unlock_thread(LOCK_FFTW);
  769. BLI_rw_mutex_unlock(&o->oceanmutex);
  770. set_height_normalize_factor(o);
  771. BLI_rng_free(rng);
  772. }
  773. void BKE_ocean_free_data(struct Ocean *oc)
  774. {
  775. if (!oc) return;
  776. BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_WRITE);
  777. BLI_lock_thread(LOCK_FFTW);
  778. if (oc->_do_disp_y) {
  779. fftw_destroy_plan(oc->_disp_y_plan);
  780. MEM_freeN(oc->_disp_y);
  781. }
  782. if (oc->_do_normals) {
  783. MEM_freeN(oc->_fft_in_nx);
  784. MEM_freeN(oc->_fft_in_nz);
  785. fftw_destroy_plan(oc->_N_x_plan);
  786. fftw_destroy_plan(oc->_N_z_plan);
  787. MEM_freeN(oc->_N_x);
  788. /*fftwf_free(oc->_N_y); (MEM01)*/
  789. MEM_freeN(oc->_N_z);
  790. }
  791. if (oc->_do_chop) {
  792. MEM_freeN(oc->_fft_in_x);
  793. MEM_freeN(oc->_fft_in_z);
  794. fftw_destroy_plan(oc->_disp_x_plan);
  795. fftw_destroy_plan(oc->_disp_z_plan);
  796. MEM_freeN(oc->_disp_x);
  797. MEM_freeN(oc->_disp_z);
  798. }
  799. if (oc->_do_jacobian) {
  800. MEM_freeN(oc->_fft_in_jxx);
  801. MEM_freeN(oc->_fft_in_jzz);
  802. MEM_freeN(oc->_fft_in_jxz);
  803. fftw_destroy_plan(oc->_Jxx_plan);
  804. fftw_destroy_plan(oc->_Jzz_plan);
  805. fftw_destroy_plan(oc->_Jxz_plan);
  806. MEM_freeN(oc->_Jxx);
  807. MEM_freeN(oc->_Jzz);
  808. MEM_freeN(oc->_Jxz);
  809. }
  810. BLI_unlock_thread(LOCK_FFTW);
  811. if (oc->_fft_in)
  812. MEM_freeN(oc->_fft_in);
  813. /* check that ocean data has been initialized */
  814. if (oc->_htilda) {
  815. MEM_freeN(oc->_htilda);
  816. MEM_freeN(oc->_k);
  817. MEM_freeN(oc->_h0);
  818. MEM_freeN(oc->_h0_minus);
  819. MEM_freeN(oc->_kx);
  820. MEM_freeN(oc->_kz);
  821. }
  822. BLI_rw_mutex_unlock(&oc->oceanmutex);
  823. }
  824. void BKE_ocean_free(struct Ocean *oc)
  825. {
  826. if (!oc) return;
  827. BKE_ocean_free_data(oc);
  828. BLI_rw_mutex_end(&oc->oceanmutex);
  829. MEM_freeN(oc);
  830. }
  831. #undef GRAVITY
  832. /* ********* Baking/Caching ********* */
  833. #define CACHE_TYPE_DISPLACE 1
  834. #define CACHE_TYPE_FOAM 2
  835. #define CACHE_TYPE_NORMAL 3
  836. static void cache_filename(char *string, const char *path, const char *relbase, int frame, int type)
  837. {
  838. char cachepath[FILE_MAX];
  839. const char *fname;
  840. switch (type) {
  841. case CACHE_TYPE_FOAM:
  842. fname = "foam_";
  843. break;
  844. case CACHE_TYPE_NORMAL:
  845. fname = "normal_";
  846. break;
  847. case CACHE_TYPE_DISPLACE:
  848. default:
  849. fname = "disp_";
  850. break;
  851. }
  852. BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
  853. BKE_image_path_from_imtype(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, true, true, "");
  854. }
  855. /* silly functions but useful to inline when the args do a lot of indirections */
  856. MINLINE void rgb_to_rgba_unit_alpha(float r_rgba[4], const float rgb[3])
  857. {
  858. r_rgba[0] = rgb[0];
  859. r_rgba[1] = rgb[1];
  860. r_rgba[2] = rgb[2];
  861. r_rgba[3] = 1.0f;
  862. }
  863. MINLINE void value_to_rgba_unit_alpha(float r_rgba[4], const float value)
  864. {
  865. r_rgba[0] = value;
  866. r_rgba[1] = value;
  867. r_rgba[2] = value;
  868. r_rgba[3] = 1.0f;
  869. }
  870. void BKE_ocean_free_cache(struct OceanCache *och)
  871. {
  872. int i, f = 0;
  873. if (!och) return;
  874. if (och->ibufs_disp) {
  875. for (i = och->start, f = 0; i <= och->end; i++, f++) {
  876. if (och->ibufs_disp[f]) {
  877. IMB_freeImBuf(och->ibufs_disp[f]);
  878. }
  879. }
  880. MEM_freeN(och->ibufs_disp);
  881. }
  882. if (och->ibufs_foam) {
  883. for (i = och->start, f = 0; i <= och->end; i++, f++) {
  884. if (och->ibufs_foam[f]) {
  885. IMB_freeImBuf(och->ibufs_foam[f]);
  886. }
  887. }
  888. MEM_freeN(och->ibufs_foam);
  889. }
  890. if (och->ibufs_norm) {
  891. for (i = och->start, f = 0; i <= och->end; i++, f++) {
  892. if (och->ibufs_norm[f]) {
  893. IMB_freeImBuf(och->ibufs_norm[f]);
  894. }
  895. }
  896. MEM_freeN(och->ibufs_norm);
  897. }
  898. if (och->time)
  899. MEM_freeN(och->time);
  900. MEM_freeN(och);
  901. }
  902. void BKE_ocean_cache_eval_uv(struct OceanCache *och, struct OceanResult *ocr, int f, float u, float v)
  903. {
  904. int res_x = och->resolution_x;
  905. int res_y = och->resolution_y;
  906. float result[4];
  907. u = fmod(u, 1.0);
  908. v = fmod(v, 1.0);
  909. if (u < 0) u += 1.0f;
  910. if (v < 0) v += 1.0f;
  911. if (och->ibufs_disp[f]) {
  912. ibuf_sample(och->ibufs_disp[f], u, v, (1.0f / (float)res_x), (1.0f / (float)res_y), result);
  913. copy_v3_v3(ocr->disp, result);
  914. }
  915. if (och->ibufs_foam[f]) {
  916. ibuf_sample(och->ibufs_foam[f], u, v, (1.0f / (float)res_x), (1.0f / (float)res_y), result);
  917. ocr->foam = result[0];
  918. }
  919. if (och->ibufs_norm[f]) {
  920. ibuf_sample(och->ibufs_norm[f], u, v, (1.0f / (float)res_x), (1.0f / (float)res_y), result);
  921. copy_v3_v3(ocr->normal, result);
  922. }
  923. }
  924. void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, int f, int i, int j)
  925. {
  926. const int res_x = och->resolution_x;
  927. const int res_y = och->resolution_y;
  928. if (i < 0) i = -i;
  929. if (j < 0) j = -j;
  930. i = i % res_x;
  931. j = j % res_y;
  932. if (och->ibufs_disp[f]) {
  933. copy_v3_v3(ocr->disp, &och->ibufs_disp[f]->rect_float[4 * (res_x * j + i)]);
  934. }
  935. if (och->ibufs_foam[f]) {
  936. ocr->foam = och->ibufs_foam[f]->rect_float[4 * (res_x * j + i)];
  937. }
  938. if (och->ibufs_norm[f]) {
  939. copy_v3_v3(ocr->normal, &och->ibufs_norm[f]->rect_float[4 * (res_x * j + i)]);
  940. }
  941. }
  942. struct OceanCache *BKE_ocean_init_cache(const char *bakepath, const char *relbase, int start, int end, float wave_scale,
  943. float chop_amount, float foam_coverage, float foam_fade, int resolution)
  944. {
  945. OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
  946. och->bakepath = bakepath;
  947. och->relbase = relbase;
  948. och->start = start;
  949. och->end = end;
  950. och->duration = (end - start) + 1;
  951. och->wave_scale = wave_scale;
  952. och->chop_amount = chop_amount;
  953. och->foam_coverage = foam_coverage;
  954. och->foam_fade = foam_fade;
  955. och->resolution_x = resolution * resolution;
  956. och->resolution_y = resolution * resolution;
  957. och->ibufs_disp = MEM_callocN(sizeof(ImBuf *) * och->duration, "displacement imbuf pointer array");
  958. och->ibufs_foam = MEM_callocN(sizeof(ImBuf *) * och->duration, "foam imbuf pointer array");
  959. och->ibufs_norm = MEM_callocN(sizeof(ImBuf *) * och->duration, "normal imbuf pointer array");
  960. och->time = NULL;
  961. return och;
  962. }
  963. void BKE_ocean_simulate_cache(struct OceanCache *och, int frame)
  964. {
  965. char string[FILE_MAX];
  966. int f = frame;
  967. /* ibufs array is zero based, but filenames are based on frame numbers */
  968. /* still need to clamp frame numbers to valid range of images on disk though */
  969. CLAMP(frame, och->start, och->end);
  970. f = frame - och->start; /* shift to 0 based */
  971. /* if image is already loaded in mem, return */
  972. if (och->ibufs_disp[f] != NULL) return;
  973. /* use default color spaces since we know for sure cache files were saved with default settings too */
  974. cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_DISPLACE);
  975. och->ibufs_disp[f] = IMB_loadiffname(string, 0, NULL);
  976. #if 0
  977. if (och->ibufs_disp[f] == NULL)
  978. printf("error loading %s\n", string);
  979. else
  980. printf("loaded cache %s\n", string);
  981. #endif
  982. cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_FOAM);
  983. och->ibufs_foam[f] = IMB_loadiffname(string, 0, NULL);
  984. #if 0
  985. if (och->ibufs_foam[f] == NULL)
  986. printf("error loading %s\n", string);
  987. else
  988. printf("loaded cache %s\n", string);
  989. #endif
  990. cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_NORMAL);
  991. och->ibufs_norm[f] = IMB_loadiffname(string, 0, NULL);
  992. #if 0
  993. if (och->ibufs_norm[f] == NULL)
  994. printf("error loading %s\n", string);
  995. else
  996. printf("loaded cache %s\n", string);
  997. #endif
  998. }
  999. void BKE_ocean_bake(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel),
  1000. void *update_cb_data)
  1001. {
  1002. /* note: some of these values remain uninitialized unless certain options
  1003. * are enabled, take care that BKE_ocean_eval_ij() initializes a member
  1004. * before use - campbell */
  1005. OceanResult ocr;
  1006. ImageFormatData imf = {0};
  1007. int f, i = 0, x, y, cancel = 0;
  1008. float progress;
  1009. ImBuf *ibuf_foam, *ibuf_disp, *ibuf_normal;
  1010. float *prev_foam;
  1011. int res_x = och->resolution_x;
  1012. int res_y = och->resolution_y;
  1013. char string[FILE_MAX];
  1014. //RNG *rng;
  1015. if (!o) return;
  1016. if (o->_do_jacobian) prev_foam = MEM_callocN(res_x * res_y * sizeof(float), "previous frame foam bake data");
  1017. else prev_foam = NULL;
  1018. //rng = BLI_rng_new(0);
  1019. /* setup image format */
  1020. imf.imtype = R_IMF_IMTYPE_OPENEXR;
  1021. imf.depth = R_IMF_CHAN_DEPTH_16;
  1022. imf.exr_codec = R_IMF_EXR_CODEC_ZIP;
  1023. for (f = och->start, i = 0; f <= och->end; f++, i++) {
  1024. /* create a new imbuf to store image for this frame */
  1025. ibuf_foam = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
  1026. ibuf_disp = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
  1027. ibuf_normal = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
  1028. BKE_ocean_simulate(o, och->time[i], och->wave_scale, och->chop_amount);
  1029. /* add new foam */
  1030. for (y = 0; y < res_y; y++) {
  1031. for (x = 0; x < res_x; x++) {
  1032. BKE_ocean_eval_ij(o, &ocr, x, y);
  1033. /* add to the image */
  1034. rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp);
  1035. if (o->_do_jacobian) {
  1036. /* TODO, cleanup unused code - campbell */
  1037. float /*r, */ /* UNUSED */ pr = 0.0f, foam_result;
  1038. float neg_disp, neg_eplus;
  1039. ocr.foam = BKE_ocean_jminus_to_foam(ocr.Jminus, och->foam_coverage);
  1040. /* accumulate previous value for this cell */
  1041. if (i > 0) {
  1042. pr = prev_foam[res_x * y + x];
  1043. }
  1044. /* r = BLI_rng_get_float(rng); */ /* UNUSED */ /* randomly reduce foam */
  1045. /* pr = pr * och->foam_fade; */ /* overall fade */
  1046. /* remember ocean coord sys is Y up!
  1047. * break up the foam where height (Y) is low (wave valley), and X and Z displacement is greatest
  1048. */
  1049. #if 0
  1050. vec[0] = ocr.disp[0];
  1051. vec[1] = ocr.disp[2];
  1052. hor_stretch = len_v2(vec);
  1053. CLAMP(hor_stretch, 0.0, 1.0);
  1054. #endif
  1055. neg_disp = ocr.disp[1] < 0.0f ? 1.0f + ocr.disp[1] : 1.0f;
  1056. neg_disp = neg_disp < 0.0f ? 0.0f : neg_disp;
  1057. /* foam, 'ocr.Eplus' only initialized with do_jacobian */
  1058. neg_eplus = ocr.Eplus[2] < 0.0f ? 1.0f + ocr.Eplus[2] : 1.0f;
  1059. neg_eplus = neg_eplus < 0.0f ? 0.0f : neg_eplus;
  1060. #if 0
  1061. if (ocr.disp[1] < 0.0 || r > och->foam_fade)
  1062. pr *= och->foam_fade;
  1063. pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
  1064. pr = pr * neg_disp * neg_eplus;
  1065. #endif
  1066. if (pr < 1.0f)
  1067. pr *= pr;
  1068. pr *= och->foam_fade * (0.75f + neg_eplus * 0.25f);
  1069. /* A full clamping should not be needed! */
  1070. foam_result = min_ff(pr + ocr.foam, 1.0f);
  1071. prev_foam[res_x * y + x] = foam_result;
  1072. /*foam_result = min_ff(foam_result, 1.0f); */
  1073. value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
  1074. }
  1075. if (o->_do_normals) {
  1076. rgb_to_rgba_unit_alpha(&ibuf_normal->rect_float[4 * (res_x * y + x)], ocr.normal);
  1077. }
  1078. }
  1079. }
  1080. /* write the images */
  1081. cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_DISPLACE);
  1082. if (0 == BKE_imbuf_write(ibuf_disp, string, &imf))
  1083. printf("Cannot save Displacement File Output to %s\n", string);
  1084. if (o->_do_jacobian) {
  1085. cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_FOAM);
  1086. if (0 == BKE_imbuf_write(ibuf_foam, string, &imf))
  1087. printf("Cannot save Foam File Output to %s\n", string);
  1088. }
  1089. if (o->_do_normals) {
  1090. cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_NORMAL);
  1091. if (0 == BKE_imbuf_write(ibuf_normal, string, &imf))
  1092. printf("Cannot save Normal File Output to %s\n", string);
  1093. }
  1094. IMB_freeImBuf(ibuf_disp);
  1095. IMB_freeImBuf(ibuf_foam);
  1096. IMB_freeImBuf(ibuf_normal);
  1097. progress = (f - och->start) / (float)och->duration;
  1098. update_cb(update_cb_data, progress, &cancel);
  1099. if (cancel) {
  1100. if (prev_foam) MEM_freeN(prev_foam);
  1101. //BLI_rng_free(rng);
  1102. return;
  1103. }
  1104. }
  1105. //BLI_rng_free(rng);
  1106. if (prev_foam) MEM_freeN(prev_foam);
  1107. och->baked = 1;
  1108. }
  1109. #else /* WITH_OCEANSIM */
  1110. /* stub */
  1111. typedef struct Ocean {
  1112. /* need some data here, C does not allow empty struct */
  1113. int stub;
  1114. } Ocean;
  1115. float BKE_ocean_jminus_to_foam(float UNUSED(jminus), float UNUSED(coverage))
  1116. {
  1117. return 0.0f;
  1118. }
  1119. void BKE_ocean_eval_uv(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u), float UNUSED(v))
  1120. {
  1121. }
  1122. /* use catmullrom interpolation rather than linear */
  1123. void BKE_ocean_eval_uv_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u),
  1124. float UNUSED(v))
  1125. {
  1126. }
  1127. void BKE_ocean_eval_xz(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x), float UNUSED(z))
  1128. {
  1129. }
  1130. void BKE_ocean_eval_xz_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x),
  1131. float UNUSED(z))
  1132. {
  1133. }
  1134. void BKE_ocean_eval_ij(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), int UNUSED(i), int UNUSED(j))
  1135. {
  1136. }
  1137. void BKE_ocean_simulate(struct Ocean *UNUSED(o), float UNUSED(t), float UNUSED(scale), float UNUSED(chop_amount))
  1138. {
  1139. }
  1140. struct Ocean *BKE_ocean_add(void)
  1141. {
  1142. Ocean *oc = MEM_callocN(sizeof(Ocean), "ocean sim data");
  1143. return oc;
  1144. }
  1145. void BKE_ocean_init(struct Ocean *UNUSED(o), int UNUSED(M), int UNUSED(N), float UNUSED(Lx), float UNUSED(Lz),
  1146. float UNUSED(V), float UNUSED(l), float UNUSED(A), float UNUSED(w), float UNUSED(damp),
  1147. float UNUSED(alignment), float UNUSED(depth), float UNUSED(time), short UNUSED(do_height_field),
  1148. short UNUSED(do_chop), short UNUSED(do_normals), short UNUSED(do_jacobian), int UNUSED(seed))
  1149. {
  1150. }
  1151. void BKE_ocean_free_data(struct Ocean *UNUSED(oc))
  1152. {
  1153. }
  1154. void BKE_ocean_free(struct Ocean *oc)
  1155. {
  1156. if (!oc) return;
  1157. MEM_freeN(oc);
  1158. }
  1159. /* ********* Baking/Caching ********* */
  1160. void BKE_ocean_free_cache(struct OceanCache *och)
  1161. {
  1162. if (!och) return;
  1163. MEM_freeN(och);
  1164. }
  1165. void BKE_ocean_cache_eval_uv(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f),
  1166. float UNUSED(u), float UNUSED(v))
  1167. {
  1168. }
  1169. void BKE_ocean_cache_eval_ij(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f),
  1170. int UNUSED(i), int UNUSED(j))
  1171. {
  1172. }
  1173. OceanCache *BKE_ocean_init_cache(const char *UNUSED(bakepath), const char *UNUSED(relbase), int UNUSED(start),
  1174. int UNUSED(end), float UNUSED(wave_scale), float UNUSED(chop_amount),
  1175. float UNUSED(foam_coverage), float UNUSED(foam_fade), int UNUSED(resolution))
  1176. {
  1177. OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
  1178. return och;
  1179. }
  1180. void BKE_ocean_simulate_cache(struct OceanCache *UNUSED(och), int UNUSED(frame))
  1181. {
  1182. }
  1183. void BKE_ocean_bake(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och),
  1184. void (*update_cb)(void *, float progress, int *cancel), void *UNUSED(update_cb_data))
  1185. {
  1186. /* unused */
  1187. (void)update_cb;
  1188. }
  1189. #endif /* WITH_OCEANSIM */