⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ocean.cpp

📁 基于FFT的海面模拟。能够实现海面的复制
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	for (int i=0;i<this->oceanSizeX;i++)
	{
		this->oceanGridPosition[this->oceanSizeX][i][0]=this->oceanGridPosition[0][i][0]+this->oceanSizeX*2;
		this->oceanGridPosition[this->oceanSizeX][i][1]=this->oceanGridPosition[0][i][1];
		this->oceanGridPosition[this->oceanSizeX][i][2]=this->oceanGridPosition[0][i][2];

		this->oceanBigNormals[this->oceanSizeX][i][0]=this->oceanBigNormals[0][i][0];
		this->oceanBigNormals[this->oceanSizeX][i][1]=this->oceanBigNormals[0][i][1];
		this->oceanBigNormals[this->oceanSizeX][i][2]=this->oceanBigNormals[0][i][2];
	}

	for (int i=0;i<this->oceanSizeY + 1;i++)
	{
		this->oceanGridPosition[i][this->oceanSizeY][0]=this->oceanGridPosition[i][0][0];
		this->oceanGridPosition[i][this->oceanSizeY][1]=this->oceanGridPosition[i][0][1];
		this->oceanGridPosition[i][this->oceanSizeY][2]=this->oceanGridPosition[i][0][2]+this->oceanSizeY*2;

		this->oceanBigNormals[i][this->oceanSizeY][0]=this->oceanBigNormals[i][0][0];
		this->oceanBigNormals[i][this->oceanSizeY][1]=this->oceanBigNormals[i][0][1];
		this->oceanBigNormals[i][this->oceanSizeY][2]=this->oceanBigNormals[i][0][2];
	}

	this->oceanBigNormals[this->oceanSizeX][this->oceanSizeY][0]=this->oceanBigNormals[0][0][0];
	this->oceanBigNormals[this->oceanSizeX][this->oceanSizeY][1]=this->oceanBigNormals[0][0][1];
	this->oceanBigNormals[this->oceanSizeX][this->oceanSizeY][2]=this->oceanBigNormals[0][0][2];
}

void T_Ocean:: oceanPreChoppy()
{
	double k[2];
	double klen;

	for (int i=0;i<this->oceanSizeX + 1;i++)
	{
		for (int j=0;j<this->oceanSizeY;j++)
		{
			k[0]=this->oceanHoldHorizontal[i][j][0];
			k[1]=this->oceanHoldHorizontal[i][j][1];
			klen=sqrt(k[0]*k[0]+k[1]*k[1]);

			if (klen==0)
			{
				this->oceanDeltaX[i][j].real=0.0;
				this->oceanDeltaX[i][j].imag=0.0;
				this->oceanDeltaX[i][j].real=0.0;
				this->oceanDeltaX[i][j].imag=0.0;
			}
			else
			{
				this->oceanDeltaX[i][j].real=0.0;
				this->oceanDeltaX[i][j].imag=this->oceanC[i][j].imag*(-k[0]/klen);
				this->oceanDeltaX[i][j].real=0.0;
				this->oceanDeltaX[i][j].imag=this->oceanC[i][j].imag*(-k[1]/klen);
			}
		}
	}

	this->fftDir=-1;
	if (ouFFT2D(this->oceanDeltaX, this->oceanSizeX, this->oceanSizeY, this->fftDir)==0)
	{
		exit( 0);
	}

	this->fftDir=-1;

	if (ouFFT2D(this->oceanDeltaX, this->oceanSizeX, this->oceanSizeY, this->fftDir)==0)
	{
		exit( 0);
	}

	for (int i=0;i<this->oceanSizeX;i++)
	{
		for (int j=0;j<this->oceanSizeY;j++)
		{
			this->oceanDeltaX[i][j].real *= (double) ouNeg1Pow(i+j)*this->oceanLambda;//参数lambda绝对值越大,波浪的对流效果就越明显
			this->oceanDeltaX[i][j].imag *= (double) ouNeg1Pow(i+j)*this->oceanLambda;
			this->oceanDeltaX[i][j].real *= (double) ouNeg1Pow(i+j)*this->oceanLambda;
			this->oceanDeltaX[i][j].imag *= (double) ouNeg1Pow(i+j)*this->oceanLambda;
		}
	}
}

