From 9008c368028296d34350f15e3707906441db513c Mon Sep 17 00:00:00 2001 From: Remi Beges Date: Thu, 31 May 2012 15:32:22 +0200 Subject: [PATCH] Added NzDynaTerrain (basis) + simplex3d 4d for nznoise --- build/scripts/module/dynaterrain.lua | 31 ++++ include/Nazara/DynaTerrain/Config.hpp | 38 +++++ include/Nazara/DynaTerrain/Debug.hpp | 11 ++ include/Nazara/DynaTerrain/DebugOff.hpp | 8 + include/Nazara/DynaTerrain/DynaTerrain.hpp | 27 ++++ include/Nazara/DynaTerrain/Node.hpp | 71 +++++++++ include/Nazara/DynaTerrain/Patch.hpp | 35 +++++ include/Nazara/DynaTerrain/QuadTree.hpp | 30 ++++ include/Nazara/Noise/Simplex3D.hpp | 45 ++++++ include/Nazara/Noise/Simplex3D.inl | 158 ++++++++++++++++++++ include/Nazara/Noise/Simplex4D.hpp | 47 ++++++ include/Nazara/Noise/Simplex4D.inl | 161 +++++++++++++++++++++ 12 files changed, 662 insertions(+) create mode 100644 build/scripts/module/dynaterrain.lua create mode 100644 include/Nazara/DynaTerrain/Config.hpp create mode 100644 include/Nazara/DynaTerrain/Debug.hpp create mode 100644 include/Nazara/DynaTerrain/DebugOff.hpp create mode 100644 include/Nazara/DynaTerrain/DynaTerrain.hpp create mode 100644 include/Nazara/DynaTerrain/Node.hpp create mode 100644 include/Nazara/DynaTerrain/Patch.hpp create mode 100644 include/Nazara/DynaTerrain/QuadTree.hpp create mode 100644 include/Nazara/Noise/Simplex3D.hpp create mode 100644 include/Nazara/Noise/Simplex3D.inl create mode 100644 include/Nazara/Noise/Simplex4D.hpp create mode 100644 include/Nazara/Noise/Simplex4D.inl diff --git a/build/scripts/module/dynaterrain.lua b/build/scripts/module/dynaterrain.lua new file mode 100644 index 000000000..31847eb8c --- /dev/null +++ b/build/scripts/module/dynaterrain.lua @@ -0,0 +1,31 @@ +project "NazaraModuleName" + +files +{ + "../include/Nazara/ModuleName/**.hpp", + "../include/Nazara/ModuleName/**.inl", + "../src/Nazara/ModuleName/**.hpp", + "../src/Nazara/ModuleName/**.cpp" +} + +if (os.is("windows")) then + excludes { "../src/Nazara/ModuleName/Posix/*.hpp", "../src/Nazara/ModuleName/Posix/*.cpp" } +else + excludes { "../src/Nazara/ModuleName/Win32/*.hpp", "../src/Nazara/ModuleName/Win32/*.cpp" } +end + +configuration "DebugStatic" + links "NazaraCored-s" + targetname "NazaraModuleNamed" + +configuration "ReleaseStatic" + links "NazaraCore-s" + targetname "NazaraModuleName" + +configuration "DebugDLL" + links "NazaraCored" + targetname "NazaraModuleNamed" + +configuration "ReleaseDLL" + links "NazaraCore" + targetname "NazaraModuleName" \ No newline at end of file diff --git a/include/Nazara/DynaTerrain/Config.hpp b/include/Nazara/DynaTerrain/Config.hpp new file mode 100644 index 000000000..9527720de --- /dev/null +++ b/include/Nazara/DynaTerrain/Config.hpp @@ -0,0 +1,38 @@ +/* + Nazara Engine + + Copyright (C) 2012 AUTHORS (EMAIL) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_CONFIG_MODULENAME_HPP +#define NAZARA_CONFIG_MODULENAME_HPP + +/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci + +// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution) +#define NAZARA_MODULENAME_MEMORYLEAKTRACKER 0 + +// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +#define NAZARA_MODULENAME_SAFE 1 + +#endif // NAZARA_CONFIG_MODULENAME_HPP diff --git a/include/Nazara/DynaTerrain/Debug.hpp b/include/Nazara/DynaTerrain/Debug.hpp new file mode 100644 index 000000000..fa2f9482e --- /dev/null +++ b/include/Nazara/DynaTerrain/Debug.hpp @@ -0,0 +1,11 @@ +// Copyright (C) 2012 AUTHORS +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#if NAZARA_MODULENAME_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG) + #include + + #define delete NzMemoryManager::NextFree(__FILE__, __LINE__), delete + #define new new(__FILE__, __LINE__) +#endif diff --git a/include/Nazara/DynaTerrain/DebugOff.hpp b/include/Nazara/DynaTerrain/DebugOff.hpp new file mode 100644 index 000000000..0a21b742d --- /dev/null +++ b/include/Nazara/DynaTerrain/DebugOff.hpp @@ -0,0 +1,8 @@ +// Copyright (C) 2012 AUTHORS +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#if NAZARA_MODULENAME_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG) + #undef delete + #undef new +#endif diff --git a/include/Nazara/DynaTerrain/DynaTerrain.hpp b/include/Nazara/DynaTerrain/DynaTerrain.hpp new file mode 100644 index 000000000..70d8f6918 --- /dev/null +++ b/include/Nazara/DynaTerrain/DynaTerrain.hpp @@ -0,0 +1,27 @@ +// Copyright (C) 2012 AUTHORS +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_MODULENAME_HPP +#define NAZARA_MODULENAME_HPP + +#include + +class NAZARA_API NzModuleName +{ + public: + NzModuleName(); + ~NzModuleName(); + + bool Initialize(); + void Uninitialize(); + + static bool IsInitialized(); + + private: + static bool s_initialized; +}; + +#endif // NAZARA_MODULENAME_HPP diff --git a/include/Nazara/DynaTerrain/Node.hpp b/include/Nazara/DynaTerrain/Node.hpp new file mode 100644 index 000000000..f7e6bd430 --- /dev/null +++ b/include/Nazara/DynaTerrain/Node.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2012 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NODE_H +#define NODE_H + +#include + +#include +#include "Patch.hpp" +class NzQuadTree; + + +//SUPPRIMER LES NODES FILS OU SEULEMENT LES PATCHS CONTENUS ? POUR L'INSTANT SUPPRESSION DES PATCHS + +class NzNode +{ + public: + enum nzDirection + { + TOP, + BOTTOM, + LEFT, + RIGHT, + TOPLEFT, + TOPRIGHT, + BOTTOMLEFT, + BOTTOMRIGHT, + CENTER + }; + + NzNode(NzQuadTree* quad, NzNode* parent, const NzVector2f& center, const NzVector2f& size, nzDirection dir = CENTER); + ~NzNode(); + + void Subdivide(); + void Refine(bool eraseMemory); + + void CreatePatch(const NzVector2f& center, const NzVector2f& size); + void DeletePatch(); + + unsigned short int GetLevel() const; + + bool IsLeaf() const; + bool IsRoot() const; + + //Retourne le voisin le plus proche dans la direction indiqué, de niveau de profondeur inférieur ou égal + bool LocateNeighbor(nzDirection dir, NzNode* neighbor); + + + private: + NzQuadTree* m_associatedQuadTree; + NzNode* m_parent; + NzNode* m_topLeftLeaf; + NzNode* m_topRightLeaf; + NzNode* m_bottomLeftLeaf; + NzNode* m_bottomRightLeaf; + bool m_isLeaf; + bool m_isRoot; + bool m_patchMemoryAllocated; + unsigned short int m_level; + + NzPatch* m_patch; + NzVector2f m_center; + NzVector2f m_size; + nzDirection m_direction; +}; + +#endif // NODE_H diff --git a/include/Nazara/DynaTerrain/Patch.hpp b/include/Nazara/DynaTerrain/Patch.hpp new file mode 100644 index 000000000..a546f2f41 --- /dev/null +++ b/include/Nazara/DynaTerrain/Patch.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2012 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef PATCH_H +#define PATCH_H + +#include + +#include + +class NzPatch +{ + public: + NzPatch(NzVector2f center, NzVector2f size); + ~NzPatch(); + + NzVector2f GetCenter() const; + NzVector2f GetSize() const; + + bool IntersectsCircle(const NzVector2f& center, double radius); + bool IsContainedByCircle(const NzVector2f& center, double radius); + + NzPatch* LocatePatch(const NzVector2f& position); + + protected: + private: + + NzVector2f m_center; + NzVector2f m_size; +}; + +#endif // PATCH_H diff --git a/include/Nazara/DynaTerrain/QuadTree.hpp b/include/Nazara/DynaTerrain/QuadTree.hpp new file mode 100644 index 000000000..8ed3f9dde --- /dev/null +++ b/include/Nazara/DynaTerrain/QuadTree.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2012 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef QUADTREE_H +#define QUADTREE_H + +#include + +#include +#include +#include "Node.hpp" + +class NzQuadTree +{ + public: + NzQuadTree(const NzVector2f& terrainCenter, const NzVector2f& terrainSize); + void RegisterLeaf(NzNode* node); + bool UnRegisterLeaf(NzNode* node); + NzNode* GetRootPtr(); + ~NzQuadTree(); + private: + NzNode* root; + //N'a pas la charge des objets en mémoire + std::list leaves; +}; + +#endif // QUADTREE_H diff --git a/include/Nazara/Noise/Simplex3D.hpp b/include/Nazara/Noise/Simplex3D.hpp new file mode 100644 index 000000000..dface2886 --- /dev/null +++ b/include/Nazara/Noise/Simplex3D.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2012 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef SIMPLEX3D_H +#define SIMPLEX3D_H + +#include +//#include +#include "NoiseBase.hpp" +#include + + +template class NzSimplex3D : public NzNoiseBase +{ + public: + NzSimplex3D(); + T GetValue(T x, T y, T z, T res); + ~NzSimplex3D() = default; + protected: + private: + int ii,jj,kk; + int gi0,gi1,gi2,gi3; + NzVector3i Origin,off1,off2; + T n1,n2,n3,n4; + T c1,c2,c3,c4; + T gradient3[16][3]; + T UnskewCoeff3D; + T SkewCoeff3D; + NzVector3 A, IsoOriginDist; + NzVector3 d1,d2,d3,d4; + + +}; + +typedef NzSimplex3D NzSimplex3Df; +typedef NzSimplex3D NzSimplex3Dd; + +//#include +#include "Simplex3D.inl" + +#endif // SIMPLEX3D_H + diff --git a/include/Nazara/Noise/Simplex3D.inl b/include/Nazara/Noise/Simplex3D.inl new file mode 100644 index 000000000..dea0881e2 --- /dev/null +++ b/include/Nazara/Noise/Simplex3D.inl @@ -0,0 +1,158 @@ +// Copyright (C) 2012 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +//#include +//#include +//#include + +template +NzSimplex3D::NzSimplex3D() +{ + SkewCoeff3D = 1/3; + UnskewCoeff3D = 1/6; + + int grad3Temp[][3] = { + {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, + {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, + {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, + {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} + }; + + for(int i(0) ; i < 16 ; ++i) + for(int j(0) ; j < 3 ; ++j) + gradient3[i][j] = grad3Temp[i][j]; +} + +template +T NzSimplex3D::GetValue(T x, T y, T z, T res) +{ + x /= res; + y /= res; + z /= res; + + Origin.x = fastfloor(x + (x + y + z) * SkewCoeff3D); + Origin.y = fastfloor(y + (x + y + z) * SkewCoeff3D); + Origin.z = fastfloor(z + (x + y + z) * SkewCoeff3D); + + A.x = Origin.x - (Origin.x + Origin.y + Origin.z) * UnskewCoeff3D; + A.y = Origin.y - (Origin.x + Origin.y + Origin.z) * UnskewCoeff3D; + A.z = Origin.z - (Origin.x + Origin.y + Origin.z) * UnskewCoeff3D; + + IsoOriginDist.x = x - A.x; + IsoOriginDist.y = y - A.y; + IsoOriginDist.z = z - A.z; + + if(IsoOriginDist.x >= IsoOriginDist.y) + { + if(IsoOriginDist.y >= IsoOriginDist.z) + { + off1.x = 1; + off1.y = 0; + off1.z = 0; + off2.x = 1; + off2.y = 1; + off2.z = 0; + } + else if(IsoOriginDist.x >= IsoOriginDist.z) + { + off1.x = 1; + off1.y = 0; + off1.z = 0; + off2.x = 1; + off2.y = 0; + off2.z = 1; + } + else + { + off1.x = 0; + off1.y = 0; + off1.z = 1; + off2.x = 1; + off2.y = 0; + off2.z = 1; + } + } + else + { + if(IsoOriginDist.y < IsoOriginDist.z) + { + off1.x = 0; + off1.y = 0; + off1.z = 1; + off2.x = 0; + off2.y = 1; + off2.z = 1; + } + else if(IsoOriginDist.x < IsoOriginDist.z) + { + off1.x = 0; + off1.y = 1; + off1.z = 0; + off2.x = 0; + off2.y = 1; + off2.z = 1; + } + else + { + off1.x = 0; + off1.y = 1; + off1.z = 0; + off2.x = 1; + off2.y = 1; + off2.z = 0; + } + } + + d1.x = A.x - x; + d1.y = A.y - y; + d1.z = A.z - z; + + d2.x = d1.x + off1.x - UnskewCoeff3D; + d2.y = d1.y + off1.y - UnskewCoeff3D; + d2.z = d1.z + off1.z - UnskewCoeff3D; + + d3.x = d1.x + off2.x - 2*UnskewCoeff3D; + d3.y = d1.y + off2.y - 2*UnskewCoeff3D; + d3.z = d1.z + off2.z - 2*UnskewCoeff3D; + + d4.x = d1.x + 1.0 - 3*UnskewCoeff3D; + d4.y = d1.y + 1.0 - 3*UnskewCoeff3D; + d4.z = d1.z + 1.0 - 3*UnskewCoeff3D; + + ii = Origin.x & 255; + jj = Origin.y & 255; + kk = Origin.z & 255; + + gi0 = perm[ii + perm[jj + perm[kk]]] % 12; + gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z]]] % 12; + gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z]]] % 12; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] % 12; + + n1 = gradient3[gi0][0] * d1.x + gradient3[gi0][1] * d1.y + gradient3[gi0][2] * d1.z; + n2 = gradient3[gi1][0] * d2.x + gradient3[gi1][1] * d2.y + gradient3[gi1][2] * d2.z; + n3 = gradient3[gi2][0] * d3.x + gradient3[gi2][1] * d3.y + gradient3[gi2][2] * d3.z; + n4 = gradient3[gi3][0] * d4.x + gradient3[gi3][1] * d4.y + gradient3[gi3][2] * d4.z; + + c1 = 0.6 - d1.x * d1.x - d1.y * d1.y - d1.z * d1.z; + c2 = 0.6 - d2.x * d2.x - d2.y * d2.y - d2.z * d2.z; + c3 = 0.6 - d3.x * d3.x - d3.y * d3.y - d3.z * d3.z; + c4 = 0.6 - d4.x * d4.x - d4.y * d4.y - d4.z * d4.z; + + if(c1 < 0) + c1 = 0; + if(c2 < 0) + c2 = 0; + if(c3 < 0) + c3 = 0; + if(c4 < 0) + c4 = 0; + + n1 = c1*c1*c1*n1; + n2 = c2*c2*c2*n2; + n3 = c3*c3*c3*n3; + n4 = c4*c4*c4*n4; + + return (n1+n2+n3+n4)*17.6995; +} + diff --git a/include/Nazara/Noise/Simplex4D.hpp b/include/Nazara/Noise/Simplex4D.hpp new file mode 100644 index 000000000..7c9982822 --- /dev/null +++ b/include/Nazara/Noise/Simplex4D.hpp @@ -0,0 +1,47 @@ +// Copyright (C) 2012 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef SIMPLEX4D_H +#define SIMPLEX4D_H + +#include +//#include +#include "NoiseBase.hpp" +#include + + +template class NzSimplex4D : public NzNoiseBase +{ + public: + NzSimplex4D(); + T GetValue(T x, T y, T z, T w, T res); + ~NzSimplex4D() = default; + protected: + private: + int ii,jj,kk,ll; + int gi0,gi1,gi2,gi3,gi4; + NzVector4i Origin,off1,off2,off3; + T n1,n2,n3,n4,n5; + T c1,c2,c3,c4,c5,c6; + T gradient4[32][4]; + int lookupTable4D[64][4]; + int c; + T UnskewCoeff4D; + T SkewCoeff4D; + NzVector4 A, IsoOriginDist; + NzVector4 d1,d2,d3,d4,d5; + + +}; + +typedef NzSimplex4D NzSimplex4Df; +typedef NzSimplex4D NzSimplex4Dd; + +//#include +#include "Simplex4D.inl" + +#endif // SIMPLEX4D_H + diff --git a/include/Nazara/Noise/Simplex4D.inl b/include/Nazara/Noise/Simplex4D.inl new file mode 100644 index 000000000..de840679d --- /dev/null +++ b/include/Nazara/Noise/Simplex4D.inl @@ -0,0 +1,161 @@ +// Copyright (C) 2012 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +//#include +//#include +//#include + +template +NzSimplex4D::NzSimplex4D() +{ + SkewCoeff4D = (sqrt(5) - 1)/4; + UnskewCoeff4D = (5 - sqrt(5))/20; + + int lookupTemp4D[][4] = + { + {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, + {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, + {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, + {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} + }; + + for(int i(0) ; i < 64 ; ++i) + for(int j(0) ; j < 4 ; ++j) + lookupTable4D[i][j] = lookupTemp4D[i][j]; + + int grad4Temp[][4] = + { + {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, + {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, + {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, + {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, + {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, + {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, + {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, + {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} + }; + + for(int i(0) ; i < 32 ; ++i) + for(int j(0) ; j < 4 ; ++j) + gradient4[i][j] = grad4Temp[i][j]; +} + +template +T NzSimplex4D::GetValue(T x, T y, T z, T w, T res) +{ + x /= res; + y /= res; + z /= res; + w /= res; + + Origin.x = fastfloor(x + (x + y + z + w) * SkewCoeff4D); + Origin.y = fastfloor(y + (x + y + z + w) * SkewCoeff4D); + Origin.z = fastfloor(z + (x + y + z + w) * SkewCoeff4D); + Origin.w = fastfloor(w + (x + y + z + w) * SkewCoeff4D); + + A.x = Origin.x - (Origin.x + Origin.y + Origin.z + Origin.w) * UnskewCoeff4D; + A.y = Origin.y - (Origin.x + Origin.y + Origin.z + Origin.w) * UnskewCoeff4D; + A.z = Origin.z - (Origin.x + Origin.y + Origin.z + Origin.w) * UnskewCoeff4D; + A.w = Origin.w - (Origin.x + Origin.y + Origin.z + Origin.w) * UnskewCoeff4D; + + IsoOriginDist.x = x - A.x; + IsoOriginDist.y = y - A.y; + IsoOriginDist.z = z - A.z; + IsoOriginDist.w = w - A.w; + + c1 = (IsoOriginDist.x > IsoOriginDist.y) ? 32 : 0; + c2 = (IsoOriginDist.x > IsoOriginDist.z) ? 16 : 0; + c3 = (IsoOriginDist.y > IsoOriginDist.z) ? 8 : 0; + c4 = (IsoOriginDist.x > IsoOriginDist.w) ? 4 : 0; + c5 = (IsoOriginDist.y > IsoOriginDist.w) ? 2 : 0; + c6 = (IsoOriginDist.z > IsoOriginDist.w) ? 1 : 0; + c = c1 + c2 + c3 + c4 + c5 + c6; + + off1.x = lookupTable4D[c][0] >= 3 ? 1 : 0; + off1.y = lookupTable4D[c][1] >= 3 ? 1 : 0; + off1.z = lookupTable4D[c][2] >= 3 ? 1 : 0; + off1.w = lookupTable4D[c][3] >= 3 ? 1 : 0; + + off2.x = lookupTable4D[c][0] >= 2 ? 1 : 0; + off2.y = lookupTable4D[c][1] >= 2 ? 1 : 0; + off2.z = lookupTable4D[c][2] >= 2 ? 1 : 0; + off2.w = lookupTable4D[c][3] >= 2 ? 1 : 0; + + off3.x = lookupTable4D[c][0] >= 1 ? 1 : 0; + off3.y = lookupTable4D[c][1] >= 1 ? 1 : 0; + off3.z = lookupTable4D[c][2] >= 1 ? 1 : 0; + off3.w = lookupTable4D[c][3] >= 1 ? 1 : 0; + + d1.x = A.x - x; + d1.y = A.y - y; + d1.z = A.z - z; + d1.w = A.w - w; + + d2.x = d1.x + off1.x - UnskewCoeff4D; + d2.y = d1.y + off1.y - UnskewCoeff4D; + d2.z = d1.z + off1.z - UnskewCoeff4D; + d2.w = d1.w + off1.w - UnskewCoeff4D; + + d3.x = d1.x + off2.x - 2*UnskewCoeff4D; + d3.y = d1.y + off2.y - 2*UnskewCoeff4D; + d3.z = d1.z + off2.z - 2*UnskewCoeff4D; + d3.w = d1.w + off2.w - 2*UnskewCoeff4D; + + d4.x = d1.x + off3.x - 3*UnskewCoeff4D; + d4.y = d1.y + off3.y - 3*UnskewCoeff4D; + d4.z = d1.z + off3.z - 3*UnskewCoeff4D; + d4.w = d1.w + off3.w - 3*UnskewCoeff4D; + + d5.x = d1.x + 1.0 - 4*UnskewCoeff4D; + d5.y = d1.y + 1.0 - 4*UnskewCoeff4D; + d5.z = d1.z + 1.0 - 4*UnskewCoeff4D; + d5.w = d1.w + 1.0 - 4*UnskewCoeff4D; + + ii = Origin.x & 255; + jj = Origin.y & 255; + kk = Origin.z & 255; + ll = Origin.w & 255; + + gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32; + gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z + perm[ll + off1.w]]]] % 32; + gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z + perm[ll + off2.w]]]] % 32; + gi3 = perm[ii + off3.x + perm[jj + off3.y + perm[kk + off3.z + perm[ll + off3.w]]]] % 32; + gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; + + n1 = gradient4[gi0][0]*d1.x + gradient4[gi0][1]*d1.y + gradient4[gi0][2]*d1.z + gradient4[gi0][3]*d1.w; + n2 = gradient4[gi1][0]*d2.x + gradient4[gi1][1]*d2.y + gradient4[gi1][2]*d2.z + gradient4[gi1][3]*d2.w; + n3 = gradient4[gi2][0]*d3.x + gradient4[gi2][1]*d3.y + gradient4[gi2][2]*d3.z + gradient4[gi2][3]*d3.w; + n4 = gradient4[gi3][0]*d4.x + gradient4[gi3][1]*d4.y + gradient4[gi3][2]*d4.z + gradient4[gi3][3]*d4.w; + n5 = gradient4[gi4][0]*d5.x + gradient4[gi4][1]*d5.y + gradient4[gi4][2]*d5.z + gradient4[gi4][3]*d5.w; + + c1 = 0.6 - d1.x*d1.x - d1.y*d1.y - d1.z*d1.z - d1.w*d1.w; + c2 = 0.6 - d2.x*d2.x - d2.y*d2.y - d2.z*d2.z - d2.w*d2.w; + c3 = 0.6 - d3.x*d3.x - d3.y*d3.y - d3.z*d3.z - d3.w*d3.w; + c4 = 0.6 - d4.x*d4.x - d4.y*d4.y - d4.z*d4.z - d4.w*d4.w; + c5 = 0.6 - d5.x*d5.x - d5.y*d5.y - d5.z*d5.z - d5.w*d5.w; + + if(c1 < 0) + c1 = 0; + if(c2 < 0) + c2 = 0; + if(c3 < 0) + c3 = 0; + if(c4 < 0) + c4 = 0; + if(c5 < 0) + c5 = 0; + + n1 = c1*c1*c1*n1; + n2 = c2*c2*c2*n2; + n3 = c3*c3*c3*n3; + n4 = c4*c4*c4*n4; + n5 = c5*c5*c5*n5; + + return (n1+n2+n3+n4+n5)*17.6995; +} +