Blender  V2.93
ocean.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  *
19  * Based on original code by Drew Whitehouse / Houdini Ocean Toolkit
20  * OpenMP hints by Christian Schnellhammer
21  */
22 
27 #include <math.h>
28 #include <stdlib.h>
29 
30 #include <string.h>
31 
32 #include "MEM_guardedalloc.h"
33 
34 #include "DNA_modifier_types.h"
35 #include "DNA_scene_types.h"
36 
37 #include "BLI_math.h"
38 #include "BLI_path_util.h"
39 #include "BLI_rand.h"
40 #include "BLI_task.h"
41 #include "BLI_utildefines.h"
42 
43 #include "BKE_image.h"
44 #include "BKE_ocean.h"
45 #include "ocean_intern.h"
46 
47 #include "IMB_imbuf.h"
48 #include "IMB_imbuf_types.h"
49 
50 #include "RE_texture.h"
51 
52 #include "BLI_hash.h"
53 
54 #ifdef WITH_OCEANSIM
55 
56 /* Ocean code */
57 
58 static float nextfr(RNG *rng, float min, float max)
59 {
60  return BLI_rng_get_float(rng) * (min - max) + max;
61 }
62 
63 static float gaussRand(RNG *rng)
64 {
65  /* Note: to avoid numerical problems with very small numbers, we make these variables
66  * singe-precision floats, but later we call the double-precision log() and sqrt() functions
67  * instead of logf() and sqrtf(). */
68  float x;
69  float y;
70  float length2;
71 
72  do {
73  x = (float)(nextfr(rng, -1, 1));
74  y = (float)(nextfr(rng, -1, 1));
75  length2 = x * x + y * y;
76  } while (length2 >= 1 || length2 == 0);
77 
78  return x * sqrtf(-2.0f * logf(length2) / length2);
79 }
80 
84 MINLINE float catrom(float p0, float p1, float p2, float p3, float f)
85 {
86  return 0.5f * ((2.0f * p1) + (-p0 + p2) * f + (2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * f * f +
87  (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * f * f * f);
88 }
89 
90 MINLINE float omega(float k, float depth)
91 {
92  return sqrtf(GRAVITY * k * tanhf(k * depth));
93 }
94 
95 /* modified Phillips spectrum */
96 static float Ph(struct Ocean *o, float kx, float kz)
97 {
98  float tmp;
99  float k2 = kx * kx + kz * kz;
100 
101  if (k2 == 0.0f) {
102  return 0.0f; /* no DC component */
103  }
104 
105  /* damp out the waves going in the direction opposite the wind */
106  tmp = (o->_wx * kx + o->_wz * kz) / sqrtf(k2);
107  if (tmp < 0) {
108  tmp *= o->_damp_reflections;
109  }
110 
111  return o->_A * expf(-1.0f / (k2 * (o->_L * o->_L))) * expf(-k2 * (o->_l * o->_l)) *
112  powf(fabsf(tmp), o->_wind_alignment) / (k2 * k2);
113 }
114 
115 static void compute_eigenstuff(struct OceanResult *ocr, float jxx, float jzz, float jxz)
116 {
117  float a, b, qplus, qminus;
118  a = jxx + jzz;
119  b = sqrt((jxx - jzz) * (jxx - jzz) + 4 * jxz * jxz);
120 
121  ocr->Jminus = 0.5f * (a - b);
122  ocr->Jplus = 0.5f * (a + b);
123 
124  qplus = (ocr->Jplus - jxx) / jxz;
125  qminus = (ocr->Jminus - jxx) / jxz;
126 
127  a = sqrt(1 + qplus * qplus);
128  b = sqrt(1 + qminus * qminus);
129 
130  ocr->Eplus[0] = 1.0f / a;
131  ocr->Eplus[1] = 0.0f;
132  ocr->Eplus[2] = qplus / a;
133 
134  ocr->Eminus[0] = 1.0f / b;
135  ocr->Eminus[1] = 0.0f;
136  ocr->Eminus[2] = qminus / b;
137 }
138 
139 /*
140  * instead of Complex.h
141  * in fftw.h "fftw_complex" typedefed as double[2]
142  * below you can see functions are needed to work with such complex numbers.
143  */
144 static void init_complex(fftw_complex cmpl, float real, float image)
145 {
146  cmpl[0] = real;
147  cmpl[1] = image;
148 }
149 
150 static void add_comlex_c(fftw_complex res, const fftw_complex cmpl1, const fftw_complex cmpl2)
151 {
152  res[0] = cmpl1[0] + cmpl2[0];
153  res[1] = cmpl1[1] + cmpl2[1];
154 }
155 
156 static void mul_complex_f(fftw_complex res, const fftw_complex cmpl, float f)
157 {
158  res[0] = cmpl[0] * (double)f;
159  res[1] = cmpl[1] * (double)f;
160 }
161 
162 static void mul_complex_c(fftw_complex res, const fftw_complex cmpl1, const fftw_complex cmpl2)
163 {
164  fftwf_complex temp;
165  temp[0] = cmpl1[0] * cmpl2[0] - cmpl1[1] * cmpl2[1];
166  temp[1] = cmpl1[0] * cmpl2[1] + cmpl1[1] * cmpl2[0];
167  res[0] = temp[0];
168  res[1] = temp[1];
169 }
170 
171 static float real_c(fftw_complex cmpl)
172 {
173  return cmpl[0];
174 }
175 
176 static float image_c(fftw_complex cmpl)
177 {
178  return cmpl[1];
179 }
180 
181 static void conj_complex(fftw_complex res, const fftw_complex cmpl1)
182 {
183  res[0] = cmpl1[0];
184  res[1] = -cmpl1[1];
185 }
186 
187 static void exp_complex(fftw_complex res, fftw_complex cmpl)
188 {
189  float r = expf(cmpl[0]);
190 
191  res[0] = cosf(cmpl[1]) * r;
192  res[1] = sinf(cmpl[1]) * r;
193 }
194 
195 float BKE_ocean_jminus_to_foam(float jminus, float coverage)
196 {
197  float foam = jminus * -0.005f + coverage;
198  CLAMP(foam, 0.0f, 1.0f);
199  return foam;
200 }
201 
202 void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
203 {
204  int i0, i1, j0, j1;
205  float frac_x, frac_z;
206  float uu, vv;
207 
208  /* first wrap the texture so 0 <= (u, v) < 1 */
209  u = fmodf(u, 1.0f);
210  v = fmodf(v, 1.0f);
211 
212  if (u < 0) {
213  u += 1.0f;
214  }
215  if (v < 0) {
216  v += 1.0f;
217  }
218 
219  BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
220 
221  uu = u * oc->_M;
222  vv = v * oc->_N;
223 
224  i0 = (int)floor(uu);
225  j0 = (int)floor(vv);
226 
227  i1 = (i0 + 1);
228  j1 = (j0 + 1);
229 
230  frac_x = uu - i0;
231  frac_z = vv - j0;
232 
233  i0 = i0 % oc->_M;
234  j0 = j0 % oc->_N;
235 
236  i1 = i1 % oc->_M;
237  j1 = j1 % oc->_N;
238 
239 # define BILERP(m) \
240  (interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \
241  interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \
242  frac_z))
243 
244  {
245  if (oc->_do_disp_y) {
246  ocr->disp[1] = BILERP(oc->_disp_y);
247  }
248 
249  if (oc->_do_normals) {
250  ocr->normal[0] = BILERP(oc->_N_x);
251  ocr->normal[1] = oc->_N_y /*BILERP(oc->_N_y) (MEM01)*/;
252  ocr->normal[2] = BILERP(oc->_N_z);
253  }
254 
255  if (oc->_do_chop) {
256  ocr->disp[0] = BILERP(oc->_disp_x);
257  ocr->disp[2] = BILERP(oc->_disp_z);
258  }
259  else {
260  ocr->disp[0] = 0.0;
261  ocr->disp[2] = 0.0;
262  }
263 
264  if (oc->_do_jacobian) {
265  compute_eigenstuff(ocr, BILERP(oc->_Jxx), BILERP(oc->_Jzz), BILERP(oc->_Jxz));
266  }
267  }
268 # undef BILERP
269 
270  BLI_rw_mutex_unlock(&oc->oceanmutex);
271 }
272 
273 /* use catmullrom interpolation rather than linear */
274 void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
275 {
276  int i0, i1, i2, i3, j0, j1, j2, j3;
277  float frac_x, frac_z;
278  float uu, vv;
279 
280  /* first wrap the texture so 0 <= (u, v) < 1 */
281  u = fmod(u, 1.0f);
282  v = fmod(v, 1.0f);
283 
284  if (u < 0) {
285  u += 1.0f;
286  }
287  if (v < 0) {
288  v += 1.0f;
289  }
290 
291  BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
292 
293  uu = u * oc->_M;
294  vv = v * oc->_N;
295 
296  i1 = (int)floor(uu);
297  j1 = (int)floor(vv);
298 
299  i2 = (i1 + 1);
300  j2 = (j1 + 1);
301 
302  frac_x = uu - i1;
303  frac_z = vv - j1;
304 
305  i1 = i1 % oc->_M;
306  j1 = j1 % oc->_N;
307 
308  i2 = i2 % oc->_M;
309  j2 = j2 % oc->_N;
310 
311  i0 = (i1 - 1);
312  i3 = (i2 + 1);
313  i0 = i0 < 0 ? i0 + oc->_M : i0;
314  i3 = i3 >= oc->_M ? i3 - oc->_M : i3;
315 
316  j0 = (j1 - 1);
317  j3 = (j2 + 1);
318  j0 = j0 < 0 ? j0 + oc->_N : j0;
319  j3 = j3 >= oc->_N ? j3 - oc->_N : j3;
320 
321 # define INTERP(m) \
322  catrom(catrom(m[i0 * oc->_N + j0], \
323  m[i1 * oc->_N + j0], \
324  m[i2 * oc->_N + j0], \
325  m[i3 * oc->_N + j0], \
326  frac_x), \
327  catrom(m[i0 * oc->_N + j1], \
328  m[i1 * oc->_N + j1], \
329  m[i2 * oc->_N + j1], \
330  m[i3 * oc->_N + j1], \
331  frac_x), \
332  catrom(m[i0 * oc->_N + j2], \
333  m[i1 * oc->_N + j2], \
334  m[i2 * oc->_N + j2], \
335  m[i3 * oc->_N + j2], \
336  frac_x), \
337  catrom(m[i0 * oc->_N + j3], \
338  m[i1 * oc->_N + j3], \
339  m[i2 * oc->_N + j3], \
340  m[i3 * oc->_N + j3], \
341  frac_x), \
342  frac_z)
343 
344  {
345  if (oc->_do_disp_y) {
346  ocr->disp[1] = INTERP(oc->_disp_y);
347  }
348  if (oc->_do_normals) {
349  ocr->normal[0] = INTERP(oc->_N_x);
350  ocr->normal[1] = oc->_N_y /*INTERP(oc->_N_y) (MEM01)*/;
351  ocr->normal[2] = INTERP(oc->_N_z);
352  }
353  if (oc->_do_chop) {
354  ocr->disp[0] = INTERP(oc->_disp_x);
355  ocr->disp[2] = INTERP(oc->_disp_z);
356  }
357  else {
358  ocr->disp[0] = 0.0;
359  ocr->disp[2] = 0.0;
360  }
361 
362  if (oc->_do_jacobian) {
363  compute_eigenstuff(ocr, INTERP(oc->_Jxx), INTERP(oc->_Jzz), INTERP(oc->_Jxz));
364  }
365  }
366 # undef INTERP
367 
368  BLI_rw_mutex_unlock(&oc->oceanmutex);
369 }
370 
371 void BKE_ocean_eval_xz(struct Ocean *oc, struct OceanResult *ocr, float x, float z)
372 {
373  BKE_ocean_eval_uv(oc, ocr, x / oc->_Lx, z / oc->_Lz);
374 }
375 
376 void BKE_ocean_eval_xz_catrom(struct Ocean *oc, struct OceanResult *ocr, float x, float z)
377 {
378  BKE_ocean_eval_uv_catrom(oc, ocr, x / oc->_Lx, z / oc->_Lz);
379 }
380 
381 /* note that this doesn't wrap properly for i, j < 0, but its not really meant for that being
382  * just a way to get the raw data out to save in some image format. */
383 void BKE_ocean_eval_ij(struct Ocean *oc, struct OceanResult *ocr, int i, int j)
384 {
385  BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
386 
387  i = abs(i) % oc->_M;
388  j = abs(j) % oc->_N;
389 
390  ocr->disp[1] = oc->_do_disp_y ? (float)oc->_disp_y[i * oc->_N + j] : 0.0f;
391 
392  if (oc->_do_chop) {
393  ocr->disp[0] = oc->_disp_x[i * oc->_N + j];
394  ocr->disp[2] = oc->_disp_z[i * oc->_N + j];
395  }
396  else {
397  ocr->disp[0] = 0.0f;
398  ocr->disp[2] = 0.0f;
399  }
400 
401  if (oc->_do_normals) {
402  ocr->normal[0] = oc->_N_x[i * oc->_N + j];
403  ocr->normal[1] = oc->_N_y /* oc->_N_y[i * oc->_N + j] (MEM01) */;
404  ocr->normal[2] = oc->_N_z[i * oc->_N + j];
405 
406  normalize_v3(ocr->normal);
407  }
408 
409  if (oc->_do_jacobian) {
410  compute_eigenstuff(
411  ocr, oc->_Jxx[i * oc->_N + j], oc->_Jzz[i * oc->_N + j], oc->_Jxz[i * oc->_N + j]);
412  }
413 
414  BLI_rw_mutex_unlock(&oc->oceanmutex);
415 }
416 
417 typedef struct OceanSimulateData {
418  Ocean *o;
419  float t;
420  float scale;
421  float chop_amount;
422 } OceanSimulateData;
423 
424 static void ocean_compute_htilda(void *__restrict userdata,
425  const int i,
426  const TaskParallelTLS *__restrict UNUSED(tls))
427 {
428  OceanSimulateData *osd = userdata;
429  const Ocean *o = osd->o;
430  const float scale = osd->scale;
431  const float t = osd->t;
432 
433  int j;
434 
435  /* Note the <= _N/2 here, see the FFTW documentation
436  * about the mechanics of the complex->real fft storage. */
437  for (j = 0; j <= o->_N / 2; j++) {
438  fftw_complex exp_param1;
439  fftw_complex exp_param2;
440  fftw_complex conj_param;
441 
442  init_complex(exp_param1, 0.0, omega(o->_k[i * (1 + o->_N / 2) + j], o->_depth) * t);
443  init_complex(exp_param2, 0.0, -omega(o->_k[i * (1 + o->_N / 2) + j], o->_depth) * t);
444  exp_complex(exp_param1, exp_param1);
445  exp_complex(exp_param2, exp_param2);
446  conj_complex(conj_param, o->_h0_minus[i * o->_N + j]);
447 
448  mul_complex_c(exp_param1, o->_h0[i * o->_N + j], exp_param1);
449  mul_complex_c(exp_param2, conj_param, exp_param2);
450 
451  add_comlex_c(o->_htilda[i * (1 + o->_N / 2) + j], exp_param1, exp_param2);
452  mul_complex_f(o->_fft_in[i * (1 + o->_N / 2) + j], o->_htilda[i * (1 + o->_N / 2) + j], scale);
453  }
454 }
455 
456 static void ocean_compute_displacement_y(TaskPool *__restrict pool, void *UNUSED(taskdata))
457 {
458  OceanSimulateData *osd = BLI_task_pool_user_data(pool);
459  const Ocean *o = osd->o;
460 
461  fftw_execute(o->_disp_y_plan);
462 }
463 
464 static void ocean_compute_displacement_x(TaskPool *__restrict pool, void *UNUSED(taskdata))
465 {
466  OceanSimulateData *osd = BLI_task_pool_user_data(pool);
467  const Ocean *o = osd->o;
468  const float scale = osd->scale;
469  const float chop_amount = osd->chop_amount;
470  int i, j;
471 
472  for (i = 0; i < o->_M; i++) {
473  for (j = 0; j <= o->_N / 2; j++) {
474  fftw_complex mul_param;
475  fftw_complex minus_i;
476 
477  init_complex(minus_i, 0.0, -1.0);
478  init_complex(mul_param, -scale, 0);
479  mul_complex_f(mul_param, mul_param, chop_amount);
480  mul_complex_c(mul_param, mul_param, minus_i);
481  mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
482  mul_complex_f(mul_param,
483  mul_param,
484  ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
485  0.0f :
486  o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
487  init_complex(o->_fft_in_x[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
488  }
489  }
490  fftw_execute(o->_disp_x_plan);
491 }
492 
493 static void ocean_compute_displacement_z(TaskPool *__restrict pool, void *UNUSED(taskdata))
494 {
495  OceanSimulateData *osd = BLI_task_pool_user_data(pool);
496  const Ocean *o = osd->o;
497  const float scale = osd->scale;
498  const float chop_amount = osd->chop_amount;
499  int i, j;
500 
501  for (i = 0; i < o->_M; i++) {
502  for (j = 0; j <= o->_N / 2; j++) {
503  fftw_complex mul_param;
504  fftw_complex minus_i;
505 
506  init_complex(minus_i, 0.0, -1.0);
507  init_complex(mul_param, -scale, 0);
508  mul_complex_f(mul_param, mul_param, chop_amount);
509  mul_complex_c(mul_param, mul_param, minus_i);
510  mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
511  mul_complex_f(mul_param,
512  mul_param,
513  ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
514  0.0f :
515  o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
516  init_complex(o->_fft_in_z[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
517  }
518  }
519  fftw_execute(o->_disp_z_plan);
520 }
521 
522 static void ocean_compute_jacobian_jxx(TaskPool *__restrict pool, void *UNUSED(taskdata))
523 {
524  OceanSimulateData *osd = BLI_task_pool_user_data(pool);
525  const Ocean *o = osd->o;
526  const float chop_amount = osd->chop_amount;
527  int i, j;
528 
529  for (i = 0; i < o->_M; i++) {
530  for (j = 0; j <= o->_N / 2; j++) {
531  fftw_complex mul_param;
532 
533  /* init_complex(mul_param, -scale, 0); */
534  init_complex(mul_param, -1, 0);
535 
536  mul_complex_f(mul_param, mul_param, chop_amount);
537  mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
538  mul_complex_f(mul_param,
539  mul_param,
540  ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
541  0.0f :
542  o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
543  init_complex(o->_fft_in_jxx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
544  }
545  }
546  fftw_execute(o->_Jxx_plan);
547 
548  for (i = 0; i < o->_M; i++) {
549  for (j = 0; j < o->_N; j++) {
550  o->_Jxx[i * o->_N + j] += 1.0;
551  }
552  }
553 }
554 
555 static void ocean_compute_jacobian_jzz(TaskPool *__restrict pool, void *UNUSED(taskdata))
556 {
557  OceanSimulateData *osd = BLI_task_pool_user_data(pool);
558  const Ocean *o = osd->o;
559  const float chop_amount = osd->chop_amount;
560  int i, j;
561 
562  for (i = 0; i < o->_M; i++) {
563  for (j = 0; j <= o->_N / 2; j++) {
564  fftw_complex mul_param;
565 
566  /* init_complex(mul_param, -scale, 0); */
567  init_complex(mul_param, -1, 0);
568 
569  mul_complex_f(mul_param, mul_param, chop_amount);
570  mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
571  mul_complex_f(mul_param,
572  mul_param,
573  ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
574  0.0f :
575  o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
576  init_complex(o->_fft_in_jzz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
577  }
578  }
579  fftw_execute(o->_Jzz_plan);
580 
581  for (i = 0; i < o->_M; i++) {
582  for (j = 0; j < o->_N; j++) {
583  o->_Jzz[i * o->_N + j] += 1.0;
584  }
585  }
586 }
587 
588 static void ocean_compute_jacobian_jxz(TaskPool *__restrict pool, void *UNUSED(taskdata))
589 {
590  OceanSimulateData *osd = BLI_task_pool_user_data(pool);
591  const Ocean *o = osd->o;
592  const float chop_amount = osd->chop_amount;
593  int i, j;
594 
595  for (i = 0; i < o->_M; i++) {
596  for (j = 0; j <= o->_N / 2; j++) {
597  fftw_complex mul_param;
598 
599  /* init_complex(mul_param, -scale, 0); */
600  init_complex(mul_param, -1, 0);
601 
602  mul_complex_f(mul_param, mul_param, chop_amount);
603  mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
604  mul_complex_f(mul_param,
605  mul_param,
606  ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
607  0.0f :
608  o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
609  init_complex(o->_fft_in_jxz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
610  }
611  }
612  fftw_execute(o->_Jxz_plan);
613 }
614 
615 static void ocean_compute_normal_x(TaskPool *__restrict pool, void *UNUSED(taskdata))
616 {
617  OceanSimulateData *osd = BLI_task_pool_user_data(pool);
618  const Ocean *o = osd->o;
619  int i, j;
620 
621  for (i = 0; i < o->_M; i++) {
622  for (j = 0; j <= o->_N / 2; j++) {
623  fftw_complex mul_param;
624 
625  init_complex(mul_param, 0.0, -1.0);
626  mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
627  mul_complex_f(mul_param, mul_param, o->_kx[i]);
628  init_complex(o->_fft_in_nx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
629  }
630  }
631  fftw_execute(o->_N_x_plan);
632 }
633 
634 static void ocean_compute_normal_z(TaskPool *__restrict pool, void *UNUSED(taskdata))
635 {
636  OceanSimulateData *osd = BLI_task_pool_user_data(pool);
637  const Ocean *o = osd->o;
638  int i, j;
639 
640  for (i = 0; i < o->_M; i++) {
641  for (j = 0; j <= o->_N / 2; j++) {
642  fftw_complex mul_param;
643 
644  init_complex(mul_param, 0.0, -1.0);
645  mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
646  mul_complex_f(mul_param, mul_param, o->_kz[i]);
647  init_complex(o->_fft_in_nz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
648  }
649  }
650  fftw_execute(o->_N_z_plan);
651 }
652 
653 void BKE_ocean_simulate(struct Ocean *o, float t, float scale, float chop_amount)
654 {
655  TaskPool *pool;
656 
657  OceanSimulateData osd;
658 
659  scale *= o->normalize_factor;
660 
661  osd.o = o;
662  osd.t = t;
663  osd.scale = scale;
664  osd.chop_amount = chop_amount;
665 
667 
668  BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
669 
670  /* Note about multi-threading here: we have to run a first set of computations (htilda one)
671  * before we can run all others, since they all depend on it.
672  * So we make a first parallelized forloop run for htilda,
673  * and then pack all other computations into a set of parallel tasks.
674  * This is not optimal in all cases,
675  * but remains reasonably simple and should be OK most of the time. */
676 
677  /* compute a new htilda */
678  TaskParallelSettings settings;
680  settings.use_threading = (o->_M > 16);
681  BLI_task_parallel_range(0, o->_M, &osd, ocean_compute_htilda, &settings);
682 
683  if (o->_do_disp_y) {
684  BLI_task_pool_push(pool, ocean_compute_displacement_y, NULL, false, NULL);
685  }
686 
687  if (o->_do_chop) {
688  BLI_task_pool_push(pool, ocean_compute_displacement_x, NULL, false, NULL);
689  BLI_task_pool_push(pool, ocean_compute_displacement_z, NULL, false, NULL);
690  }
691 
692  if (o->_do_jacobian) {
693  BLI_task_pool_push(pool, ocean_compute_jacobian_jxx, NULL, false, NULL);
694  BLI_task_pool_push(pool, ocean_compute_jacobian_jzz, NULL, false, NULL);
695  BLI_task_pool_push(pool, ocean_compute_jacobian_jxz, NULL, false, NULL);
696  }
697 
698  if (o->_do_normals) {
699  BLI_task_pool_push(pool, ocean_compute_normal_x, NULL, false, NULL);
700  BLI_task_pool_push(pool, ocean_compute_normal_z, NULL, false, NULL);
701  o->_N_y = 1.0f / scale;
702  }
703 
705 
706  BLI_rw_mutex_unlock(&o->oceanmutex);
707 
709 }
710 
711 static void set_height_normalize_factor(struct Ocean *oc)
712 {
713  float res = 1.0;
714  float max_h = 0.0;
715 
716  int i, j;
717 
718  if (!oc->_do_disp_y) {
719  return;
720  }
721 
722  oc->normalize_factor = 1.0;
723 
724  BKE_ocean_simulate(oc, 0.0, 1.0, 0);
725 
726  BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
727 
728  for (i = 0; i < oc->_M; i++) {
729  for (j = 0; j < oc->_N; j++) {
730  if (max_h < fabs(oc->_disp_y[i * oc->_N + j])) {
731  max_h = fabs(oc->_disp_y[i * oc->_N + j]);
732  }
733  }
734  }
735 
736  BLI_rw_mutex_unlock(&oc->oceanmutex);
737 
738  if (max_h == 0.0f) {
739  max_h = 0.00001f; /* just in case ... */
740  }
741 
742  res = 1.0f / (max_h);
743 
744  oc->normalize_factor = res;
745 }
746 
747 struct Ocean *BKE_ocean_add(void)
748 {
749  Ocean *oc = MEM_callocN(sizeof(Ocean), "ocean sim data");
750 
751  BLI_rw_mutex_init(&oc->oceanmutex);
752 
753  return oc;
754 }
755 
756 bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution)
757 {
758  if (omd->ocean) {
759  /* Check that the ocean has the same resolution than we want now. */
760  if (omd->ocean->_M == resolution * resolution) {
761  return false;
762  }
763 
764  BKE_ocean_free(omd->ocean);
765  }
766 
767  omd->ocean = BKE_ocean_add();
768  BKE_ocean_init_from_modifier(omd->ocean, omd, resolution);
769  return true;
770 }
771 
772 void BKE_ocean_init_from_modifier(struct Ocean *ocean,
773  struct OceanModifierData const *omd,
774  const int resolution)
775 {
776  short do_heightfield, do_chop, do_normals, do_jacobian, do_spray;
777 
778  do_heightfield = true;
779  do_chop = (omd->chop_amount > 0);
780  do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
781  do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
782  do_spray = do_jacobian && (omd->flag & MOD_OCEAN_GENERATE_SPRAY);
783 
784  BKE_ocean_free_data(ocean);
785 
786  BKE_ocean_init(ocean,
787  resolution * resolution,
788  resolution * resolution,
789  omd->spatial_size,
790  omd->spatial_size,
791  omd->wind_velocity,
792  omd->smallest_wave,
793  1.0,
794  omd->wave_direction,
795  omd->damp,
796  omd->wave_alignment,
797  omd->depth,
798  omd->time,
799  omd->spectrum,
800  omd->fetch_jonswap,
802  do_heightfield,
803  do_chop,
804  do_spray,
805  do_normals,
806  do_jacobian,
807  omd->seed);
808 }
809 
810 void BKE_ocean_init(struct Ocean *o,
811  int M,
812  int N,
813  float Lx,
814  float Lz,
815  float V,
816  float l,
817  float A,
818  float w,
819  float damp,
820  float alignment,
821  float depth,
822  float time,
823  int spectrum,
824  float fetch_jonswap,
825  float sharpen_peak_jonswap,
826  short do_height_field,
827  short do_chop,
828  short do_spray,
829  short do_normals,
830  short do_jacobian,
831  int seed)
832 {
833  RNG *rng;
834  int i, j, ii;
835 
836  BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
837 
838  o->_M = M;
839  o->_N = N;
840  o->_V = V;
841  o->_l = l;
842  o->_A = A;
843  o->_w = w;
844  o->_damp_reflections = 1.0f - damp;
845  o->_wind_alignment = alignment * 10.0f;
846  o->_depth = depth;
847  o->_Lx = Lx;
848  o->_Lz = Lz;
849  o->_wx = cos(w);
850  o->_wz = -sin(w); /* wave direction */
851  o->_L = V * V / GRAVITY; /* largest wave for a given velocity V */
852  o->time = time;
853 
854  /* Spectrum to use. */
855  o->_spectrum = spectrum;
856 
857  /* Common JONSWAP parameters. */
858  o->_fetch_jonswap = fetch_jonswap;
859  o->_sharpen_peak_jonswap = sharpen_peak_jonswap * 10.0f;
860 
861  o->_do_disp_y = do_height_field;
862  o->_do_normals = do_normals;
863  o->_do_spray = do_spray;
864  o->_do_chop = do_chop;
865  o->_do_jacobian = do_jacobian;
866 
867  o->_k = (float *)MEM_mallocN(M * (1 + N / 2) * sizeof(float), "ocean_k");
868  o->_h0 = (fftw_complex *)MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0");
869  o->_h0_minus = (fftw_complex *)MEM_mallocN(M * N * sizeof(fftw_complex), "ocean_h0_minus");
870  o->_kx = (float *)MEM_mallocN(o->_M * sizeof(float), "ocean_kx");
871  o->_kz = (float *)MEM_mallocN(o->_N * sizeof(float), "ocean_kz");
872 
873  /* make this robust in the face of erroneous usage */
874  if (o->_Lx == 0.0f) {
875  o->_Lx = 0.001f;
876  }
877 
878  if (o->_Lz == 0.0f) {
879  o->_Lz = 0.001f;
880  }
881 
882  /* the +ve components and DC */
883  for (i = 0; i <= o->_M / 2; i++) {
884  o->_kx[i] = 2.0f * (float)M_PI * i / o->_Lx;
885  }
886 
887  /* the -ve components */
888  for (i = o->_M - 1, ii = 0; i > o->_M / 2; i--, ii++) {
889  o->_kx[i] = -2.0f * (float)M_PI * ii / o->_Lx;
890  }
891 
892  /* the +ve components and DC */
893  for (i = 0; i <= o->_N / 2; i++) {
894  o->_kz[i] = 2.0f * (float)M_PI * i / o->_Lz;
895  }
896 
897  /* the -ve components */
898  for (i = o->_N - 1, ii = 0; i > o->_N / 2; i--, ii++) {
899  o->_kz[i] = -2.0f * (float)M_PI * ii / o->_Lz;
900  }
901 
902  /* pre-calculate the k matrix */
903  for (i = 0; i < o->_M; i++) {
904  for (j = 0; j <= o->_N / 2; j++) {
905  o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);
906  }
907  }
908 
909  rng = BLI_rng_new(seed);
910 
911  for (i = 0; i < o->_M; i++) {
912  for (j = 0; j < o->_N; j++) {
913  /* This ensures we get a value tied to the surface location, avoiding dramatic surface
914  * change with changing resolution.
915  * Explicitly cast to signed int first to ensure consistent behavior on all processors,
916  * since behavior of float to unsigned int cast is undefined in C. */
917  const int hash_x = o->_kx[i] * 360.0f;
918  const int hash_z = o->_kz[j] * 360.0f;
919  int new_seed = seed + BLI_hash_int_2d(hash_x, hash_z);
920 
921  BLI_rng_seed(rng, new_seed);
922  float r1 = gaussRand(rng);
923  float r2 = gaussRand(rng);
924 
925  fftw_complex r1r2;
926  init_complex(r1r2, r1, r2);
927  switch (o->_spectrum) {
929  mul_complex_f(o->_h0[i * o->_N + j],
930  r1r2,
931  (float)(sqrt(BLI_ocean_spectrum_jonswap(o, o->_kx[i], o->_kz[j]) / 2.0f)));
932  mul_complex_f(
933  o->_h0_minus[i * o->_N + j],
934  r1r2,
935  (float)(sqrt(BLI_ocean_spectrum_jonswap(o, -o->_kx[i], -o->_kz[j]) / 2.0f)));
936  break;
938  mul_complex_f(
939  o->_h0[i * o->_N + j],
940  r1r2,
941  (float)(sqrt(BLI_ocean_spectrum_texelmarsenarsloe(o, o->_kx[i], o->_kz[j]) / 2.0f)));
942  mul_complex_f(
943  o->_h0_minus[i * o->_N + j],
944  r1r2,
945  (float)(sqrt(BLI_ocean_spectrum_texelmarsenarsloe(o, -o->_kx[i], -o->_kz[j]) /
946  2.0f)));
947  break;
949  mul_complex_f(
950  o->_h0[i * o->_N + j],
951  r1r2,
952  (float)(sqrt(BLI_ocean_spectrum_piersonmoskowitz(o, o->_kx[i], o->_kz[j]) / 2.0f)));
953  mul_complex_f(
954  o->_h0_minus[i * o->_N + j],
955  r1r2,
956  (float)(sqrt(BLI_ocean_spectrum_piersonmoskowitz(o, -o->_kx[i], -o->_kz[j]) /
957  2.0f)));
958  break;
959  default:
960  mul_complex_f(
961  o->_h0[i * o->_N + j], r1r2, (float)(sqrt(Ph(o, o->_kx[i], o->_kz[j]) / 2.0f)));
962  mul_complex_f(o->_h0_minus[i * o->_N + j],
963  r1r2,
964  (float)(sqrt(Ph(o, -o->_kx[i], -o->_kz[j]) / 2.0f)));
965  break;
966  }
967  }
968  }
969 
970  o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
971  "ocean_fft_in");
972  o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
973  "ocean_htilda");
974 
976 
977  if (o->_do_disp_y) {
978  o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
979  o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
980  }
981 
982  if (o->_do_normals) {
983  o->_fft_in_nx = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
984  "ocean_fft_in_nx");
985  o->_fft_in_nz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
986  "ocean_fft_in_nz");
987 
988  o->_N_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
989  /* o->_N_y = (float *) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01) */
990  o->_N_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");
991 
992  o->_N_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nx, o->_N_x, FFTW_ESTIMATE);
993  o->_N_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nz, o->_N_z, FFTW_ESTIMATE);
994  }
995 
996  if (o->_do_chop) {
997  o->_fft_in_x = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
998  "ocean_fft_in_x");
999  o->_fft_in_z = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
1000  "ocean_fft_in_z");
1001 
1002  o->_disp_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
1003  o->_disp_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");
1004 
1005  o->_disp_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_x, o->_disp_x, FFTW_ESTIMATE);
1006  o->_disp_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_z, o->_disp_z, FFTW_ESTIMATE);
1007  }
1008  if (o->_do_jacobian) {
1009  o->_fft_in_jxx = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
1010  "ocean_fft_in_jxx");
1011  o->_fft_in_jzz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
1012  "ocean_fft_in_jzz");
1013  o->_fft_in_jxz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
1014  "ocean_fft_in_jxz");
1015 
1016  o->_Jxx = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
1017  o->_Jzz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
1018  o->_Jxz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");
1019 
1020  o->_Jxx_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxx, o->_Jxx, FFTW_ESTIMATE);
1021  o->_Jzz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jzz, o->_Jzz, FFTW_ESTIMATE);
1022  o->_Jxz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxz, o->_Jxz, FFTW_ESTIMATE);
1023  }
1024 
1026 
1027  BLI_rw_mutex_unlock(&o->oceanmutex);
1028 
1029  set_height_normalize_factor(o);
1030 
1031  BLI_rng_free(rng);
1032 }
1033 
1034 void BKE_ocean_free_data(struct Ocean *oc)
1035 {
1036  if (!oc) {
1037  return;
1038  }
1039 
1040  BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_WRITE);
1041 
1043 
1044  if (oc->_do_disp_y) {
1045  fftw_destroy_plan(oc->_disp_y_plan);
1046  MEM_freeN(oc->_disp_y);
1047  }
1048 
1049  if (oc->_do_normals) {
1050  MEM_freeN(oc->_fft_in_nx);
1051  MEM_freeN(oc->_fft_in_nz);
1052  fftw_destroy_plan(oc->_N_x_plan);
1053  fftw_destroy_plan(oc->_N_z_plan);
1054  MEM_freeN(oc->_N_x);
1055  /*fftwf_free(oc->_N_y); (MEM01)*/
1056  MEM_freeN(oc->_N_z);
1057  }
1058 
1059  if (oc->_do_chop) {
1060  MEM_freeN(oc->_fft_in_x);
1061  MEM_freeN(oc->_fft_in_z);
1062  fftw_destroy_plan(oc->_disp_x_plan);
1063  fftw_destroy_plan(oc->_disp_z_plan);
1064  MEM_freeN(oc->_disp_x);
1065  MEM_freeN(oc->_disp_z);
1066  }
1067 
1068  if (oc->_do_jacobian) {
1069  MEM_freeN(oc->_fft_in_jxx);
1070  MEM_freeN(oc->_fft_in_jzz);
1071  MEM_freeN(oc->_fft_in_jxz);
1072  fftw_destroy_plan(oc->_Jxx_plan);
1073  fftw_destroy_plan(oc->_Jzz_plan);
1074  fftw_destroy_plan(oc->_Jxz_plan);
1075  MEM_freeN(oc->_Jxx);
1076  MEM_freeN(oc->_Jzz);
1077  MEM_freeN(oc->_Jxz);
1078  }
1079 
1081 
1082  if (oc->_fft_in) {
1083  MEM_freeN(oc->_fft_in);
1084  }
1085 
1086  /* check that ocean data has been initialized */
1087  if (oc->_htilda) {
1088  MEM_freeN(oc->_htilda);
1089  MEM_freeN(oc->_k);
1090  MEM_freeN(oc->_h0);
1091  MEM_freeN(oc->_h0_minus);
1092  MEM_freeN(oc->_kx);
1093  MEM_freeN(oc->_kz);
1094  }
1095 
1096  BLI_rw_mutex_unlock(&oc->oceanmutex);
1097 }
1098 
1099 void BKE_ocean_free(struct Ocean *oc)
1100 {
1101  if (!oc) {
1102  return;
1103  }
1104 
1105  BKE_ocean_free_data(oc);
1106  BLI_rw_mutex_end(&oc->oceanmutex);
1107 
1108  MEM_freeN(oc);
1109 }
1110 
1111 # undef GRAVITY
1112 
1113 /* ********* Baking/Caching ********* */
1114 
1115 # define CACHE_TYPE_DISPLACE 1
1116 # define CACHE_TYPE_FOAM 2
1117 # define CACHE_TYPE_NORMAL 3
1118 # define CACHE_TYPE_SPRAY 4
1119 # define CACHE_TYPE_SPRAY_INVERSE 5
1120 
1121 static void cache_filename(
1122  char *string, const char *path, const char *relbase, int frame, int type)
1123 {
1124  char cachepath[FILE_MAX];
1125  const char *fname;
1126 
1127  switch (type) {
1128  case CACHE_TYPE_FOAM:
1129  fname = "foam_";
1130  break;
1131  case CACHE_TYPE_NORMAL:
1132  fname = "normal_";
1133  break;
1134  case CACHE_TYPE_SPRAY:
1135  fname = "spray_";
1136  break;
1137  case CACHE_TYPE_SPRAY_INVERSE:
1138  fname = "spray_inverse_";
1139  break;
1140  case CACHE_TYPE_DISPLACE:
1141  default:
1142  fname = "disp_";
1143  break;
1144  }
1145 
1146  BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
1147 
1149  string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, true, true, "");
1150 }
1151 
1152 /* silly functions but useful to inline when the args do a lot of indirections */
1153 MINLINE void rgb_to_rgba_unit_alpha(float r_rgba[4], const float rgb[3])
1154 {
1155  r_rgba[0] = rgb[0];
1156  r_rgba[1] = rgb[1];
1157  r_rgba[2] = rgb[2];
1158  r_rgba[3] = 1.0f;
1159 }
1160 MINLINE void value_to_rgba_unit_alpha(float r_rgba[4], const float value)
1161 {
1162  r_rgba[0] = value;
1163  r_rgba[1] = value;
1164  r_rgba[2] = value;
1165  r_rgba[3] = 1.0f;
1166 }
1167 
1168 void BKE_ocean_free_cache(struct OceanCache *och)
1169 {
1170  int i, f = 0;
1171 
1172  if (!och) {
1173  return;
1174  }
1175 
1176  if (och->ibufs_disp) {
1177  for (i = och->start, f = 0; i <= och->end; i++, f++) {
1178  if (och->ibufs_disp[f]) {
1179  IMB_freeImBuf(och->ibufs_disp[f]);
1180  }
1181  }
1182  MEM_freeN(och->ibufs_disp);
1183  }
1184 
1185  if (och->ibufs_foam) {
1186  for (i = och->start, f = 0; i <= och->end; i++, f++) {
1187  if (och->ibufs_foam[f]) {
1188  IMB_freeImBuf(och->ibufs_foam[f]);
1189  }
1190  }
1191  MEM_freeN(och->ibufs_foam);
1192  }
1193 
1194  if (och->ibufs_spray) {
1195  for (i = och->start, f = 0; i <= och->end; i++, f++) {
1196  if (och->ibufs_spray[f]) {
1197  IMB_freeImBuf(och->ibufs_spray[f]);
1198  }
1199  }
1200  MEM_freeN(och->ibufs_spray);
1201  }
1202 
1203  if (och->ibufs_spray_inverse) {
1204  for (i = och->start, f = 0; i <= och->end; i++, f++) {
1205  if (och->ibufs_spray_inverse[f]) {
1207  }
1208  }
1210  }
1211 
1212  if (och->ibufs_norm) {
1213  for (i = och->start, f = 0; i <= och->end; i++, f++) {
1214  if (och->ibufs_norm[f]) {
1215  IMB_freeImBuf(och->ibufs_norm[f]);
1216  }
1217  }
1218  MEM_freeN(och->ibufs_norm);
1219  }
1220 
1221  if (och->time) {
1222  MEM_freeN(och->time);
1223  }
1224  MEM_freeN(och);
1225 }
1226 
1228  struct OceanCache *och, struct OceanResult *ocr, int f, float u, float v)
1229 {
1230  int res_x = och->resolution_x;
1231  int res_y = och->resolution_y;
1232  float result[4];
1233 
1234  u = fmod(u, 1.0);
1235  v = fmod(v, 1.0);
1236 
1237  if (u < 0) {
1238  u += 1.0f;
1239  }
1240  if (v < 0) {
1241  v += 1.0f;
1242  }
1243 
1244  if (och->ibufs_disp[f]) {
1245  ibuf_sample(och->ibufs_disp[f], u, v, (1.0f / (float)res_x), (1.0f / (float)res_y), result);
1246  copy_v3_v3(ocr->disp, result);
1247  }
1248 
1249  if (och->ibufs_foam[f]) {
1250  ibuf_sample(och->ibufs_foam[f], u, v, (1.0f / (float)res_x), (1.0f / (float)res_y), result);
1251  ocr->foam = result[0];
1252  }
1253 
1254  if (och->ibufs_spray[f]) {
1255  ibuf_sample(och->ibufs_spray[f], u, v, (1.0f / (float)res_x), (1.0f / (float)res_y), result);
1256  copy_v3_v3(ocr->Eplus, result);
1257  }
1258 
1259  if (och->ibufs_spray_inverse[f]) {
1260  ibuf_sample(
1261  och->ibufs_spray_inverse[f], u, v, (1.0f / (float)res_x), (1.0f / (float)res_y), result);
1262  copy_v3_v3(ocr->Eminus, result);
1263  }
1264 
1265  if (och->ibufs_norm[f]) {
1266  ibuf_sample(och->ibufs_norm[f], u, v, (1.0f / (float)res_x), (1.0f / (float)res_y), result);
1267  copy_v3_v3(ocr->normal, result);
1268  }
1269 }
1270 
1271 void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, int f, int i, int j)
1272 {
1273  const int res_x = och->resolution_x;
1274  const int res_y = och->resolution_y;
1275 
1276  if (i < 0) {
1277  i = -i;
1278  }
1279  if (j < 0) {
1280  j = -j;
1281  }
1282 
1283  i = i % res_x;
1284  j = j % res_y;
1285 
1286  if (och->ibufs_disp[f]) {
1287  copy_v3_v3(ocr->disp, &och->ibufs_disp[f]->rect_float[4 * (res_x * j + i)]);
1288  }
1289 
1290  if (och->ibufs_foam[f]) {
1291  ocr->foam = och->ibufs_foam[f]->rect_float[4 * (res_x * j + i)];
1292  }
1293 
1294  if (och->ibufs_spray[f]) {
1295  copy_v3_v3(ocr->Eplus, &och->ibufs_spray[f]->rect_float[4 * (res_x * j + i)]);
1296  }
1297 
1298  if (och->ibufs_spray_inverse[f]) {
1299  copy_v3_v3(ocr->Eminus, &och->ibufs_spray_inverse[f]->rect_float[4 * (res_x * j + i)]);
1300  }
1301 
1302  if (och->ibufs_norm[f]) {
1303  copy_v3_v3(ocr->normal, &och->ibufs_norm[f]->rect_float[4 * (res_x * j + i)]);
1304  }
1305 }
1306 
1307 struct OceanCache *BKE_ocean_init_cache(const char *bakepath,
1308  const char *relbase,
1309  int start,
1310  int end,
1311  float wave_scale,
1312  float chop_amount,
1313  float foam_coverage,
1314  float foam_fade,
1315  int resolution)
1316 {
1317  OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
1318 
1319  och->bakepath = bakepath;
1320  och->relbase = relbase;
1321 
1322  och->start = start;
1323  och->end = end;
1324  och->duration = (end - start) + 1;
1325  och->wave_scale = wave_scale;
1326  och->chop_amount = chop_amount;
1328  och->foam_fade = foam_fade;
1329  och->resolution_x = resolution * resolution;
1330  och->resolution_y = resolution * resolution;
1331 
1332  och->ibufs_disp = MEM_callocN(sizeof(ImBuf *) * och->duration,
1333  "displacement imbuf pointer array");
1334  och->ibufs_foam = MEM_callocN(sizeof(ImBuf *) * och->duration, "foam imbuf pointer array");
1335  och->ibufs_spray = MEM_callocN(sizeof(ImBuf *) * och->duration, "spray imbuf pointer array");
1336  och->ibufs_spray_inverse = MEM_callocN(sizeof(ImBuf *) * och->duration,
1337  "spray_inverse imbuf pointer array");
1338  och->ibufs_norm = MEM_callocN(sizeof(ImBuf *) * och->duration, "normal imbuf pointer array");
1339 
1340  och->time = NULL;
1341 
1342  return och;
1343 }
1344 
1345 void BKE_ocean_simulate_cache(struct OceanCache *och, int frame)
1346 {
1347  char string[FILE_MAX];
1348  int f = frame;
1349 
1350  /* ibufs array is zero based, but filenames are based on frame numbers */
1351  /* still need to clamp frame numbers to valid range of images on disk though */
1352  CLAMP(frame, och->start, och->end);
1353  f = frame - och->start; /* shift to 0 based */
1354 
1355  /* if image is already loaded in mem, return */
1356  if (och->ibufs_disp[f] != NULL) {
1357  return;
1358  }
1359 
1360  /* Use default color spaces since we know for sure cache
1361  * files were saved with default settings too. */
1362 
1363  cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_DISPLACE);
1364  och->ibufs_disp[f] = IMB_loadiffname(string, 0, NULL);
1365 
1366  cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_FOAM);
1367  och->ibufs_foam[f] = IMB_loadiffname(string, 0, NULL);
1368 
1369  cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_SPRAY);
1370  och->ibufs_spray[f] = IMB_loadiffname(string, 0, NULL);
1371 
1372  cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_SPRAY_INVERSE);
1373  och->ibufs_spray_inverse[f] = IMB_loadiffname(string, 0, NULL);
1374 
1375  cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_NORMAL);
1376  och->ibufs_norm[f] = IMB_loadiffname(string, 0, NULL);
1377 }
1378 
1379 void BKE_ocean_bake(struct Ocean *o,
1380  struct OceanCache *och,
1381  void (*update_cb)(void *, float progress, int *cancel),
1382  void *update_cb_data)
1383 {
1384  /* note: some of these values remain uninitialized unless certain options
1385  * are enabled, take care that BKE_ocean_eval_ij() initializes a member
1386  * before use - campbell */
1387  OceanResult ocr;
1388 
1389  ImageFormatData imf = {0};
1390 
1391  int f, i = 0, x, y, cancel = 0;
1392  float progress;
1393 
1394  ImBuf *ibuf_foam, *ibuf_disp, *ibuf_normal, *ibuf_spray, *ibuf_spray_inverse;
1395  float *prev_foam;
1396  int res_x = och->resolution_x;
1397  int res_y = och->resolution_y;
1398  char string[FILE_MAX];
1399  // RNG *rng;
1400 
1401  if (!o) {
1402  return;
1403  }
1404 
1405  if (o->_do_jacobian) {
1406  prev_foam = MEM_callocN(res_x * res_y * sizeof(float), "previous frame foam bake data");
1407  }
1408  else {
1409  prev_foam = NULL;
1410  }
1411 
1412  // rng = BLI_rng_new(0);
1413 
1414  /* setup image format */
1416  imf.depth = R_IMF_CHAN_DEPTH_16;
1418 
1419  for (f = och->start, i = 0; f <= och->end; f++, i++) {
1420 
1421  /* create a new imbuf to store image for this frame */
1422  ibuf_foam = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
1423  ibuf_disp = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
1424  ibuf_normal = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
1425  ibuf_spray = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
1426  ibuf_spray_inverse = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
1427 
1428  BKE_ocean_simulate(o, och->time[i], och->wave_scale, och->chop_amount);
1429 
1430  /* add new foam */
1431  for (y = 0; y < res_y; y++) {
1432  for (x = 0; x < res_x; x++) {
1433 
1434  BKE_ocean_eval_ij(o, &ocr, x, y);
1435 
1436  /* add to the image */
1437  rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp);
1438 
1439  if (o->_do_jacobian) {
1440  /* TODO, cleanup unused code - campbell */
1441 
1442  float /*r, */ /* UNUSED */ pr = 0.0f, foam_result;
1443  float neg_disp, neg_eplus;
1444 
1446 
1447  /* accumulate previous value for this cell */
1448  if (i > 0) {
1449  pr = prev_foam[res_x * y + x];
1450  }
1451 
1452  /* r = BLI_rng_get_float(rng); */ /* UNUSED */ /* randomly reduce foam */
1453 
1454  /* pr = pr * och->foam_fade; */ /* overall fade */
1455 
1456  /* Remember ocean coord sys is Y up!
1457  * break up the foam where height (Y) is low (wave valley),
1458  * and X and Z displacement is greatest. */
1459 
1460  neg_disp = ocr.disp[1] < 0.0f ? 1.0f + ocr.disp[1] : 1.0f;
1461  neg_disp = neg_disp < 0.0f ? 0.0f : neg_disp;
1462 
1463  /* foam, 'ocr.Eplus' only initialized with do_jacobian */
1464  neg_eplus = ocr.Eplus[2] < 0.0f ? 1.0f + ocr.Eplus[2] : 1.0f;
1465  neg_eplus = neg_eplus < 0.0f ? 0.0f : neg_eplus;
1466 
1467  if (pr < 1.0f) {
1468  pr *= pr;
1469  }
1470 
1471  pr *= och->foam_fade * (0.75f + neg_eplus * 0.25f);
1472 
1473  /* A full clamping should not be needed! */
1474  foam_result = min_ff(pr + ocr.foam, 1.0f);
1475 
1476  prev_foam[res_x * y + x] = foam_result;
1477 
1478  /*foam_result = min_ff(foam_result, 1.0f); */
1479 
1480  value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
1481 
1482  /* spray map baking */
1483  if (o->_do_spray) {
1484  rgb_to_rgba_unit_alpha(&ibuf_spray->rect_float[4 * (res_x * y + x)], ocr.Eplus);
1485  rgb_to_rgba_unit_alpha(&ibuf_spray_inverse->rect_float[4 * (res_x * y + x)],
1486  ocr.Eminus);
1487  }
1488  }
1489 
1490  if (o->_do_normals) {
1491  rgb_to_rgba_unit_alpha(&ibuf_normal->rect_float[4 * (res_x * y + x)], ocr.normal);
1492  }
1493  }
1494  }
1495 
1496  /* write the images */
1497  cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_DISPLACE);
1498  if (0 == BKE_imbuf_write(ibuf_disp, string, &imf)) {
1499  printf("Cannot save Displacement File Output to %s\n", string);
1500  }
1501 
1502  if (o->_do_jacobian) {
1503  cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_FOAM);
1504  if (0 == BKE_imbuf_write(ibuf_foam, string, &imf)) {
1505  printf("Cannot save Foam File Output to %s\n", string);
1506  }
1507 
1508  if (o->_do_spray) {
1509  cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_SPRAY);
1510  if (0 == BKE_imbuf_write(ibuf_spray, string, &imf)) {
1511  printf("Cannot save Spray File Output to %s\n", string);
1512  }
1513 
1514  cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_SPRAY_INVERSE);
1515  if (0 == BKE_imbuf_write(ibuf_spray_inverse, string, &imf)) {
1516  printf("Cannot save Spray Inverse File Output to %s\n", string);
1517  }
1518  }
1519  }
1520 
1521  if (o->_do_normals) {
1522  cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_NORMAL);
1523  if (0 == BKE_imbuf_write(ibuf_normal, string, &imf)) {
1524  printf("Cannot save Normal File Output to %s\n", string);
1525  }
1526  }
1527 
1528  IMB_freeImBuf(ibuf_disp);
1529  IMB_freeImBuf(ibuf_foam);
1530  IMB_freeImBuf(ibuf_normal);
1531  IMB_freeImBuf(ibuf_spray);
1532  IMB_freeImBuf(ibuf_spray_inverse);
1533 
1534  progress = (f - och->start) / (float)och->duration;
1535 
1536  update_cb(update_cb_data, progress, &cancel);
1537 
1538  if (cancel) {
1539  if (prev_foam) {
1540  MEM_freeN(prev_foam);
1541  }
1542  // BLI_rng_free(rng);
1543  return;
1544  }
1545  }
1546 
1547  // BLI_rng_free(rng);
1548  if (prev_foam) {
1549  MEM_freeN(prev_foam);
1550  }
1551  och->baked = 1;
1552 }
1553 
1554 #else /* WITH_OCEANSIM */
1555 
1556 float BKE_ocean_jminus_to_foam(float UNUSED(jminus), float UNUSED(coverage))
1557 {
1558  return 0.0f;
1559 }
1560 
1561 void BKE_ocean_eval_uv(struct Ocean *UNUSED(oc),
1562  struct OceanResult *UNUSED(ocr),
1563  float UNUSED(u),
1564  float UNUSED(v))
1565 {
1566 }
1567 
1568 /* use catmullrom interpolation rather than linear */
1570  struct OceanResult *UNUSED(ocr),
1571  float UNUSED(u),
1572  float UNUSED(v))
1573 {
1574 }
1575 
1576 void BKE_ocean_eval_xz(struct Ocean *UNUSED(oc),
1577  struct OceanResult *UNUSED(ocr),
1578  float UNUSED(x),
1579  float UNUSED(z))
1580 {
1581 }
1582 
1584  struct OceanResult *UNUSED(ocr),
1585  float UNUSED(x),
1586  float UNUSED(z))
1587 {
1588 }
1589 
1590 void BKE_ocean_eval_ij(struct Ocean *UNUSED(oc),
1591  struct OceanResult *UNUSED(ocr),
1592  int UNUSED(i),
1593  int UNUSED(j))
1594 {
1595 }
1596 
1598  float UNUSED(t),
1599  float UNUSED(scale),
1600  float UNUSED(chop_amount))
1601 {
1602 }
1603 
1604 struct Ocean *BKE_ocean_add(void)
1605 {
1606  Ocean *oc = MEM_callocN(sizeof(Ocean), "ocean sim data");
1607 
1608  return oc;
1609 }
1610 
1611 void BKE_ocean_init(struct Ocean *UNUSED(o),
1612  int UNUSED(M),
1613  int UNUSED(N),
1614  float UNUSED(Lx),
1615  float UNUSED(Lz),
1616  float UNUSED(V),
1617  float UNUSED(l),
1618  float UNUSED(A),
1619  float UNUSED(w),
1620  float UNUSED(damp),
1621  float UNUSED(alignment),
1622  float UNUSED(depth),
1623  float UNUSED(time),
1624  int UNUSED(spectrum),
1625  float UNUSED(fetch_jonswap),
1626  float UNUSED(sharpen_peak_jonswap),
1627  short UNUSED(do_height_field),
1628  short UNUSED(do_chop),
1629  short UNUSED(do_spray),
1630  short UNUSED(do_normals),
1631  short UNUSED(do_jacobian),
1632  int UNUSED(seed))
1633 {
1634 }
1635 
1637 {
1638 }
1639 
1640 void BKE_ocean_free(struct Ocean *oc)
1641 {
1642  if (!oc) {
1643  return;
1644  }
1645  MEM_freeN(oc);
1646 }
1647 
1648 /* ********* Baking/Caching ********* */
1649 
1651 {
1652  if (!och) {
1653  return;
1654  }
1655 
1656  MEM_freeN(och);
1657 }
1658 
1660  struct OceanResult *UNUSED(ocr),
1661  int UNUSED(f),
1662  float UNUSED(u),
1663  float UNUSED(v))
1664 {
1665 }
1666 
1668  struct OceanResult *UNUSED(ocr),
1669  int UNUSED(f),
1670  int UNUSED(i),
1671  int UNUSED(j))
1672 {
1673 }
1674 
1675 OceanCache *BKE_ocean_init_cache(const char *UNUSED(bakepath),
1676  const char *UNUSED(relbase),
1677  int UNUSED(start),
1678  int UNUSED(end),
1679  float UNUSED(wave_scale),
1680  float UNUSED(chop_amount),
1681  float UNUSED(foam_coverage),
1682  float UNUSED(foam_fade),
1683  int UNUSED(resolution))
1684 {
1685  OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
1686 
1687  return och;
1688 }
1689 
1690 void BKE_ocean_simulate_cache(struct OceanCache *UNUSED(och), int UNUSED(frame))
1691 {
1692 }
1693 
1694 void BKE_ocean_bake(struct Ocean *UNUSED(o),
1695  struct OceanCache *UNUSED(och),
1696  void (*update_cb)(void *, float progress, int *cancel),
1697  void *UNUSED(update_cb_data))
1698 {
1699  /* unused */
1700  (void)update_cb;
1701 }
1702 
1704  struct OceanModifierData const *UNUSED(omd),
1705  int UNUSED(resolution))
1706 {
1707 }
1708 
1709 #endif /* WITH_OCEANSIM */
1710 
1712 {
1714  omd->oceancache = NULL;
1715  omd->cached = false;
1716 }
typedef float(TangentPoint)[2]
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, const struct ImageFormatData *imf)
void BKE_image_path_from_imtype(char *string, const char *base, const char *relbase, int frame, const char imtype, const bool use_ext, const bool use_frames, const char *suffix)
Definition: image.c:3091
float BLI_ocean_spectrum_texelmarsenarsloe(const struct Ocean *oc, const float kx, const float kz)
float BLI_ocean_spectrum_piersonmoskowitz(const struct Ocean *oc, const float kx, const float kz)
bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution)
float BLI_ocean_spectrum_jonswap(const struct Ocean *oc, const float kx, const float kz)
sqrt(x)+1/max(0
BLI_INLINE unsigned int BLI_hash_int_2d(unsigned int kx, unsigned int ky)
Definition: BLI_hash.h:67
MINLINE float min_ff(float a, float b)
#define M_PI
Definition: BLI_math_base.h:38
#define MINLINE
MINLINE float normalize_v3(float r[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define FILE_MAX
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1737
Random number functions.
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:76
void BLI_rng_seed(struct RNG *rng, unsigned int seed) ATTR_NONNULL(1)
Definition: rand.cc:81
struct RNG * BLI_rng_new(unsigned int seed)
Definition: rand.cc:54
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:120
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
void * BLI_task_pool_user_data(TaskPool *pool)
Definition: task_pool.cc:541
void BLI_task_pool_work_and_wait(TaskPool *pool)
Definition: task_pool.cc:496
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
TaskPool * BLI_task_pool_create(void *userdata, TaskPriority priority)
Definition: task_pool.cc:406
void BLI_task_pool_free(TaskPool *pool)
Definition: task_pool.cc:456
@ TASK_PRIORITY_HIGH
Definition: BLI_task.h:67
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
Definition: task_pool.cc:475
void BLI_rw_mutex_end(ThreadRWMutex *mutex)
Definition: threads.cc:531
void BLI_thread_unlock(int type)
Definition: threads.cc:389
void BLI_thread_lock(int type)
Definition: threads.cc:384
#define THREAD_LOCK_READ
Definition: BLI_threads.h:121
#define THREAD_LOCK_WRITE
Definition: BLI_threads.h:122
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
Definition: threads.cc:516
@ LOCK_FFTW
Definition: BLI_threads.h:74
void BLI_rw_mutex_init(ThreadRWMutex *mutex)
Definition: threads.cc:511
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
Definition: threads.cc:526
#define UNUSED(x)
typedef double(DMatrix)[4][4]
@ MOD_OCEAN_SPECTRUM_TEXEL_MARSEN_ARSLOE
@ MOD_OCEAN_SPECTRUM_JONSWAP
@ MOD_OCEAN_SPECTRUM_PIERSON_MOSKOWITZ
@ MOD_OCEAN_GENERATE_NORMALS
@ MOD_OCEAN_GENERATE_FOAM
@ MOD_OCEAN_GENERATE_SPRAY
#define R_IMF_EXR_CODEC_ZIP
@ R_IMF_CHAN_DEPTH_16
#define R_IMF_IMTYPE_OPENEXR
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint i1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:478
void IMB_freeImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:211
struct ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:224
Contains defines and structs used throughout the imbuf module.
@ IB_rectfloat
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static unsigned long seed
Definition: btSoftBody.h:39
SIMD_FORCE_INLINE btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:251
double time
#define logf(x)
#define sinf(x)
#define cosf(x)
#define expf(x)
#define powf(x, y)
#define fmodf(x, y)
#define tanhf(x)
#define fabsf(x)
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
#define M
static unsigned a[3]
Definition: RandGen.cpp:92
double real
Definition: Precision.h:26
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
void BKE_ocean_eval_xz(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x), float UNUSED(z))
Definition: ocean.c:1576
void BKE_ocean_cache_eval_ij(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f), int UNUSED(i), int UNUSED(j))
Definition: ocean.c:1667
void BKE_ocean_simulate(struct Ocean *UNUSED(o), float UNUSED(t), float UNUSED(scale), float UNUSED(chop_amount))
Definition: ocean.c:1597
void BKE_ocean_free_data(struct Ocean *UNUSED(oc))
Definition: ocean.c:1636
void BKE_ocean_free_modifier_cache(struct OceanModifierData *omd)
Definition: ocean.c:1711
void BKE_ocean_free_cache(struct OceanCache *och)
Definition: ocean.c:1650
OceanCache * BKE_ocean_init_cache(const char *UNUSED(bakepath), const char *UNUSED(relbase), int UNUSED(start), int UNUSED(end), float UNUSED(wave_scale), float UNUSED(chop_amount), float UNUSED(foam_coverage), float UNUSED(foam_fade), int UNUSED(resolution))
Definition: ocean.c:1675
void BKE_ocean_cache_eval_uv(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f), float UNUSED(u), float UNUSED(v))
Definition: ocean.c:1659
void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean), struct OceanModifierData const *UNUSED(omd), int UNUSED(resolution))
Definition: ocean.c:1703
struct Ocean * BKE_ocean_add(void)
Definition: ocean.c:1604
void BKE_ocean_eval_xz_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x), float UNUSED(z))
Definition: ocean.c:1583
void BKE_ocean_eval_uv(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u), float UNUSED(v))
Definition: ocean.c:1561
void BKE_ocean_eval_ij(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), int UNUSED(i), int UNUSED(j))
Definition: ocean.c:1590
void BKE_ocean_init(struct Ocean *UNUSED(o), int UNUSED(M), int UNUSED(N), float UNUSED(Lx), float UNUSED(Lz), float UNUSED(V), float UNUSED(l), float UNUSED(A), float UNUSED(w), float UNUSED(damp), float UNUSED(alignment), float UNUSED(depth), float UNUSED(time), int UNUSED(spectrum), float UNUSED(fetch_jonswap), float UNUSED(sharpen_peak_jonswap), short UNUSED(do_height_field), short UNUSED(do_chop), short UNUSED(do_spray), short UNUSED(do_normals), short UNUSED(do_jacobian), int UNUSED(seed))
Definition: ocean.c:1611
void BKE_ocean_free(struct Ocean *oc)
Definition: ocean.c:1640
void BKE_ocean_simulate_cache(struct OceanCache *UNUSED(och), int UNUSED(frame))
Definition: ocean.c:1690
float BKE_ocean_jminus_to_foam(float UNUSED(jminus), float UNUSED(coverage))
Definition: ocean.c:1556
void BKE_ocean_bake(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och), void(*update_cb)(void *, float progress, int *cancel), void *UNUSED(update_cb_data))
Definition: ocean.c:1694
void BKE_ocean_eval_uv_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u), float UNUSED(v))
Definition: ocean.c:1569
params N
static void update_cb(PBVHNode *node, void *rebuild)
Definition: sculpt_undo.c:120
#define min(a, b)
Definition: sort.c:51
float * rect_float
int resolution_x
Definition: BKE_ocean.h:67
int resolution_y
Definition: BKE_ocean.h:68
const char * bakepath
Definition: BKE_ocean.h:52
float * time
Definition: BKE_ocean.h:56
struct ImBuf ** ibufs_disp
Definition: BKE_ocean.h:44
int duration
Definition: BKE_ocean.h:66
int baked
Definition: BKE_ocean.h:70
float wave_scale
Definition: BKE_ocean.h:59
int start
Definition: BKE_ocean.h:64
float foam_fade
Definition: BKE_ocean.h:62
struct ImBuf ** ibufs_spray
Definition: BKE_ocean.h:48
struct ImBuf ** ibufs_norm
Definition: BKE_ocean.h:46
struct ImBuf ** ibufs_foam
Definition: BKE_ocean.h:45
const char * relbase
Definition: BKE_ocean.h:53
struct ImBuf ** ibufs_spray_inverse
Definition: BKE_ocean.h:50
float chop_amount
Definition: BKE_ocean.h:60
float foam_coverage
Definition: BKE_ocean.h:61
struct OceanCache * oceancache
float Eplus[3]
Definition: BKE_ocean.h:40
float Jplus
Definition: BKE_ocean.h:38
float Eminus[3]
Definition: BKE_ocean.h:39
float disp[3]
Definition: BKE_ocean.h:32
float Jminus
Definition: BKE_ocean.h:37
float normal[3]
Definition: BKE_ocean.h:33
float foam
Definition: BKE_ocean.h:34
Definition: rand.cc:48
void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4])
float max
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
ccl_device_inline float2 floor(const float2 &a)
ccl_device_inline float2 fabs(const float2 &a)
CCL_NAMESPACE_BEGIN struct View V