void T_Ocean::oceanSimulating(float timeStep)
{
		float kvector[2];
		float klength;
		float wkt;

		this->oceanTimeDiff += timeStep;	//时间步长
		int yHalf = (this->oceanSizeY)/2 + 1;
		for (int i = 0; i<yHalf; ++i)
		{
			int yLine = i*(this->oceanSizeY);
			int yLineMirr = (((this->oceanSizeY)-i)% (this->oceanSizeY))*(this->oceanSizeY);

			for (int j = 0; j<(this->oceanSizeX); ++j)
			{
				kvector[0]=this->oceanHoldHorizontal[i][j][0];
				kvector[1]=this->oceanHoldHorizontal[i][j][1];
				klength=this->oceanHoldHorizontal[i][j][2];//矢量K的模
				wkt = sqrt(klength * worldGravity) * this->oceanTimeDiff;//求解SQRT(omega(K))*t带入方程8求解出h(K,t)
				int  kNegIndex = yLineMirr*(this->oceanSizeY) + (((this->oceanSizeY)-j)% (this->oceanSizeY));
			
				this->oceanC[i][j].real= this->oceanH0[i][j].real*cos(wkt)
					+ this->oceanH0[i][j].imag*sin(wkt)
					+ this->oceanH0[(this->oceanSizeX) - i-1][(this->oceanSizeY) - j-1].real*cos(wkt)
					- this->oceanH0[(this->oceanSizeX) - i-1][(this->oceanSizeY) -j-1].imag*sin(wkt);

				this->oceanC[i][j].imag= this->oceanH0[i][j].imag*cos(wkt)
					+ this->oceanH0[i][j].real*sin(wkt)
					-this->oceanH0[(this->oceanSizeX) - i-1][(this->oceanSizeY) - j-1].imag*cos(wkt)
					- this->oceanH0[(this->oceanSizeX) - i-1][(this->oceanSizeY) -j-1].real*sin(wkt);

				if (i != yHalf-1)
				{
					this->oceanC[(this->oceanSizeX) - i-1][(this->oceanSizeY)  - j-1].imag= this->oceanH0[i][j].real*cos(wkt)
						+ this->oceanH0[i][j].imag*sin(wkt)
						+ this->oceanH0[(this->oceanSizeX) - i-1][(this->oceanSizeY) - j-1].real*cos(wkt)
						- this->oceanH0[(this->oceanSizeX) - i-1][(this->oceanSizeY) -j-1].imag*sin(wkt);

					this->oceanC[(this->oceanSizeX) - i-1][(this->oceanSizeY) - j-1].real= this->oceanH0[i][j].imag*cos(wkt)
						+ this->oceanH0[i][j].real*sin(wkt)
						-this->oceanH0[(this->oceanSizeX) - i-1][(this->oceanSizeY) - j-1].imag*cos(wkt)
						- this->oceanH0[(this->oceanSizeX) - i-1][(this->oceanSizeY) -j-1].real*sin(wkt);
				}
			}
		}

		//this->oceanPreChoppy();//该函数被注释后,海面无法重叠,但是可以运行
		this->fftDir=-1;
		ouFFT2D(this->oceanC, this->oceanSizeX, this->oceanSizeY, this->fftDir);//逆傅立叶变换得到表面,返回值是C[][].real和C[][].imag 

		for (int i=0;i<this->oceanSizeX;i++)
		{
			for (int j=0;j<this->oceanSizeY;j++)
			{
				this->oceanC[i][j].real *= float(ouNeg1Pow(i+j));
				this->oceanDisplayXY[i][j][0]=((double)i/(this->oceanSizeX))*((this->oceanSizeX)*2)+this->oceanDeltaX[i][j].imag;
				this->oceanDisplayXY[i][j][1]=((double)j/(this->oceanSizeY))*((this->oceanSizeY)*2)+this->oceanDeltaY[i][j].imag;
			}
		}
		this->oceanMakeNormals(this->oceanC);//产生法线,与光照计算相关联
		this->oceanPrepLoop();	//this loop loads the actual sea vertices装载真实的海面定点,displayXY->sea[][]
}



