override public void GenerateHeightField(int currentFrame, ExtendedHeightField extendedHeightField) { Profiler.BeginSample("Clear Height Field"); extendedHeightField.Clear(); Profiler.EndSample(); Profiler.BeginSample("Set Point Map"); waveParticles.setPointMap(currentFrame, ref pointMap); Profiler.EndSample(); Profiler.BeginSample("Convolve Wave Particles"); for (int row = 0; row < heightFieldInfo.VertRes; row++) { for (int col = 0; col < heightFieldInfo.HoriRes; col++) { int index = row * heightFieldInfo.HoriRes + col; for (int y = 0; y < kernelHeight; y++) { for (int x = 0; x < kernelWidth; x++) { int y_index = (y - (kernelHeight / 2)) + row; int x_index = (x - (kernelWidth / 2)) + col; if (y_index > 0 && y_index < heightFieldInfo.VertRes && x_index > 0 && x_index < heightFieldInfo.HoriRes) { int fresh_index = (y_index * heightFieldInfo.HoriRes) + (x_index); extendedHeightField.heightMap[index] += (Color)(pointMap.heightMap[fresh_index] * kernel[(y * kernelWidth) + x]); } } } } } extendedHeightField.ApplyCPUHeightMap(); Profiler.EndSample(); }
override public void GenerateHeightField(int currentFrame, ExtendedHeightField extendedHeightField) { Profiler.BeginSample("Clear Height Field"); extendedHeightField.Clear(); Profiler.EndSample(); Profiler.BeginSample("Set Point Map"); waveParticles.setPointMap(currentFrame, ref pointMap); Profiler.EndSample(); Profiler.BeginSample("Convolve Wave Particles"); convolveWaveParticles(); extendedHeightField.UpdateTexture(convolvedTexture); Profiler.EndSample(); }
override public void GenerateHeightField(int currentFrame, ExtendedHeightField extendedHeightField) { extendedHeightField.Clear(); foreach (WaveParticle waveParticle in waveParticles) { Vector2 waveParticlePosition = waveParticle.getPosition(currentFrame); int xPos = Mathf.RoundToInt((waveParticlePosition.x / heightFieldInfo.Width) * heightFieldInfo.HoriRes); int yPos = Mathf.RoundToInt((waveParticlePosition.y / heightFieldInfo.Height) * heightFieldInfo.VertRes); for (int y = 0; y < sectionWidth; y++) { for (int x = 0; x < sectionHeight; x++) { int col = (x - (sectionWidth / 2)) + xPos; int row = (y - (sectionHeight / 2)) + yPos; if (row > 0 && row < heightFieldInfo.VertRes && col > 0 && col < heightFieldInfo.HoriRes) { int index = row * heightFieldInfo.HoriRes + col; Vector2 position = new Vector2(heightFieldInfo.UnitX * col, heightFieldInfo.UnitY * row); Vector2 diff = position - waveParticlePosition; float abs_diff = diff.magnitude; if (abs_diff > WaveParticle.RADIUS) { // Don't need to do rest of calculation based on rectangle function. continue; } // Caclulate vertical displacement float piOverRadius = Mathf.PI / WaveParticle.RADIUS; float y_displacement = (waveParticle.amplitude * 0.5f) * (Mathf.Cos(abs_diff * piOverRadius) + 1); Vector2 longitudinalComponent; { float dotproduct = Vector2.Dot(waveParticle.velocity.normalized, diff); Vector2 Li = -Mathf.Sin(dotproduct * piOverRadius) * waveParticle.velocity.normalized; longitudinalComponent = y_displacement * Li; } float x_displacement = longitudinalComponent.x; float z_displacement = longitudinalComponent.y; extendedHeightField.heightMap[index] += new Color(x_displacement, y_displacement, z_displacement, 1f); } } } } }
public WaveParticleSystem(float particleSpeed, float particleRadius, int maxNumParticles, int horRes, int vertRes, float height, float width, float waveParticleKillThreshold) { _particleSpeed = particleSpeed; _particleRadius = particleRadius; _numParticles = maxNumParticles; _waveParticleKillThreshold = waveParticleKillThreshold; _currentFrame = 0; // TODO: move all relvant code to do with this to here! _frameCycleLength = WaveParticle.FRAME_CYCLE_LENGTH; _extendedHeightField = new ExtendedHeightField(width, height, horRes, vertRes); _extendedHeightField.Clear(); _particleContainer = SplatEnumToInstance(_splatImplementationChoice); _particleContainer.Initialise(maxNumParticles, waveParticleKillThreshold); _heightFieldGenerator = ConvEnumToInstance(_convolutionImplementationChoice); _heightFieldGenerator.Initialise(_extendedHeightField.heightFieldInfo, _particleContainer); }
void Start() { waterMaterial = GetComponent <Renderer>().material; waveParticles.Initialise(numWaveParticles, waveParticleKillThreshold); { int horRes = 100; int vertRes = 100; float height = 8; float width = 8; extendedHeightField = new ExtendedHeightField(width, height, horRes, vertRes); extendedHeightField.Clear(); } _mesh = GetComponent <MeshFilter>().mesh; vertices = new Vector3[extendedHeightField.HoriRes * extendedHeightField.VertRes]; uv = new Vector2[extendedHeightField.HoriRes * extendedHeightField.VertRes]; triangles = new int[(extendedHeightField.HoriRes - 1) * (extendedHeightField.VertRes - 1) * 6]; heightFieldGenerator = HeightFieldGeneratorSelector.CreateAndInitialise(selectedHeightFieldGenerator, extendedHeightField.heightFieldInfo, waveParticles); // Initialise and set-up the mesh the wave particles will be rendered to { GenerateMeshFromHeightMap(extendedHeightField, vertices, uv, triangles, _mesh); Renderer rend = GetComponent <Renderer>(); if (rend != null) { rend.material = waterMaterial; waterMaterial.SetTexture(Shader.PropertyToID("_MainTex"), extendedHeightField.textureHeightMap); waterMaterial.SetFloat(Shader.PropertyToID("_UnitX"), extendedHeightField.UnitX); waterMaterial.SetFloat(Shader.PropertyToID("_UnitY"), extendedHeightField.UnitY); waterMaterial.SetFloat(Shader.PropertyToID("_HoriResInverse"), 1f / ((float)extendedHeightField.HoriRes)); waterMaterial.SetFloat(Shader.PropertyToID("_VertResInverse"), 1f / ((float)extendedHeightField.VertRes)); waterMaterial.SetInt(Shader.PropertyToID("_VertexEnabled"), _useGpuForVertices ? 1 : 0); } } _hasStarted = true; }
public void setPointMap(int currentFrame, ref ExtendedHeightField pointMap) { bool antiAliased = false; Profiler.BeginSample("Clear Point Map"); pointMap.Clear(); Profiler.EndSample(); Profiler.BeginSample("Get Point Map Raw"); var pointMapRaw = pointMap.heightMap; Profiler.EndSample(); Profiler.BeginSample("Get Height Field Info"); var heightFieldInfo = pointMap.heightFieldInfo; Profiler.EndSample(); Profiler.BeginSample("For Each Wave Particle"); foreach (var waveParticle in this) { Profiler.BeginSample("Splat Wave Particle"); if (antiAliased) { Vector2 waveParticlePosition = waveParticle.getPosition(currentFrame); float xpos = (waveParticlePosition.x / heightFieldInfo.Width) * heightFieldInfo.HoriRes; float ypos = (waveParticlePosition.y / heightFieldInfo.Height) * heightFieldInfo.VertRes; int col0; int col1; int row0; int row1; { int col = Mathf.RoundToInt(xpos); int row = Mathf.RoundToInt(ypos); col0 = col - 1; row0 = row - 1; col1 = col; row1 = row; } float width0 = 0.5f + col1 - xpos; float width1 = 0.5f + xpos - col1; float height0 = 0.5f + row1 - ypos; float height1 = 0.5f + ypos - row1; bool col0InRange = col0 < heightFieldInfo.HoriRes && col0 > 0; bool col1InRange = col1 < heightFieldInfo.HoriRes && col1 > 0; bool row0InRange = row0 < heightFieldInfo.VertRes && row0 > 0; bool row1InRange = row1 < heightFieldInfo.VertRes && row1 > 0; if (col0InRange && row0InRange) { pointMapRaw[(row0 * heightFieldInfo.HoriRes) + col0].g += waveParticle.amplitude * width0 * height0; } if (col1InRange && row0InRange) { pointMapRaw[(row0 * heightFieldInfo.HoriRes) + col1].g += waveParticle.amplitude * width1 * height0; } if (col0InRange && row1InRange) { pointMapRaw[(row1 * heightFieldInfo.HoriRes) + col0].g += waveParticle.amplitude * width0 * height1; } if (col1InRange && row1InRange) { pointMapRaw[(row1 * heightFieldInfo.HoriRes) + col1].g += waveParticle.amplitude * width1 * height1; } } else { Vector2 waveParticlePosition = waveParticle.getPosition(currentFrame); int xPos = Mathf.RoundToInt((waveParticlePosition.x / heightFieldInfo.Width) * heightFieldInfo.HoriRes); int yPos = Mathf.RoundToInt((waveParticlePosition.y / heightFieldInfo.Height) * heightFieldInfo.VertRes); int index = (yPos * heightFieldInfo.HoriRes) + xPos; if (xPos < heightFieldInfo.HoriRes && xPos > 0 && yPos < heightFieldInfo.VertRes && yPos > 0) { pointMapRaw[index].g += waveParticle.amplitude; } } Profiler.EndSample(); } Profiler.EndSample(); Profiler.BeginSample("Apply CPU Height Map"); pointMap.ApplyCPUHeightMap(); Profiler.EndSample(); }