Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
FFT.cpp
Go to the documentation of this file.
1/*
2--------------------------------------------------------------------------------
3This currentWaves file is part of Hydrax.
4Visit ---
5
6Copyright (C) 2008 Xavier Verguín González <xavierverguin@hotmail.com>
7 <xavyiy@gmail.com>
8
9This program is free software; you can redistribute it and/or modify it under
10the terms of the GNU Lesser General Public License as published by the Free Software
11Foundation; either version 2 of the License, or (at your option) any later
12version.
13
14This program is distributed in the hope that it will be useful, but WITHOUT
15ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public License along with
19this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21http://www.gnu.org/copyleft/lesser.txt.
22--------------------------------------------------------------------------------
23*/
24
25#include "FFT.h"
26#include "OgrePixelFormat.h"
27
28#include <Hydrax.h>
29
30namespace 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
74 {
75 if (isCreated())
76 {
77 return;
78 }
79
80 _initNoise();
81
83 }
84
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
115 {
116 delete [] angularFrequencies;
117 }
118
119 maximalValue = 2;
120 time = 10;
121
123 }
124
126 {
127 if (isCreated())
128 {
134 {
135 remove();
136
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
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
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 {
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
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}}
#define HydraxLOG(msg)
Definition Application.h:60
static Ogre::String _getCfgString(const Ogre::String &Name, const int &Value)
static Ogre::Real _getFloatValue(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get float value.
static Ogre::Vector2 _getVector2Value(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get vector2 value.
static int _getIntValue(Ogre::ConfigFile &CfgFile, const Ogre::String Name)
Get int value.
Class to manager GPU normal maps.
Ogre::TexturePtr & getTexture(const int &Index)
Get a texture.
Hydrax * getHydrax()
Get the Hydrax parent pointer.
void addTexture(Ogre::TexturePtr &Texture)
Create a texture.
Ogre::MaterialPtr & getNormalMapMaterial()
Get the normal map material.
const MaterialManager::ShaderMode & getShaderMode() const
Get current shader mode.
Definition Hydrax.h:405
MaterialManager * getMaterialManager()
Get Hydrax::MaterialManager.
Definition Hydrax.h:325
Material/Shader manager class.
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.
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
void _calculeNoise(const float &delta)
Calcule noise.
Definition FFT.cpp:469
void _initNoise()
Initialize noise.
Definition FFT.cpp:433
void setOptions(const Options &Options)
Set/Update fft noise options.
Definition FFT.cpp:125
float time
Current time.
Definition FFT.h:268
float * angularFrequencies
the angular frequencies
Definition FFT.h:266
Options mOptions
Perlin noise options.
Definition FFT.h:274
void _executeInverseFFT()
Execute inverse fast fourier transform.
Definition FFT.cpp:547
void _normalizeFFTData(const float &scale)
Normalize fft data.
Definition FFT.cpp:714
float * re
Pointers to resolution*resolution float size arrays.
Definition FFT.h:257
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
FFT()
Default constructor.
Definition FFT.cpp:37
bool loadCfg(Ogre::ConfigFile &CfgFile)
Load config.
Definition FFT.cpp:404
void saveCfg(Ogre::String &Data)
Save config.
Definition FFT.cpp:391
const float _getGaussianRandomFloat() const
Get a Gaussian random number with mean 0 and standard deviation 1, using Box - muller transform.
Definition FFT.cpp:506
float * img
Definition FFT.h:257
void remove()
Remove.
Definition FFT.cpp:85
int resolution
FFT resolution.
Definition FFT.h:255
bool createGPUNormalMapResources(GPUNormalMapManager *g)
Create GPUNormalMap resources.
Definition FFT.cpp:175
GPUNormalMapManager * mGPUNormalMapManager
GPUNormalMapManager pointer.
Definition FFT.h:271
void _updateGPUNormalMapResources()
Update gpu normal map resources.
Definition FFT.cpp:371
float maximalValue
The minimal value of the result data of the fft transformation.
Definition FFT.h:259
void create()
Create.
Definition FFT.cpp:73
float getValue(const float &x, const float &y)
Get the especified x/y noise value.
Definition FFT.cpp:757
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
void update(const Ogre::Real &timeSinceLastFrame)
Call it each frame.
Definition FFT.cpp:423
~FFT()
Destructor.
Definition FFT.cpp:66
Base noise class, Override it for create different ways of create water noise.
Definition Noise.h:43
virtual void remove()
Remove.
Definition Noise.cpp:47
const Ogre::String & getName() const
Get noise name.
Definition Noise.h:92
const bool & areGPUNormalMapResourcesCreated() const
Are GPU normal map resources created?
Definition Noise.h:116
virtual bool createGPUNormalMapResources(GPUNormalMapManager *g)
Create GPUNormalMap resources.
Definition Noise.cpp:52
virtual bool loadCfg(Ogre::ConfigFile &CfgFile)
Load config.
Definition Noise.cpp:87
const bool & isGPUNormalMapSupported() const
Is GPU Normal map generation supported.
Definition Noise.h:108
virtual void removeGPUNormalMapResources(GPUNormalMapManager *g)
Remove GPUNormalMap resources.
Definition Noise.cpp:71
virtual void saveCfg(Ogre::String &Data)
Save config.
Definition Noise.cpp:81
virtual void create()
Create.
Definition Noise.cpp:42
const bool & isCreated() const
Is created() called?
Definition Noise.h:100
float uniform_deviate()
Definition FFT.cpp:32
Struct wich contains fft noise module options.
Definition FFT.h:50
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
float GPU_Strength
GPU Normal map generator parameters Only if GPU normal map generation is active.
Definition FFT.h:70
float Amplitude
Noise amplitude.
Definition FFT.h:64
float KwPower
KwPower.
Definition FFT.h:62
int Resolution
Noise resolution (2^n)
Definition FFT.h:52
Ogre::Vector2 WindDirection
Wind direction.
Definition FFT.h:58
float Scale
Noise scale.
Definition FFT.h:56
float AnimationSpeed
Animation speed.
Definition FFT.h:60
float PhysicalResolution
Physical resolution.
Definition FFT.h:54