void T_Ocean::particleIntial()
{
	for (int i = 0;i < this->oceanSizeX; i++)
	{
		for (int j = 0; j< this->oceanSizeY; j++)
		{
			for (int k = 0; k< this->particleNum; k++)
			{
				this->oceanParticle[i][j][k].active = true;
				this->oceanParticle[i][j][k].life = 1.0f;
				this->oceanParticle[i][j][k].fade = float(rand()%100)/1000.0f;
				this->oceanParticle[i][j][k].particleColor.r = 1.0f;
				this->oceanParticle[i][j][k].particleColor.g = 1.0f;
				this->oceanParticle[i][j][k].particleColor.b = 1.0f;
			}
		}
	}
}

void T_Ocean::BreakingWaveSimulating()
{
	for (int i = 0;i < this->oceanSizeX; i++)
	{
		for (int j = 0; j< this->oceanSizeY; j++)
		{
			for (int k = 0; k< this->particleNum; k++)
			{
				if (this->oceanBigNormals[i][j][0]<0 && this->oceanBigNormals[i][j][1]<0)// && this->oceanGridPosition[i][j][1] > 10.0f ) 
				{
					if (this->oceanParticle[i][j][k].life > 0)
					{
						this->oceanParticle[i][j][k].life -= this->oceanParticle[i][j][k].fade;
						this->oceanParticle[i][j][k].particleVelocity.y += worldGravity;

						this->oceanParticle[i][j][k].particlePosition.x += this->oceanParticle[i][j][k].particleVelocity.x/1000.0f;
						this->oceanParticle[i][j][k].particlePosition.y += -this->oceanParticle[i][j][k].particleVelocity.y/500.0f;
						this->oceanParticle[i][j][k].particlePosition.z += this->oceanParticle[i][j][k].particleVelocity.z/1000.0f;

					}
					else
					{
						this->oceanParticle[i][j][k].life = 0.5f;
						this->oceanParticle[i][j][k].fade = float(rand()%100)/100.0f;

						this->oceanParticle[i][j][k].particlePosition.x = this->oceanGridPosition[i][j][0];
						this->oceanParticle[i][j][k].particlePosition.y = this->oceanGridPosition[i][j][1];
						this->oceanParticle[i][j][k].particlePosition.z = this->oceanGridPosition[i][j][2];

						this->oceanParticle[i][j][k].particleVelocity.x=(1+0.5*worldGravity*(maxHeight-this->oceanGridPosition[i][j][1]))*this->oceanBigNormals[i][j][0]*0.15;	
						this->oceanParticle[i][j][k].particleVelocity.y=(1+0.5*worldGravity*(maxHeight-this->oceanGridPosition[i][j][1]))*this->oceanBigNormals[i][j][2]*0.01;
						this->oceanParticle[i][j][k].particleVelocity.z=(1+0.5*worldGravity*(maxHeight-this->oceanGridPosition[i][j][1]))*this->oceanBigNormals[i][j][1]*0.15;
					}
				}
			}
		}
	}
}


void setOceanWaveHeight(T_Ocean* ocean,  float waveHeight)
{
ocean->oceanWaveHeight =  waveHeight;
}

void enableBreakingWave(T_Ocean* ocean)
{
	ocean->showParticle = true;
}

void disableBreakingWave(T_Ocean* ocean)
{
	ocean->showParticle = false;
}

int getOceanSizeX(T_Ocean* ocean)
{
	return ocean->oceanSizeX;
}


int getOceanSizeY(T_Ocean* ocean)
{
	return ocean->oceanSizeY;
}


float getOceanWindScaleX(T_Ocean* ocean)
{
	return ocean->oceanWindScaleX;
}


float getOceanWindScaleY(T_Ocean* ocean)
{
	return ocean->oceanWindScaleY;
}


float getOceanLambda(T_Ocean* ocean)
{
	return ocean->oceanLambda;
}


float getOceanWaveHeight(T_Ocean* ocean)
{
	return ocean->oceanWaveHeight;
}

void simuOcean(T_Ocean* ocean, float timeStep)
{
	ocean->oceanSimulating(timeStep);

	if (ocean->showParticle)
	{
		ocean->BreakingWaveSimulating();
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -