////////////////////////////////////////////////////////////////////////////// // File: hypercloud.h // Created: 28.11.2001 in Delphi for I-Tex 2.2, converted to C++ 3.2.2002 // Author: Tobias Reichert // Email: tobias_reichert@i-tex.de // Summary: The class THyperCloudTexture is initialized // with the Init(...) method that sets random seed and // initializes the parameters and random value cache. // double GetValue4D(x,y,z,time) returns a depth value [0..1). // Animated this looks life boiling water ;-) // Computation Expense : O(Octaves*Density*2^Dimension), // nothing for realtime apps, but can be optimized a lot ////////////////////////////////////////////////////////////////////////////// #include "math.hpp" #include "math.h" class THyperCloudTexture { int RSeed; //Random Seed, use full range int Octaves; //Detail, Proportional to Computation Expense, use 6+ int Density; //Number of Puffs per Gridcell, use [1..20] double SubScale; //Resolution for Octave(n)=Subscale^n, use [1 .. 4] double Persistance; //Valence for Octave(n)= //Persistance^n/Sum(all Octave Valences) //use [0 .. 1) double ReciPuffSize; //1/Size of Cloud Puffs, use [0.5 .. 1) double Amplify; //Values can be very low, scale with this double Bias; //Make also Brighter with this Value double ReciOctaveSum; //is 1/Sum(all Octave Valances), Initialized by Init() double FNoiseArray[1024]; //RandomPool of Doubles int INoiseArray[1024]; //RandomPool of Integers private: double __fastcall DirectRandom(int i); public: void __fastcall Init(int pRSeed, int pOctaves, int pDensity, double pSubScale, double pPersistance, double pPuffSize, double pAmplify, double pBias); double __fastcall GetValue4D(double x, double y, double z, double t); }; double __fastcall THyperCloudTexture::DirectRandom(int i) { return abs(((i + i * ( 89603 + i *46703) ) * 114269) % 9995057 ) * (double)1.000494544453323e-7; } void __fastcall THyperCloudTexture::Init(int pRSeed, int pOctaves, int pDensity, double pSubScale, double pPersistance, double pPuffSize, double pAmplify, double pBias) //Example : THyperCloudTexture *Clouds; // Clouds=new(THyperCloudTexture); // Clouds->Init(123,6,20,2,0.6,0.8,4,0.1); { //Copy Parameters to Internal Variables RSeed = pRSeed; Octaves = pOctaves; Density = pDensity; SubScale = pSubScale; Persistance = pPersistance; //Puffs with Size=0 would not be very useful (and cause DbZ) if (pPuffSize>0) { ReciPuffSize = sqrt(1/pPuffSize); } else { ReciPuffSize = 10; } Amplify = pAmplify; Bias = pBias; //Compute 1/Sum(persistance^n,n=0..octaves-1); if (Octaves==0) {Octaves=1;} //Just for the case ... if (Persistance==1) { ReciOctaveSum = 1/Octaves; } else { ReciOctaveSum = (Persistance-1) / (IntPower(Persistance,Octaves) - 1) ; } //Init Cached Random Arrays for (int i=0; i<1024; i++) { FNoiseArray[i] = DirectRandom(i*101+RSeed); INoiseArray[i] = (int)(33111*DirectRandom(i*91+RSeed)); } } double __fastcall THyperCloudTexture::GetValue4D(double x, double y, double z, double t) { int i,d; //Some Working Variables int tx,ty,tz,tt; //Scan loop Variables int nd; //Octave "ANDing" Argument = 2^n-1 double c=0; //Return Value double b; double p=1; //Persistance int intx,inty,intz,intt; int offx,offy,offz,offt; double fracx,fracy,fracz,fract; double fx,fy,fz,ft; int inoff; double SqrDist; double PuffDens; double ReciSize; int cachex,cachey,cachez,cachet; int r; for (i=0;ib) { b=SqrDist; } } //End tx-loop } //End ty-loop } //End tz-loop } //End tt-loop //Change Random for each Element inoff += 101; } //End d-loop //Add Result of the Octave * Persistance c += sqrt(b)*p; //Higher Octaves are scaled with the SubScale Parameter x*=SubScale; y*=SubScale; z*=SubScale; t*=SubScale; //Compute Next Persistance p*=Persistance; } //Scale and Transform Result and Return Value return 1-exp(-c*Amplify * ReciOctaveSum - Bias); }