RigsofRods
Soft-body Physics Simulation
FFT.cpp
Go to the documentation of this file.
1 /*
2 --------------------------------------------------------------------------------
3 This currentWaves file is part of Hydrax.
4 Visit ---
5 
6 Copyright (C) 2008 Xavier Verguín González <xavierverguin@hotmail.com>
7  <xavyiy@gmail.com>
8 
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU Lesser General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
12 version.
13 
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License along with
19 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21 http://www.gnu.org/copyleft/lesser.txt.
22 --------------------------------------------------------------------------------
23 */
24 
25 #include "FFT.h"
26 #include "OgrePixelFormat.h"
27 
28 #include <Hydrax.h>
29 
30 namespace Hydrax{namespace Noise
31 {
32  inline float uniform_deviate()
33  {
34  return rand() * ( 1.0f / ( RAND_MAX + 1.0f ) );
35  }
36 
38  : Noise("FFT", true)
39  , resolution(128)
40  , re(0)
41  , img(0)
42  , maximalValue(2)
43  , initialWaves(0)
44  , currentWaves(0)
45  , angularFrequencies(0)
46  , time(10)
47  , mGPUNormalMapManager(0)
48  {
49  }
50 
52  : Noise("FFT", true)
53  , mOptions(Options)
54  , resolution(128)
55  , re(0)
56  , img(0)
57  , maximalValue(2)
58  , initialWaves(0)
59  , currentWaves(0)
60  , angularFrequencies(0)
61  , time(10)
62  , mGPUNormalMapManager(0)
63  {
64  }
65 
67  {
68  remove();
69 
70  HydraxLOG(getName() + " destroyed.");
71  }
72 
73  void FFT::create()
74  {
75  if (isCreated())
76  {
77  return;
78  }
79 
80  _initNoise();
81 
82  Noise::create();
83  }
84 
85  void FFT::remove()
86  {
88  {
90  }
91 
92  if (!isCreated())
93  {
94  return;
95  }
96 
97  if (currentWaves)
98  {
99  delete [] currentWaves;
100  }
101  if (re)
102  {
103  delete [] re;
104  }
105  if (img)
106  {
107  delete [] img;
108  }
109  if (initialWaves)
110  {
111  delete [] initialWaves;
112  }
113 
114  if (angularFrequencies)
115  {
116  delete [] angularFrequencies;
117  }
118 
119  maximalValue = 2;
120  time = 10;
121 
122  Noise::remove();
123  }
124 
126  {
127  if (isCreated())
128  {
134  {
135  remove();
136 
137  mOptions = Options;
139 
140  create();
141 
143  {
145  }
146 
147  return;
148  }
149  else
150  {
152  {
154  getTechnique(0)->getPass(0)->
155  getVertexProgramParameters()->
156  setNamedConstant("uScale", Options.Scale);
157 
159  getTechnique(0)->getPass(0)->
160  getFragmentProgramParameters()->
161  setNamedConstant("uStrength", Options.GPU_Strength);
162 
164  getTechnique(0)->getPass(0)->
165  getFragmentProgramParameters()->
166  setNamedConstant("uLODParameters", Options.GPU_LODParameters);
167  }
168  }
169  }
170 
171  mOptions = Options;
173  }
174 
176  {
178  {
179  return false;
180  }
181 
183 
184  // Create our FFT texture
185  Ogre::TexturePtr mFFTTexture
186  = Ogre::TextureManager::getSingleton().
187  createManual("_Hydrax_FFT_Noise",
188  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
189  Ogre::TEX_TYPE_2D,
191  Ogre::PF_L16,
192  Ogre::TU_DYNAMIC_WRITE_ONLY);
193 
194  mGPUNormalMapManager->addTexture(mFFTTexture);
195 
196  // Create our normal map generator material
197 
198  MaterialManager *mMaterialManager = g->getHydrax()->getMaterialManager();
199 
200  Ogre::String VertexProgramData, FragmentProgramData;
201  Ogre::GpuProgramParametersSharedPtr VP_Parameters, FP_Parameters;
202  Ogre::String EntryPoints[2] = {"main_vp", "main_fp"};
203  Ogre::String GpuProgramsData[2]; Ogre::String GpuProgramNames[2];
204 
205  // Vertex program
206 
207  switch (g->getHydrax()->getShaderMode())
208  {
210  {
211  VertexProgramData +=
212  Ogre::String(
213  "void main_vp(\n") +
214  // IN
215  "float4 iPosition : POSITION,\n" +
216  // OUT
217  "out float4 oPosition : POSITION,\n" +
218  "out float3 oPosition_ : TEXCOORD0,\n" +
219  "out float4 oWorldUV : TEXCOORD1,\n" +
220  "out float oScale : TEXCOORD2,\n" +
221  "out float3 oCameraPos : TEXCOORD3,\n" +
222  "out float3 oCameraToPixel : TEXCOORD4,\n" +
223  // UNIFORM
224  "uniform float4x4 uWorldViewProj,\n" +
225  "uniform float4x4 uWorld, \n" +
226  "uniform float3 uCameraPos,\n"+
227  "uniform float uScale)\n" +
228  "{\n" +
229  "oPosition = mul(uWorldViewProj, iPosition);\n" +
230  "oPosition_ = iPosition.xyz;\n" +
231  "float2 Scale = uScale*mul(uWorld, iPosition).xz*0.0078125;\n" +
232  "oWorldUV.xy = Scale;\n" +
233  "oWorldUV.zw = Scale*16;\n" +
234  "oScale = uScale;\n" +
235  "oCameraPos = uCameraPos,\n" +
236  "oCameraToPixel = iPosition - uCameraPos;\n"+
237  "}\n";
238  }
239  break;
240 
242  {}
243  break;
244  }
245 
246  // Fragment program
247 
248  switch (g->getHydrax()->getShaderMode())
249  {
251  {
252  FragmentProgramData +=
253  Ogre::String(
254  "void main_fp(\n") +
255  // IN
256  "float3 iPosition : TEXCOORD0,\n" +
257  "float4 iWorldCoord : TEXCOORD1,\n" +
258  "float iScale : TEXCOORD2,\n" +
259  "float3 iCameraPos : TEXCOORD3,\n" +
260  "float3 iCameraToPixel : TEXCOORD4,\n" +
261  // OUT
262  "out float4 oColor : COLOR,\n" +
263  // UNIFORM
264  "uniform float uStrength,\n" +
265  "uniform float3 uLODParameters,\n" + // x: Initial derivation, y: Final derivation, z: Step
266  "uniform float3 uCameraPos,\n" +
267  "uniform sampler2D uFFT : register(s0))\n" +
268  "{\n" +
269  "float Distance = length(iCameraToPixel);\n" +
270  "float Attenuation = saturate(Distance/uLODParameters.z);\n" +
271 
272  "uLODParameters.x += (uLODParameters.y-uLODParameters.x)*Attenuation;\n"+
273  "uLODParameters.x *= iScale;\n" +
274 
275  "float AngleAttenuation = 1/abs(normalize(iCameraToPixel).y);\n"+
276  "uLODParameters.x *= AngleAttenuation;\n"+
277 
278  "float2 dx = float2(uLODParameters.x*0.0078125, 0);\n" +
279  "float2 dy = float2(0, dx.x);\n" +
280 
281  "float3 p_dx, m_dx, p_dy, m_dy;\n" +
282 
283  "p_dx = float3(\n" +
284  // x+
285  "iPosition.x+uLODParameters.x,\n" +
286  // y+
287  "tex2D(uFFT, iWorldCoord.xy+dx).x,\n" +
288  // z
289  "iPosition.z);\n" +
290 
291  "m_dx = float3(\n" +
292  // x-
293  "iPosition.x-uLODParameters.x,\n" +
294  // y-
295  "tex2D(uFFT, iWorldCoord.xy-dx).x, \n" +
296  // z
297  "iPosition.z);\n" +
298 
299  "p_dy = float3(\n" +
300  // x
301  "iPosition.x,\n" +
302  // y+
303  "tex2D(uFFT, iWorldCoord.xy+dy).x,\n" +
304  // z+
305  "iPosition.z+uLODParameters.x);\n" +
306 
307  "m_dy = float3(\n" +
308  // x
309  "iPosition.x,\n" +
310  // y-
311  "tex2D(uFFT, iWorldCoord.xy-dy).x,\n" +
312  // z-
313  "iPosition.z-uLODParameters.x);\n" +
314 
315  "uStrength *= (1-Attenuation);\n" +
316  "p_dx.y *= uStrength; m_dx.y *= uStrength;\n" +
317  "p_dy.y *= uStrength; m_dy.y *= uStrength;\n" +
318 
319  "float3 normal = normalize(cross(p_dx-m_dx, p_dy-m_dy));\n" +
320 
321  "oColor = float4(saturate(1-(0.5+0.5*normal)),1);\n" +
322  "}\n";
323 
324  }
325  break;
326 
328  {}
329  break;
330  }
331 
332  // Build our material
333 
334  Ogre::MaterialPtr &mNormalMapMaterial = mGPUNormalMapManager->getNormalMapMaterial();
335  mNormalMapMaterial = Ogre::MaterialManager::getSingleton().create("_Hydrax_GPU_Normal_Map_Material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
336 
337  Ogre::Pass *Technique0_Pass0 = mNormalMapMaterial->getTechnique(0)->getPass(0);
338 
339  Technique0_Pass0->setLightingEnabled(false);
340  Technique0_Pass0->setCullingMode(Ogre::CULL_NONE);
341  Technique0_Pass0->setDepthWriteEnabled(true);
342  Technique0_Pass0->setDepthCheckEnabled(true);
343 
344  GpuProgramsData[0] = VertexProgramData; GpuProgramsData[1] = FragmentProgramData;
345  GpuProgramNames[0] = "_Hydrax_GPU_Normal_Map_VP"; GpuProgramNames[1] = "_Hydrax_GPU_Normal_Map_FP";
346 
347  mMaterialManager->fillGpuProgramsToPass(Technique0_Pass0, GpuProgramNames, g->getHydrax()->getShaderMode(), EntryPoints, GpuProgramsData);
348 
349  VP_Parameters = Technique0_Pass0->getVertexProgramParameters();
350 
351  VP_Parameters->setNamedAutoConstant("uWorldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
352  VP_Parameters->setNamedAutoConstant("uWorld", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
353  VP_Parameters->setNamedAutoConstant("uCameraPos", Ogre::GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
354  VP_Parameters->setNamedConstant("uScale", mOptions.Scale);
355 
356  FP_Parameters = Technique0_Pass0->getFragmentProgramParameters();
357 
358  FP_Parameters->setNamedConstant("uStrength", mOptions.GPU_Strength);
359  FP_Parameters->setNamedConstant("uLODParameters", mOptions.GPU_LODParameters);
360 
361  Technique0_Pass0->createTextureUnitState(mGPUNormalMapManager->getTexture(0)->getName(), 0)
362  ->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
363 
364  mNormalMapMaterial->load();
365 
367 
368  return true;
369  }
370 
372  {
373  Ogre::uchar *Data;
374  Ogre::HardwarePixelBufferSharedPtr PixelBuffer
375  = mGPUNormalMapManager->getTexture(0)->getBuffer();
376 
377  PixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
378 
379  const Ogre::PixelBox& PixelBox = PixelBuffer->getCurrentLock();
380 
381  Data = PixelBox.data;
382 
383  for (int u = 0; u < resolution*resolution; u++)
384  {
385  Data[u] = (re[u]*65535);
386  }
387 
388  PixelBuffer->unlock();
389  }
390 
391  void FFT::saveCfg(Ogre::String &Data)
392  {
393  Noise::saveCfg(Data);
394 
395  Data += CfgFileManager::_getCfgString("FFT_Resolution", mOptions.Resolution);
396  Data += CfgFileManager::_getCfgString("FFT_PhysycalResolution", mOptions.PhysicalResolution);
397  Data += CfgFileManager::_getCfgString("FFT_Scale", mOptions.Scale);
398  Data += CfgFileManager::_getCfgString("FFT_WindDirection", mOptions.WindDirection);
399  Data += CfgFileManager::_getCfgString("FFT_AnimationSpeed", mOptions.AnimationSpeed);
400  Data += CfgFileManager::_getCfgString("FFT_KwPower", mOptions.KwPower);
401  Data += CfgFileManager::_getCfgString("FFT_Amplitude", mOptions.Amplitude); Data += "\n";
402  }
403 
404  bool FFT::loadCfg(Ogre::ConfigFile &CfgFile)
405  {
406  if (!Noise::loadCfg(CfgFile))
407  {
408  return false;
409  }
410 
411  setOptions(
412  Options(CfgFileManager::_getIntValue(CfgFile,"FFT_Resolution"),
413  CfgFileManager::_getFloatValue(CfgFile,"FFT_PhysycalResolution"),
414  CfgFileManager::_getFloatValue(CfgFile,"FFT_Scale"),
415  CfgFileManager::_getVector2Value(CfgFile,"FFT_WindDirection"),
416  CfgFileManager::_getFloatValue(CfgFile,"FFT_AnimationSpeed"),
417  CfgFileManager::_getFloatValue(CfgFile,"FFT_KwPower"),
418  CfgFileManager::_getFloatValue(CfgFile,"FFT_Amplitude")));
419 
420  return true;
421  }
422 
423  void FFT::update(const Ogre::Real &timeSinceLastFrame)
424  {
425  _calculeNoise(timeSinceLastFrame);
426 
428  {
430  }
431  }
432 
434  {
435  initialWaves = new std::complex<float>[resolution*resolution];
436  currentWaves = new std::complex<float>[resolution*resolution];
438 
439  re = new float[resolution*resolution];
440  img = new float[resolution*resolution];
441 
442  Ogre::Vector2 wave = Ogre::Vector2(0,0);
443 
444  std::complex<float>* pInitialWavesData = initialWaves;
445  float* pAngularFrequenciesData = angularFrequencies;
446 
447  float u, v,
448  temp;
449 
450  for (u = 0; u < resolution; u++)
451  {
452  wave.x = (-0.5f * resolution + u) * (2.0f* Ogre::Math::PI / mOptions.PhysicalResolution);
453 
454  for (v = 0; v < resolution; v++)
455  {
456  wave.y = (-0.5f * resolution + v) * (2.0f* Ogre::Math::PI / mOptions.PhysicalResolution);
457 
458  temp = Ogre::Math::Sqrt(0.5f * _getPhillipsSpectrum(wave, mOptions.WindDirection, mOptions.KwPower));
459  *pInitialWavesData++ = std::complex<float>(_getGaussianRandomFloat() * temp, _getGaussianRandomFloat() * temp);
460 
461  temp=9.81f * wave.length();
462  *pAngularFrequenciesData++ = Ogre::Math::Sqrt(temp);
463  }
464  }
465 
466  _calculeNoise(0);
467  }
468 
469  void FFT::_calculeNoise(const float &delta)
470  {
471  time += delta*mOptions.AnimationSpeed;
472 
473  std::complex<float>* pData = currentWaves;
474 
475  int u, v;
476 
477  float wt,
478  coswt, sinwt,
479  realVal, imagVal;
480 
481  for (u = 0; u < resolution; u++)
482  {
483  for (v = 0; v< resolution ; v++)
484  {
485  const std::complex<float>& positive_h0 = initialWaves[u * (resolution)+v];
486  const std::complex<float>& negative_h0 = initialWaves[(resolution-1 - u) * (resolution) + (resolution-1- v)];
487 
488  wt = angularFrequencies[u * (resolution) + v] * time;
489 
490  coswt = Ogre::Math::Cos(wt);
491  sinwt = Ogre::Math::Sin(wt);
492 
493  realVal =
494  positive_h0.real() * coswt - positive_h0.imag() * sinwt + negative_h0.real() * coswt - (-negative_h0.imag()) * (-sinwt),
495  imagVal =
496  positive_h0.real() * sinwt + positive_h0.imag() * coswt + negative_h0.real() * (-sinwt) + (-negative_h0.imag()) * coswt;
497 
498  *pData++ = std::complex<float>(realVal, imagVal);
499  }
500  }
501 
504  }
505 
506  const float FFT::_getGaussianRandomFloat() const
507  {
508  float x1, x2, w, y1;
509 
510  do
511  {
512  x1 = 2.0f * uniform_deviate() - 1.0f;
513  x2 = 2.0f * uniform_deviate() - 1.0f;
514 
515  w = x1 * x1 + x2 * x2;
516 
517  } while ( w >= 1.0f );
518 
519  w = Ogre::Math::Sqrt( (-2.0f * Ogre::Math::Log( w ) ) / w );
520  y1 = x1 * w;
521 
522  return y1;
523  }
524 
525  const float FFT::_getPhillipsSpectrum(const Ogre::Vector2& waveVector, const Ogre::Vector2& wind, const float& kwPower_) const
526  {
527  // Compute the length of the vector
528  float k = waveVector.length();
529 
530  // To avoid division by 0
531  if (k < 0.0000001f)
532  {
533  return 0;
534  }
535  else
536  {
537  float windVelocity = wind.length(),
538  l = pow(windVelocity,2.0f)/9.81f,
539  dot=waveVector.dotProduct(wind);
540 
541  return mOptions.Amplitude*
542  (Ogre::Math::Exp(-1 / pow(k * l,2)) / (Ogre::Math::Pow(k,2) *
543  Ogre::Math::Pow(k,2))) * Ogre::Math::Pow(-dot/ (k * windVelocity), kwPower_);
544  }
545  }
546 
548  {
549  int l2n = 0, p = 1;
550  while (p < resolution)
551  {
552  p *= 2; l2n++;
553  }
554  int l2m = 0; p = 1;
555  while (p < resolution)
556  {
557  p *= 2; l2m++;
558  }
559 
560  resolution = 1<<l2m;
561  resolution = 1<<l2n;
562 
563  int x, y, i;
564 
565  for(x = 0; x <resolution; x++)
566  {
567  for(y = 0; y <resolution; y++)
568  {
569  re[resolution * x + y] = currentWaves[resolution * x + y].real();
570  img[resolution * x + y] = currentWaves[resolution * x + y].imag();
571  }
572  }
573 
574  //Bit reversal of each row
575  int j, k;
576  for(y = 0; y < resolution; y++) //for each row
577  {
578  j = 0;
579  for(i = 0; i < resolution - 1; i++)
580  {
581  re[resolution * i + y] = currentWaves[resolution * j + y].real();
582  img[resolution * i + y] = currentWaves[resolution * j + y].imag();
583 
584  k = resolution / 2;
585  while (k <= j)
586  {
587  j -= k;
588  k/= 2;
589  }
590 
591  j += k;
592  }
593  }
594 
595  //Bit reversal of each column
596  float tx = 0, ty = 0;
597  for(x = 0; x < resolution; x++) //for each column
598  {
599  j = 0;
600  for(i = 0; i < resolution - 1; i++)
601  {
602  if(i < j)
603  {
604  tx = re[resolution * x + i];
605  ty = img[resolution * x + i];
606  re[resolution * x + i] = re[resolution * x + j];
607  img[resolution * x + i] = img[resolution * x + j];
608  re[resolution * x + j] = tx;
609  img[resolution * x + j] = ty;
610  }
611  k = resolution / 2;
612  while (k <= j)
613  {
614  j -= k;
615  k/= 2;
616  }
617  j += k;
618  }
619  }
620 
621  //Calculate the FFT of the columns
622  float ca, sa,
623  u1, u2,
624  t1, t2,
625  z;
626 
627  int l1, l2,
628  l, i1;
629 
630  for(x = 0; x < resolution; x++) //for each column
631  {
632  //This is the 1D FFT:
633  ca = -1.0;
634  sa = 0.0;
635  l1 = 1, l2 = 1;
636 
637  for(l=0;l<l2n;l++)
638  {
639  l1 = l2;
640  l2 *= 2;
641  u1 = 1.0;
642  u2 = 0.0;
643  for(j = 0; j < l1; j++)
644  {
645  for(i = j; i < resolution; i += l2)
646  {
647  i1 = i + l1;
648  t1 = u1 * re[resolution * x + i1] - u2 * img[resolution * x + i1];
649  t2 = u1 * img[resolution * x + i1] + u2 * re[resolution * x + i1];
650  re[resolution * x + i1] = re[resolution * x + i] - t1;
651  img[resolution * x + i1] = img[resolution * x + i] - t2;
652  re[resolution * x + i] += t1;
653  img[resolution * x + i] += t2;
654  }
655  z = u1 * ca - u2 * sa;
656  u2 = u1 * sa + u2 * ca;
657  u1 = z;
658  }
659  sa = Ogre::Math::Sqrt((1.0f - ca) / 2.0f);
660  ca = Ogre::Math::Sqrt((1.0f+ca) / 2.0f);
661  }
662  }
663  //Calculate the FFT of the rows
664  for(y = 0; y < resolution; y++) //for each row
665  {
666  //This is the 1D FFT:
667  ca = -1.0;
668  sa = 0.0;
669  l1= 1, l2 = 1;
670 
671  for(l = 0; l < l2m; l++)
672  {
673  l1 = l2;
674  l2 *= 2;
675  u1 = 1.0;
676  u2 = 0.0;
677  for(j = 0; j < l1; j++)
678  {
679  for(i = j; i < resolution; i += l2)
680  {
681  i1 = i + l1;
682  t1 = u1 * re[resolution * i1 + y] - u2 * img[resolution * i1 + y];
683  t2 = u1 * img[resolution * i1 + y] + u2 * re[resolution* i1 + y];
684  re[resolution * i1 + y] = re[resolution * i + y] - t1;
685  img[resolution * i1 + y] = img[resolution * i + y] - t2;
686  re[resolution * i + y] += t1;
687  img[resolution * i + y] += t2;
688  }
689  z = u1 * ca - u2 * sa;
690  u2 = u1 * sa + u2 * ca;
691  u1 = z;
692  }
693  sa = Ogre::Math::Sqrt((1.0f - ca) / 2.0f);
694  ca = Ogre::Math::Sqrt((1.0f+ca) / 2.0f);
695  }
696  }
697 
698  for(x=0;x<resolution;x++)
699  {
700  for(y=0;y<resolution;y++)
701  {
702  if (((x+y) & 0x1)==1)
703  {
704  re[x*resolution+y]*=1;
705  }
706  else
707  {
708  re[x*resolution+y]*=-1;
709  }
710  }
711  }
712  }
713 
714  void FFT::_normalizeFFTData(const float& scale)
715  {
716  float scaleCoef = 0.000001f;
717  int i;
718 
719  // Perform automatic detection of maximum value
720  if (scale == 0.0f)
721  {
722  float min=re[0], max=re[0],
723  currentMax=maximalValue;;
724 
725  for(i=1;i<resolution*resolution;i++)
726  {
727  if (min>re[i]) min=re[i];
728  if (max<re[i]) max=re[i];
729  }
730 
731  min=Ogre::Math::Abs(min);
732  max=Ogre::Math::Abs(max);
733 
734  currentMax = (min>max) ? min : max;
735 
736  if (currentMax>maximalValue) maximalValue=currentMax;
737 
738  scaleCoef += maximalValue;
739  }
740  else
741  { // User defined scale
742  scaleCoef=scale;
743  }
744 
745  // Scale all the value, and clamp to [0,1] range
746  int x, y;
747  for(x=0;x<resolution;x++)
748  {
749  for(y=0;y<resolution;y++)
750  {
751  i=x*resolution+y;
752  re[i]=(re[i]+scaleCoef)/(scaleCoef*2);
753  }
754  }
755  }
756 
757  float FFT::getValue(const float &x, const float &y)
758  {
759  // Scale world coords
760  float xScale = x*mOptions.Scale,
761  yScale = y*mOptions.Scale;
762 
763  // Convert coords from world-space to data-space
764  int xs = static_cast<int>(xScale)%resolution,
765  ys = static_cast<int>(yScale)%resolution;
766 
767  // If data-space coords are negative, transform it to positive
768  if (x<0) xs += resolution-1;
769  if (y<0) ys += resolution-1;
770 
771  // Determine x and y diff for linear interpolation
772  int xINT = (x>0) ? static_cast<int>(xScale) : static_cast<int>(xScale-1),
773  yINT = (y>0) ? static_cast<int>(yScale) : static_cast<int>(yScale-1);
774 
775  // Calculate interpolation coeficients
776  float xDIFF = xScale-xINT,
777  yDIFF = yScale-yINT,
778  _xDIFF = 1-xDIFF,
779  _yDIFF = 1-yDIFF;
780 
781  // To adjust the index if coords are out of range
782  int xxs = (xs==resolution-1) ? -1 : xs,
783  yys = (ys==resolution-1) ? -1 : ys;
784 
785  // A B
786  //
787  //
788  // C D
789  float A = re[(ys*resolution+xs)],
790  B = re[(ys*resolution+xxs+1)],
791  C = re[((yys+1)*resolution+xs)],
792  D = re[((yys+1)*resolution+xxs+1)];
793 
794  // Return the result of the linear interpolation
795  return (A*_xDIFF*_yDIFF +
796  B* xDIFF*_yDIFF +
797  C*_xDIFF* yDIFF +
798  D* xDIFF* yDIFF) // Range [-0.3, 0.3]
799  *0.6f-0.3f;
800  }
801 }}
Hydrax::GPUNormalMapManager::getTexture
Ogre::TexturePtr & getTexture(const int &Index)
Get a texture.
Definition: GPUNormalMapManager.h:111
Hydrax::Noise::Noise::remove
virtual void remove()
Remove.
Definition: Noise.cpp:47
Hydrax::Noise::FFT::currentWaves
std::complex< float > * currentWaves
the data of the simulation at time t, which is formed using the data at time 0 and the angular freque...
Definition: FFT.h:264
y
float y
Definition: (ValueTypes) quaternion.h:6
Hydrax::Noise::Noise::createGPUNormalMapResources
virtual bool createGPUNormalMapResources(GPUNormalMapManager *g)
Create GPUNormalMap resources.
Definition: Noise.cpp:52
Hydrax::Noise::FFT::_executeInverseFFT
void _executeInverseFFT()
Execute inverse fast fourier transform.
Definition: FFT.cpp:547
Hydrax::MaterialManager::SM_GLSL
@ SM_GLSL
Definition: MaterialManager.h:95
Hydrax::Noise::FFT::_initNoise
void _initNoise()
Initialize noise.
Definition: FFT.cpp:433
Hydrax::Noise::FFT::~FFT
~FFT()
Destructor.
Definition: FFT.cpp:66
Hydrax::Noise::Noise::create
virtual void create()
Create.
Definition: Noise.cpp:42
Hydrax::Noise::FFT::_getGaussianRandomFloat
const float _getGaussianRandomFloat() const
Get a Gaussian random number with mean 0 and standard deviation 1, using Box - muller transform.
Definition: FFT.cpp:506
Hydrax::GPUNormalMapManager::getNormalMapMaterial
Ogre::MaterialPtr & getNormalMapMaterial()
Get the normal map material.
Definition: GPUNormalMapManager.h:102
Hydrax::Noise::FFT::Options::AnimationSpeed
float AnimationSpeed
Animation speed.
Definition: FFT.h:60
Hydrax::Noise::FFT::Options::WindDirection
Ogre::Vector2 WindDirection
Wind direction.
Definition: FFT.h:58
Hydrax
Definition: CfgFileManager.cpp:28
z
float z
Definition: (ValueTypes) quaternion.h:7
Hydrax::Hydrax::getMaterialManager
MaterialManager * getMaterialManager()
Get Hydrax::MaterialManager.
Definition: Hydrax.h:325
Hydrax.h
Hydrax::Noise::FFT::Options::Amplitude
float Amplitude
Noise amplitude.
Definition: FFT.h:64
Hydrax::Noise::FFT::_getPhillipsSpectrum
const float _getPhillipsSpectrum(const Ogre::Vector2 &waveVector, const Ogre::Vector2 &wind, const float &kwPower_=2.0f) const
Get the Philipps Spectrum, used to create the amplitudes and phases.
Definition: FFT.cpp:525
Hydrax::Noise::FFT::Options::KwPower
float KwPower
KwPower.
Definition: FFT.h:62
Hydrax::MaterialManager
Material/Shader manager class.
Definition: MaterialManager.h:44
Hydrax::Noise::Noise::removeGPUNormalMapResources
virtual void removeGPUNormalMapResources(GPUNormalMapManager *g)
Remove GPUNormalMap resources.
Definition: Noise.cpp:71
Hydrax::Noise::Noise::loadCfg
virtual bool loadCfg(Ogre::ConfigFile &CfgFile)
Load config.
Definition: Noise.cpp:87
Hydrax::Noise::Noise::saveCfg
virtual void saveCfg(Ogre::String &Data)
Save config.
Definition: Noise.cpp:81
Hydrax::Noise::FFT::createGPUNormalMapResources
bool createGPUNormalMapResources(GPUNormalMapManager *g)
Create GPUNormalMap resources.
Definition: FFT.cpp:175
Hydrax::Noise::FFT::maximalValue
float maximalValue
The minimal value of the result data of the fft transformation.
Definition: FFT.h:259
Hydrax::GPUNormalMapManager::addTexture
void addTexture(Ogre::TexturePtr &Texture)
Create a texture.
Definition: GPUNormalMapManager.h:119
Hydrax::Noise::FFT::_updateGPUNormalMapResources
void _updateGPUNormalMapResources()
Update gpu normal map resources.
Definition: FFT.cpp:371
Hydrax::GPUNormalMapManager
Class to manager GPU normal maps.
Definition: GPUNormalMapManager.h:45
Hydrax::Noise::FFT::mGPUNormalMapManager
GPUNormalMapManager * mGPUNormalMapManager
GPUNormalMapManager pointer.
Definition: FFT.h:271
Hydrax::Noise::FFT::saveCfg
void saveCfg(Ogre::String &Data)
Save config.
Definition: FFT.cpp:391
Hydrax::Hydrax::getShaderMode
const MaterialManager::ShaderMode & getShaderMode() const
Get current shader mode.
Definition: Hydrax.h:405
w
float w
Definition: (ValueTypes) quaternion.h:4
Hydrax::Noise::FFT::update
void update(const Ogre::Real &timeSinceLastFrame)
Call it each frame.
Definition: FFT.cpp:423
Hydrax::Noise::FFT::Options::GPU_LODParameters
Ogre::Vector3 GPU_LODParameters
LOD Parameters, in order to obtain a smooth normal map we need to decrease the detail level when the ...
Definition: FFT.h:78
Exp
quaternion Exp() const
FFT.h
Hydrax::Noise::FFT::resolution
int resolution
FFT resolution.
Definition: FFT.h:255
Hydrax::Noise::FFT::_calculeNoise
void _calculeNoise(const float &delta)
Calcule noise.
Definition: FFT.cpp:469
Hydrax::Noise::FFT::Options::GPU_Strength
float GPU_Strength
GPU Normal map generator parameters Only if GPU normal map generation is active.
Definition: FFT.h:70
Hydrax::Noise::FFT::setOptions
void setOptions(const Options &Options)
Set/Update fft noise options.
Definition: FFT.cpp:125
Hydrax::Noise::FFT::mOptions
Options mOptions
Perlin noise options.
Definition: FFT.h:274
Hydrax::Noise::Noise::getName
const Ogre::String & getName() const
Get noise name.
Definition: Noise.h:92
Hydrax::MaterialManager::fillGpuProgramsToPass
bool fillGpuProgramsToPass(Ogre::Pass *Pass, const Ogre::String GpuProgramNames[2], const ShaderMode &SM, const Ogre::String EntryPoints[2], const Ogre::String Data[2])
Fill GPU vertex and fragment program to a pass.
Definition: MaterialManager.cpp:239
Hydrax::Noise::FFT::FFT
FFT()
Default constructor.
Definition: FFT.cpp:37
Hydrax::MaterialManager::SM_HLSL
@ SM_HLSL
Definition: MaterialManager.h:91
Hydrax::Noise::uniform_deviate
float uniform_deviate()
Definition: FFT.cpp:32
Hydrax::Noise::Noise
Base noise class, Override it for create different ways of create water noise.
Definition: Noise.h:42
Hydrax::Noise::FFT::Options::Scale
float Scale
Noise scale.
Definition: FFT.h:56
Hydrax::Noise::FFT::create
void create()
Create.
Definition: FFT.cpp:73
Hydrax::Noise::FFT::getValue
float getValue(const float &x, const float &y)
Get the especified x/y noise value.
Definition: FFT.cpp:757
HydraxLOG
#define HydraxLOG(msg)
Definition: Application.h:59
Hydrax::Noise::FFT::angularFrequencies
float * angularFrequencies
the angular frequencies
Definition: FFT.h:266
Hydrax::Noise::FFT::Options::PhysicalResolution
float PhysicalResolution
Physical resolution.
Definition: FFT.h:54
Hydrax::GPUNormalMapManager::getHydrax
Hydrax * getHydrax()
Get the Hydrax parent pointer.
Definition: GPUNormalMapManager.h:94
Hydrax::CfgFileManager::_getCfgString
static Ogre::String _getCfgString(const Ogre::String &Name, const int &Value)
Definition: CfgFileManager.cpp:155
Hydrax::Noise::FFT::remove
void remove()
Remove.
Definition: FFT.cpp:85
Hydrax::Noise::FFT::loadCfg
bool loadCfg(Ogre::ConfigFile &CfgFile)
Load config.
Definition: FFT.cpp:404
Hydrax::Noise::FFT::img
float * img
Definition: FFT.h:257
Hydrax::Noise::Noise::areGPUNormalMapResourcesCreated
const bool & areGPUNormalMapResourcesCreated() const
Are GPU normal map resources created?
Definition: Noise.h:116
Hydrax::GPUNormalMapManager::create
void create()
Create.
Definition: GPUNormalMapManager.cpp:47
Hydrax::Noise::FFT::time
float time
Current time.
Definition: FFT.h:268
Hydrax::Noise::FFT::initialWaves
std::complex< float > * initialWaves
the data which is referred as h0{x,t), that is, the data of the simulation at the time 0.
Definition: FFT.h:262
Hydrax::Noise::FFT::re
float * re
Pointers to resolution*resolution float size arrays.
Definition: FFT.h:257
Hydrax::CfgFileManager::_getIntValue
static int _getIntValue(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get int value.
Definition: CfgFileManager.cpp:432
Hydrax::Noise::Noise::isCreated
const bool & isCreated() const
Is created() called?
Definition: Noise.h:100
Hydrax::Noise::FFT::Options::Resolution
int Resolution
Noise resolution (2^n)
Definition: FFT.h:52
Hydrax::CfgFileManager::_getVector2Value
static Ogre::Vector2 _getVector2Value(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get vector2 value.
Definition: CfgFileManager.cpp:474
Hydrax::MaterialManager::SM_CG
@ SM_CG
Definition: MaterialManager.h:93
Hydrax::CfgFileManager::_getFloatValue
static Ogre::Real _getFloatValue(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get float value.
Definition: CfgFileManager.cpp:446
Hydrax::Noise::FFT::_normalizeFFTData
void _normalizeFFTData(const float &scale)
Normalize fft data.
Definition: FFT.cpp:714
x
float x
Definition: (ValueTypes) quaternion.h:5
Log
quaternion Log() const
Hydrax::Noise::Noise::isGPUNormalMapSupported
const bool & isGPUNormalMapSupported() const
Is GPU Normal map generation supported.
Definition: Noise.h:108
Hydrax::Noise::FFT::Options
Struct wich contains fft noise module options.
Definition: FFT.h:49