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:
authorSebastián Barschkis <sebbas@sebbas.org>2019-12-16 17:40:15 +0300
committerSebastián Barschkis <sebbas@sebbas.org>2019-12-16 18:27:26 +0300
commit4ff7c5eed6b546ae42692f3a869a5ccc095a9cb4 (patch)
tree03f8233788ae46e66672f711e3cf42d8d00d01cc /extern/mantaflow/preprocessed/noisefield.h
parent6a3f2b30d206df23120cd212132adea821b6c20e (diff)
Mantaflow [Part 1]: Added preprocessed Mantaflow source files
Includes preprocessed Mantaflow source files for both OpenMP and TBB (if OpenMP is not present, TBB files will be used instead). These files come directly from the Mantaflow repository. Future updates to the core fluid solver will take place by updating the files. Reviewed By: sergey, mont29 Maniphest Tasks: T59995 Differential Revision: https://developer.blender.org/D3850
Diffstat (limited to 'extern/mantaflow/preprocessed/noisefield.h')
-rw-r--r--extern/mantaflow/preprocessed/noisefield.h635
1 files changed, 635 insertions, 0 deletions
diff --git a/extern/mantaflow/preprocessed/noisefield.h b/extern/mantaflow/preprocessed/noisefield.h
new file mode 100644
index 00000000000..ddf47573dd9
--- /dev/null
+++ b/extern/mantaflow/preprocessed/noisefield.h
@@ -0,0 +1,635 @@
+
+
+// DO NOT EDIT !
+// This file is generated using the MantaFlow preprocessor (prep generate).
+
+/******************************************************************************
+ *
+ * MantaFlow fluid solver framework
+ * Copyright 2011 Tobias Pfaff, Nils Thuerey
+ *
+ * This program is free software, distributed under the terms of the
+ * Apache License, Version 2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Wavelet noise field
+ *
+ ******************************************************************************/
+
+#ifndef _NOISEFIELD_H_
+#define _NOISEFIELD_H_
+
+#include "vectorbase.h"
+#include "manta.h"
+#include "grid.h"
+#include <atomic>
+
+namespace Manta {
+
+#define NOISE_TILE_SIZE 128
+
+// wrapper for a parametrized field of wavelet noise
+
+class WaveletNoiseField : public PbClass {
+ public:
+ WaveletNoiseField(FluidSolver *parent, int fixedSeed = -1, int loadFromFile = false);
+ static int _W_0(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
+ {
+ PbClass *obj = Pb::objFromPy(_self);
+ if (obj)
+ delete obj;
+ try {
+ PbArgs _args(_linargs, _kwds);
+ bool noTiming = _args.getOpt<bool>("notiming", -1, 0);
+ pbPreparePlugin(0, "WaveletNoiseField::WaveletNoiseField", !noTiming);
+ {
+ ArgLocker _lock;
+ FluidSolver *parent = _args.getPtr<FluidSolver>("parent", 0, &_lock);
+ int fixedSeed = _args.getOpt<int>("fixedSeed", 1, -1, &_lock);
+ int loadFromFile = _args.getOpt<int>("loadFromFile", 2, false, &_lock);
+ obj = new WaveletNoiseField(parent, fixedSeed, loadFromFile);
+ obj->registerObject(_self, &_args);
+ _args.check();
+ }
+ pbFinalizePlugin(obj->getParent(), "WaveletNoiseField::WaveletNoiseField", !noTiming);
+ return 0;
+ }
+ catch (std::exception &e) {
+ pbSetError("WaveletNoiseField::WaveletNoiseField", e.what());
+ return -1;
+ }
+ }
+
+ ~WaveletNoiseField()
+ {
+ if (mNoiseTile && !mNoiseReferenceCount) {
+ delete mNoiseTile;
+ mNoiseTile = NULL;
+ }
+ };
+
+ //! evaluate noise
+ inline Real evaluate(Vec3 pos, int tile = 0) const;
+ //! evaluate noise as a vector
+ inline Vec3 evaluateVec(Vec3 pos, int tile = 0) const;
+ //! evaluate curl noise
+ inline Vec3 evaluateCurl(Vec3 pos) const;
+
+ //! direct data access
+ Real *data()
+ {
+ return mNoiseTile;
+ }
+
+ //! compute wavelet decomposition of an input grid (stores residual coefficients)
+ static void computeCoefficients(Grid<Real> &input, Grid<Real> &tempIn1, Grid<Real> &tempIn2);
+
+ // helper
+ std::string toString();
+
+ // texcoord position and scale
+ Vec3 mPosOffset;
+ static PyObject *_GET_mPosOffset(PyObject *self, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ return toPy(pbo->mPosOffset);
+ }
+ static int _SET_mPosOffset(PyObject *self, PyObject *val, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ pbo->mPosOffset = fromPy<Vec3>(val);
+ return 0;
+ }
+
+ Vec3 mPosScale;
+ static PyObject *_GET_mPosScale(PyObject *self, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ return toPy(pbo->mPosScale);
+ }
+ static int _SET_mPosScale(PyObject *self, PyObject *val, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ pbo->mPosScale = fromPy<Vec3>(val);
+ return 0;
+ }
+
+ // value offset & scale
+ Real mValOffset;
+ static PyObject *_GET_mValOffset(PyObject *self, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ return toPy(pbo->mValOffset);
+ }
+ static int _SET_mValOffset(PyObject *self, PyObject *val, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ pbo->mValOffset = fromPy<Real>(val);
+ return 0;
+ }
+
+ Real mValScale;
+ static PyObject *_GET_mValScale(PyObject *self, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ return toPy(pbo->mValScale);
+ }
+ static int _SET_mValScale(PyObject *self, PyObject *val, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ pbo->mValScale = fromPy<Real>(val);
+ return 0;
+ }
+
+ // clamp? (default 0-1)
+ bool mClamp;
+ static PyObject *_GET_mClamp(PyObject *self, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ return toPy(pbo->mClamp);
+ }
+ static int _SET_mClamp(PyObject *self, PyObject *val, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ pbo->mClamp = fromPy<bool>(val);
+ return 0;
+ }
+
+ Real mClampNeg;
+ static PyObject *_GET_mClampNeg(PyObject *self, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ return toPy(pbo->mClampNeg);
+ }
+ static int _SET_mClampNeg(PyObject *self, PyObject *val, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ pbo->mClampNeg = fromPy<Real>(val);
+ return 0;
+ }
+
+ Real mClampPos;
+ static PyObject *_GET_mClampPos(PyObject *self, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ return toPy(pbo->mClampPos);
+ }
+ static int _SET_mClampPos(PyObject *self, PyObject *val, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ pbo->mClampPos = fromPy<Real>(val);
+ return 0;
+ }
+
+ // animated over time
+ Real mTimeAnim;
+ static PyObject *_GET_mTimeAnim(PyObject *self, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ return toPy(pbo->mTimeAnim);
+ }
+ static int _SET_mTimeAnim(PyObject *self, PyObject *val, void *cl)
+ {
+ WaveletNoiseField *pbo = dynamic_cast<WaveletNoiseField *>(Pb::objFromPy(self));
+ pbo->mTimeAnim = fromPy<Real>(val);
+ return 0;
+ }
+
+ protected:
+ // noise evaluation functions
+ static inline Real WNoiseDx(const Vec3 &p, Real *data);
+ static inline Vec3 WNoiseVec(const Vec3 &p, Real *data);
+ static inline Real WNoise(const Vec3 &p, Real *data);
+
+ // helpers for tile generation , for periodic 128 grids only
+ static void downsample(Real *from, Real *to, int n, int stride);
+ static void upsample(Real *from, Real *to, int n, int stride);
+
+ // for grids with arbitrary sizes, and neumann boundary conditions
+ static void downsampleNeumann(const Real *from, Real *to, int n, int stride);
+ static void upsampleNeumann(const Real *from, Real *to, int n, int stride);
+
+ static inline int modSlow(int x, int n)
+ {
+ int m = x % n;
+ return (m < 0) ? m + n : m;
+ }
+// warning - noiseTileSize has to be 128^3!
+#define modFast128(x) ((x)&127)
+
+ inline Real getTime() const
+ {
+ return mParent->getTime() * mParent->getDx() * mTimeAnim;
+ }
+
+ // pre-compute tile data for wavelet noise
+ void generateTile(int loadFromFile);
+
+ // animation over time
+ // grid size normalization (inverse size)
+ Real mGsInvX, mGsInvY, mGsInvZ;
+ // random offset into tile to simulate different random seeds
+ Vec3 mSeedOffset;
+
+ static Real *mNoiseTile;
+ // global random seed storage
+ static int randomSeed;
+ // global reference count for noise tile
+ static std::atomic<int> mNoiseReferenceCount;
+ public:
+ PbArgs _args;
+}
+#define _C_WaveletNoiseField
+;
+
+// **************************************************************************
+// Implementation
+
+#define ADD_WEIGHTED(x, y, z) \
+ weight = 1.0f; \
+ xC = modFast128(midX + (x)); \
+ weight *= w[0][(x) + 1]; \
+ yC = modFast128(midY + (y)); \
+ weight *= w[1][(y) + 1]; \
+ zC = modFast128(midZ + (z)); \
+ weight *= w[2][(z) + 1]; \
+ result += weight * data[(zC * NOISE_TILE_SIZE + yC) * NOISE_TILE_SIZE + xC];
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// derivatives of 3D noise - unrolled for performance
+//////////////////////////////////////////////////////////////////////////////////////////
+inline Real WaveletNoiseField::WNoiseDx(const Vec3 &p, Real *data)
+{
+ Real w[3][3], t, result = 0;
+
+ // Evaluate quadratic B-spline basis functions
+ int midX = (int)ceil(p[0] - 0.5f);
+ t = midX - (p[0] - 0.5f);
+ w[0][0] = -t;
+ w[0][2] = (1.f - t);
+ w[0][1] = 2.0f * t - 1.0f;
+
+ int midY = (int)ceil(p[1] - 0.5f);
+ t = midY - (p[1] - 0.5f);
+ w[1][0] = t * t * 0.5f;
+ w[1][2] = (1.f - t) * (1.f - t) * 0.5f;
+ w[1][1] = 1.f - w[1][0] - w[1][2];
+
+ int midZ = (int)ceil(p[2] - 0.5f);
+ t = midZ - (p[2] - 0.5f);
+ w[2][0] = t * t * 0.5f;
+ w[2][2] = (1.f - t) * (1.f - t) * 0.5f;
+ w[2][1] = 1.f - w[2][0] - w[2][2];
+
+ // Evaluate noise by weighting noise coefficients by basis function values
+ int xC, yC, zC;
+ Real weight = 1;
+
+ ADD_WEIGHTED(-1, -1, -1);
+ ADD_WEIGHTED(0, -1, -1);
+ ADD_WEIGHTED(1, -1, -1);
+ ADD_WEIGHTED(-1, 0, -1);
+ ADD_WEIGHTED(0, 0, -1);
+ ADD_WEIGHTED(1, 0, -1);
+ ADD_WEIGHTED(-1, 1, -1);
+ ADD_WEIGHTED(0, 1, -1);
+ ADD_WEIGHTED(1, 1, -1);
+
+ ADD_WEIGHTED(-1, -1, 0);
+ ADD_WEIGHTED(0, -1, 0);
+ ADD_WEIGHTED(1, -1, 0);
+ ADD_WEIGHTED(-1, 0, 0);
+ ADD_WEIGHTED(0, 0, 0);
+ ADD_WEIGHTED(1, 0, 0);
+ ADD_WEIGHTED(-1, 1, 0);
+ ADD_WEIGHTED(0, 1, 0);
+ ADD_WEIGHTED(1, 1, 0);
+
+ ADD_WEIGHTED(-1, -1, 1);
+ ADD_WEIGHTED(0, -1, 1);
+ ADD_WEIGHTED(1, -1, 1);
+ ADD_WEIGHTED(-1, 0, 1);
+ ADD_WEIGHTED(0, 0, 1);
+ ADD_WEIGHTED(1, 0, 1);
+ ADD_WEIGHTED(-1, 1, 1);
+ ADD_WEIGHTED(0, 1, 1);
+ ADD_WEIGHTED(1, 1, 1);
+
+ return result;
+}
+
+inline Real WaveletNoiseField::WNoise(const Vec3 &p, Real *data)
+{
+ Real w[3][3], t, result = 0;
+
+ // Evaluate quadratic B-spline basis functions
+ int midX = (int)ceilf(p[0] - 0.5f);
+ t = midX - (p[0] - 0.5f);
+ w[0][0] = t * t * 0.5f;
+ w[0][2] = (1.f - t) * (1.f - t) * 0.5f;
+ w[0][1] = 1.f - w[0][0] - w[0][2];
+
+ int midY = (int)ceilf(p[1] - 0.5f);
+ t = midY - (p[1] - 0.5f);
+ w[1][0] = t * t * 0.5f;
+ w[1][2] = (1.f - t) * (1.f - t) * 0.5f;
+ w[1][1] = 1.f - w[1][0] - w[1][2];
+
+ int midZ = (int)ceilf(p[2] - 0.5f);
+ t = midZ - (p[2] - 0.5f);
+ w[2][0] = t * t * 0.5f;
+ w[2][2] = (1.f - t) * (1.f - t) * 0.5f;
+ w[2][1] = 1.f - w[2][0] - w[2][2];
+
+ // Evaluate noise by weighting noise coefficients by basis function values
+ int xC, yC, zC;
+ Real weight = 1;
+
+ ADD_WEIGHTED(-1, -1, -1);
+ ADD_WEIGHTED(0, -1, -1);
+ ADD_WEIGHTED(1, -1, -1);
+ ADD_WEIGHTED(-1, 0, -1);
+ ADD_WEIGHTED(0, 0, -1);
+ ADD_WEIGHTED(1, 0, -1);
+ ADD_WEIGHTED(-1, 1, -1);
+ ADD_WEIGHTED(0, 1, -1);
+ ADD_WEIGHTED(1, 1, -1);
+
+ ADD_WEIGHTED(-1, -1, 0);
+ ADD_WEIGHTED(0, -1, 0);
+ ADD_WEIGHTED(1, -1, 0);
+ ADD_WEIGHTED(-1, 0, 0);
+ ADD_WEIGHTED(0, 0, 0);
+ ADD_WEIGHTED(1, 0, 0);
+ ADD_WEIGHTED(-1, 1, 0);
+ ADD_WEIGHTED(0, 1, 0);
+ ADD_WEIGHTED(1, 1, 0);
+
+ ADD_WEIGHTED(-1, -1, 1);
+ ADD_WEIGHTED(0, -1, 1);
+ ADD_WEIGHTED(1, -1, 1);
+ ADD_WEIGHTED(-1, 0, 1);
+ ADD_WEIGHTED(0, 0, 1);
+ ADD_WEIGHTED(1, 0, 1);
+ ADD_WEIGHTED(-1, 1, 1);
+ ADD_WEIGHTED(0, 1, 1);
+ ADD_WEIGHTED(1, 1, 1);
+
+ return result;
+}
+
+#define ADD_WEIGHTEDX(x, y, z) \
+ weight = dw[0][(x) + 1] * w[1][(y) + 1] * w[2][(z) + 1]; \
+ result += weight * neighbors[x + 1][y + 1][z + 1];
+
+#define ADD_WEIGHTEDY(x, y, z) \
+ weight = w[0][(x) + 1] * dw[1][(y) + 1] * w[2][(z) + 1]; \
+ result += weight * neighbors[x + 1][y + 1][z + 1];
+
+#define ADD_WEIGHTEDZ(x, y, z) \
+ weight = w[0][(x) + 1] * w[1][(y) + 1] * dw[2][(z) + 1]; \
+ result += weight * neighbors[x + 1][y + 1][z + 1];
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// compute all derivatives in at once
+//////////////////////////////////////////////////////////////////////////////////////////
+inline Vec3 WaveletNoiseField::WNoiseVec(const Vec3 &p, Real *data)
+{
+ Vec3 final(0.);
+ Real w[3][3];
+ Real dw[3][3];
+ Real result = 0;
+ int xC, yC, zC;
+ Real weight;
+
+ int midX = (int)ceil(p[0] - 0.5f);
+ int midY = (int)ceil(p[1] - 0.5f);
+ int midZ = (int)ceil(p[2] - 0.5f);
+
+ Real t0 = midX - (p[0] - 0.5f);
+ Real t1 = midY - (p[1] - 0.5f);
+ Real t2 = midZ - (p[2] - 0.5f);
+
+ // precache all the neighbors for fast access
+ Real neighbors[3][3][3];
+ for (int z = -1; z <= 1; z++)
+ for (int y = -1; y <= 1; y++)
+ for (int x = -1; x <= 1; x++) {
+ xC = modFast128(midX + (x));
+ yC = modFast128(midY + (y));
+ zC = modFast128(midZ + (z));
+ neighbors[x + 1][y + 1][z + 1] =
+ data[zC * NOISE_TILE_SIZE * NOISE_TILE_SIZE + yC * NOISE_TILE_SIZE + xC];
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // evaluate splines
+ ///////////////////////////////////////////////////////////////////////////////////////
+ dw[0][0] = -t0;
+ dw[0][2] = (1.f - t0);
+ dw[0][1] = 2.0f * t0 - 1.0f;
+
+ dw[1][0] = -t1;
+ dw[1][2] = (1.0f - t1);
+ dw[1][1] = 2.0f * t1 - 1.0f;
+
+ dw[2][0] = -t2;
+ dw[2][2] = (1.0f - t2);
+ dw[2][1] = 2.0f * t2 - 1.0f;
+
+ w[0][0] = t0 * t0 * 0.5f;
+ w[0][2] = (1.f - t0) * (1.f - t0) * 0.5f;
+ w[0][1] = 1.f - w[0][0] - w[0][2];
+
+ w[1][0] = t1 * t1 * 0.5f;
+ w[1][2] = (1.f - t1) * (1.f - t1) * 0.5f;
+ w[1][1] = 1.f - w[1][0] - w[1][2];
+
+ w[2][0] = t2 * t2 * 0.5f;
+ w[2][2] = (1.f - t2) * (1.f - t2) * 0.5f;
+ w[2][1] = 1.f - w[2][0] - w[2][2];
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // x derivative
+ ///////////////////////////////////////////////////////////////////////////////////////
+ result = 0.0f;
+ ADD_WEIGHTEDX(-1, -1, -1);
+ ADD_WEIGHTEDX(0, -1, -1);
+ ADD_WEIGHTEDX(1, -1, -1);
+ ADD_WEIGHTEDX(-1, 0, -1);
+ ADD_WEIGHTEDX(0, 0, -1);
+ ADD_WEIGHTEDX(1, 0, -1);
+ ADD_WEIGHTEDX(-1, 1, -1);
+ ADD_WEIGHTEDX(0, 1, -1);
+ ADD_WEIGHTEDX(1, 1, -1);
+
+ ADD_WEIGHTEDX(-1, -1, 0);
+ ADD_WEIGHTEDX(0, -1, 0);
+ ADD_WEIGHTEDX(1, -1, 0);
+ ADD_WEIGHTEDX(-1, 0, 0);
+ ADD_WEIGHTEDX(0, 0, 0);
+ ADD_WEIGHTEDX(1, 0, 0);
+ ADD_WEIGHTEDX(-1, 1, 0);
+ ADD_WEIGHTEDX(0, 1, 0);
+ ADD_WEIGHTEDX(1, 1, 0);
+
+ ADD_WEIGHTEDX(-1, -1, 1);
+ ADD_WEIGHTEDX(0, -1, 1);
+ ADD_WEIGHTEDX(1, -1, 1);
+ ADD_WEIGHTEDX(-1, 0, 1);
+ ADD_WEIGHTEDX(0, 0, 1);
+ ADD_WEIGHTEDX(1, 0, 1);
+ ADD_WEIGHTEDX(-1, 1, 1);
+ ADD_WEIGHTEDX(0, 1, 1);
+ ADD_WEIGHTEDX(1, 1, 1);
+ final[0] = result;
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // y derivative
+ ///////////////////////////////////////////////////////////////////////////////////////
+ result = 0.0f;
+ ADD_WEIGHTEDY(-1, -1, -1);
+ ADD_WEIGHTEDY(0, -1, -1);
+ ADD_WEIGHTEDY(1, -1, -1);
+ ADD_WEIGHTEDY(-1, 0, -1);
+ ADD_WEIGHTEDY(0, 0, -1);
+ ADD_WEIGHTEDY(1, 0, -1);
+ ADD_WEIGHTEDY(-1, 1, -1);
+ ADD_WEIGHTEDY(0, 1, -1);
+ ADD_WEIGHTEDY(1, 1, -1);
+
+ ADD_WEIGHTEDY(-1, -1, 0);
+ ADD_WEIGHTEDY(0, -1, 0);
+ ADD_WEIGHTEDY(1, -1, 0);
+ ADD_WEIGHTEDY(-1, 0, 0);
+ ADD_WEIGHTEDY(0, 0, 0);
+ ADD_WEIGHTEDY(1, 0, 0);
+ ADD_WEIGHTEDY(-1, 1, 0);
+ ADD_WEIGHTEDY(0, 1, 0);
+ ADD_WEIGHTEDY(1, 1, 0);
+
+ ADD_WEIGHTEDY(-1, -1, 1);
+ ADD_WEIGHTEDY(0, -1, 1);
+ ADD_WEIGHTEDY(1, -1, 1);
+ ADD_WEIGHTEDY(-1, 0, 1);
+ ADD_WEIGHTEDY(0, 0, 1);
+ ADD_WEIGHTEDY(1, 0, 1);
+ ADD_WEIGHTEDY(-1, 1, 1);
+ ADD_WEIGHTEDY(0, 1, 1);
+ ADD_WEIGHTEDY(1, 1, 1);
+ final[1] = result;
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // z derivative
+ ///////////////////////////////////////////////////////////////////////////////////////
+ result = 0.0f;
+ ADD_WEIGHTEDZ(-1, -1, -1);
+ ADD_WEIGHTEDZ(0, -1, -1);
+ ADD_WEIGHTEDZ(1, -1, -1);
+ ADD_WEIGHTEDZ(-1, 0, -1);
+ ADD_WEIGHTEDZ(0, 0, -1);
+ ADD_WEIGHTEDZ(1, 0, -1);
+ ADD_WEIGHTEDZ(-1, 1, -1);
+ ADD_WEIGHTEDZ(0, 1, -1);
+ ADD_WEIGHTEDZ(1, 1, -1);
+
+ ADD_WEIGHTEDZ(-1, -1, 0);
+ ADD_WEIGHTEDZ(0, -1, 0);
+ ADD_WEIGHTEDZ(1, -1, 0);
+ ADD_WEIGHTEDZ(-1, 0, 0);
+ ADD_WEIGHTEDZ(0, 0, 0);
+ ADD_WEIGHTEDZ(1, 0, 0);
+ ADD_WEIGHTEDZ(-1, 1, 0);
+ ADD_WEIGHTEDZ(0, 1, 0);
+ ADD_WEIGHTEDZ(1, 1, 0);
+
+ ADD_WEIGHTEDZ(-1, -1, 1);
+ ADD_WEIGHTEDZ(0, -1, 1);
+ ADD_WEIGHTEDZ(1, -1, 1);
+ ADD_WEIGHTEDZ(-1, 0, 1);
+ ADD_WEIGHTEDZ(0, 0, 1);
+ ADD_WEIGHTEDZ(1, 0, 1);
+ ADD_WEIGHTEDZ(-1, 1, 1);
+ ADD_WEIGHTEDZ(0, 1, 1);
+ ADD_WEIGHTEDZ(1, 1, 1);
+ final[2] = result;
+
+ // debMsg("FINAL","at "<<p<<" = "<<final); // DEBUG
+ return final;
+}
+#undef ADD_WEIGHTEDX
+#undef ADD_WEIGHTEDY
+#undef ADD_WEIGHTEDZ
+
+inline Real WaveletNoiseField::evaluate(Vec3 pos, int tile) const
+{
+ pos[0] *= mGsInvX;
+ pos[1] *= mGsInvY;
+ pos[2] *= mGsInvZ;
+ pos += mSeedOffset;
+
+ // time anim
+ pos += Vec3(getTime());
+
+ pos[0] *= mPosScale[0];
+ pos[1] *= mPosScale[1];
+ pos[2] *= mPosScale[2];
+ pos += mPosOffset;
+
+ const int n3 = square(NOISE_TILE_SIZE) * NOISE_TILE_SIZE;
+ Real v = WNoise(pos, &mNoiseTile[tile * n3]);
+
+ v += mValOffset;
+ v *= mValScale;
+ if (mClamp) {
+ if (v < mClampNeg)
+ v = mClampNeg;
+ if (v > mClampPos)
+ v = mClampPos;
+ }
+ return v;
+}
+
+inline Vec3 WaveletNoiseField::evaluateVec(Vec3 pos, int tile) const
+{
+ pos[0] *= mGsInvX;
+ pos[1] *= mGsInvY;
+ pos[2] *= mGsInvZ;
+ pos += mSeedOffset;
+
+ // time anim
+ pos += Vec3(getTime());
+
+ pos[0] *= mPosScale[0];
+ pos[1] *= mPosScale[1];
+ pos[2] *= mPosScale[2];
+ pos += mPosOffset;
+
+ const int n3 = square(NOISE_TILE_SIZE) * NOISE_TILE_SIZE;
+ Vec3 v = WNoiseVec(pos, &mNoiseTile[tile * n3]);
+
+ v += Vec3(mValOffset);
+ v *= mValScale;
+
+ if (mClamp) {
+ for (int i = 0; i < 3; i++) {
+ if (v[i] < mClampNeg)
+ v[i] = mClampNeg;
+ if (v[i] > mClampPos)
+ v[i] = mClampPos;
+ }
+ }
+ return v;
+}
+
+inline Vec3 WaveletNoiseField::evaluateCurl(Vec3 pos) const
+{
+ // gradients of w0-w2
+ Vec3 d0 = evaluateVec(pos, 0), d1 = evaluateVec(pos, 1), d2 = evaluateVec(pos, 2);
+
+ return Vec3(d0.y - d1.z, d2.z - d0.x, d1.x - d2.y);
+}
+
+} // namespace Manta
+
+#endif