Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Stopford <philstopford>2020-03-12 05:35:22 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-03-12 07:48:20 +0300
commit6ce709dceb8db65ec6baae21100a7ce93829b1f6 (patch)
tree15ffc300239a2344ebd445d4316d55a51a3a350c /source/blender/blenkernel/intern/ocean_spectrum.c
parent1aebcdbb3a75b8c59ea211bb1ea6cc8573b0ea0f (diff)
Ocean: add new spectra modes to the ocean modifier
This extends the ocean modifier to add new spectra (Pierson-Moskowitz, Jonswap, TMA). These models are very different to the Phillips spectrum. They are intended for more established, large area, oceans and/or shallow water situations.
Diffstat (limited to 'source/blender/blenkernel/intern/ocean_spectrum.c')
-rw-r--r--source/blender/blenkernel/intern/ocean_spectrum.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/ocean_spectrum.c b/source/blender/blenkernel/intern/ocean_spectrum.c
new file mode 100644
index 00000000000..93018f4a5b0
--- /dev/null
+++ b/source/blender/blenkernel/intern/ocean_spectrum.c
@@ -0,0 +1,224 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BLI_math.h"
+#include "BKE_ocean.h"
+#include "ocean_intern.h"
+
+#ifdef WITH_OCEANSIM
+
+/* -------------------------------------------------------------------- */
+/** \name Ocean Spectrum from EncinoWaves
+ * \{ */
+
+/*
+ * Original code from EncinoWaves project Copyright (c) 2015 Christopher Jon Horvath
+ * Modifications made to work within blender.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+/**
+ * alpha_beta_spectrum is a common algorithm for the Pierson-Moskowitz, JONSWAP and TMA models.
+ * This is a modified implementation from the EncinoWaves project.
+ */
+static float alpha_beta_spectrum(const float alpha,
+ const float beta,
+ const float gamma,
+ const float omega,
+ const float peakomega)
+{
+ return (alpha * sqrt(gamma) / pow(omega, 5.0)) * exp(-beta * pow(peakomega / omega, 4.0));
+}
+
+static float peak_sharpen(const float omega, const float m_peakomega, const float m_gamma)
+{
+ const float peak_sharpening_sigma = (omega < m_peakomega) ? 0.07 : 0.09;
+ const float peak_sharpening = pow(
+ m_gamma, exp(-sqrt((omega - m_peakomega) / (peak_sharpening_sigma * m_peakomega)) / 2.0));
+
+ return peak_sharpening;
+}
+
+/**
+ * Spectrum-type independent modifications.
+ */
+static float ocean_spectrum_wind_and_damp(const Ocean *oc,
+ const float kx,
+ const float kz,
+ const float val)
+{
+ const float k2 = kx * kx + kz * kz;
+ const float k_mag_inv = 1.0f / k2;
+ const float k_dot_w = (kx * k_mag_inv * oc->_wx) + (kz * k_mag_inv * oc->_wz);
+
+ /* Bias towards wind dir. */
+ float newval = val * pow(fabs(k_dot_w), oc->_wind_alignment);
+
+ /* Eliminate wavelengths smaller than cutoff. */
+ /* val *= exp(-k2 * m_cutoff); */
+
+ /* Reduce reflected waves. */
+ if (k_dot_w < 0.0f) {
+ if (oc->_wind_alignment > 0.0) {
+ newval *= oc->_damp_reflections;
+ }
+ }
+
+ return newval;
+}
+
+static float jonswap(const Ocean *oc, const float k2)
+{
+ /* Get our basic JONSWAP value from #alpha_beta_spectrum. */
+ const float k_mag = sqrt(k2);
+
+ const float m_omega = GRAVITY * k_mag * tanh(k_mag * oc->_depth);
+ const float omega = sqrt(m_omega);
+
+ const float m_fetch = oc->_fetch_jonswap;
+
+ /* Strictly, this should be a random value from a Gaussian (mean 3.3, variance 0.67),
+ * clamped 1.0 to 6.0. */
+ float m_gamma = oc->_sharpen_peak_jonswap;
+ if (m_gamma < 1.0) {
+ m_gamma = 1.00;
+ }
+ if (m_gamma > 6.0) {
+ m_gamma = 6.0;
+ }
+
+ const float m_windspeed = oc->_V;
+
+ const float m_dimensionlessFetch = fabs(GRAVITY * m_fetch / sqrt(m_windspeed));
+ const float m_alpha = 0.076 * pow(m_dimensionlessFetch, -0.22);
+
+ const float m_tau = M_PI * 2;
+ const float m_peakomega = m_tau * 3.5 * fabs(GRAVITY / oc->_V) *
+ pow(m_dimensionlessFetch, -0.33);
+
+ const float beta = 1.25f;
+
+ float val = alpha_beta_spectrum(m_alpha, beta, GRAVITY, omega, m_peakomega);
+
+ /* Peak sharpening */
+ val *= peak_sharpen(m_omega, m_peakomega, m_gamma);
+
+ return val;
+}
+
+/**
+ * Pierson-Moskowitz model, 1964, assumes waves reach equilibrium with wind.
+ * Model is intended for large area 'fully developed' sea, where winds have been steadily blowing
+ * for days over an area that includes hundreds of wavelengths on a side.
+ */
+float BLI_ocean_spectrum_piersonmoskowitz(const Ocean *oc, const float kx, const float kz)
+{
+ const float k2 = kx * kx + kz * kz;
+
+ if (k2 == 0.0f) {
+ /* No DC component. */
+ return 0.0f;
+ }
+
+ /* Get Pierson-Moskowitz value from #alpha_beta_spectrum. */
+ const float peak_omega_PM = 0.87f * GRAVITY / oc->_V;
+
+ const float k_mag = sqrt(k2);
+ const float m_omega = GRAVITY * k_mag * tanh(k_mag * oc->_depth);
+
+ const float omega = sqrt(m_omega);
+ const float alpha = 0.0081f;
+ const float beta = 1.291f;
+
+ float val = alpha_beta_spectrum(alpha, beta, GRAVITY, omega, peak_omega_PM);
+
+ val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
+
+ return val;
+}
+
+/**
+ * TMA extends the JONSWAP spectrum.
+ * This spectral model is best suited to shallow water.
+ */
+float BLI_ocean_spectrum_texelmarsenarsloe(const Ocean *oc, const float kx, const float kz)
+{
+ const float k2 = kx * kx + kz * kz;
+
+ if (k2 == 0.0f) {
+ /* No DC component. */
+ return 0.0f;
+ }
+
+ float val = jonswap(oc, k2);
+
+ val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
+
+ /* TMA modifications to JONSWAP. */
+ const float m_depth = oc->_depth;
+ const float gain = sqrt(m_depth / GRAVITY);
+
+ const float k_mag = sqrt(k2);
+
+ const float m_omega = GRAVITY * k_mag * tanh(k_mag * oc->_depth);
+ const float omega = sqrt(m_omega);
+
+ const float kitaigorodskiiDepth_wh = omega * gain;
+ const float kitaigorodskiiDepth = 0.5 + (0.5 * tanh(1.8 * (kitaigorodskiiDepth_wh - 1.125)));
+
+ val *= kitaigorodskiiDepth;
+
+ val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
+
+ return val;
+}
+
+/**
+ * Hasselmann et al, 1973. This model extends the Pierson-Moskowitz model with a peak sharpening
+ * function This enhancement is an artificial construct to address the problem that the wave
+ * spectrum is never fully developed.
+ *
+ * The fetch parameter represents the distance from a lee shore,
+ * called the fetch, or the distance over which the wind blows with constant velocity.
+ */
+float BLI_ocean_spectrum_jonswap(const Ocean *oc, const float kx, const float kz)
+{
+ const float k2 = kx * kx + kz * kz;
+
+ if (k2 == 0.0f) {
+ /* No DC component. */
+ return 0.0f;
+ }
+
+ float val = jonswap(oc, k2);
+
+ val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
+
+ return val;
+}
+
+/** \} */
+
+#endif /* WITH_OCEANSIM */