MWS/Terrain/Assets/Scripts/GrassController.cs
2021-09-16 19:47:54 +02:00

168 lines
3.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
struct DifferentialEquationData
{
public float water;
public float vegetation;
}
public class GrassController : MonoBehaviour
{
int _structSize()
{
return sizeof(float) + sizeof(float);
}
private GameObject cube;
public float updateInterval;
float timePassed;
Terrain terrain;
public ComputeShader computeShader;
[Header("equation coeffs")]
public float DWater = 1.0f;
public float DVegetation = 0.5f;
public float feedRate = 0.055f;
public float killRate = 0.0462f;
public float dT = 0.10f;
public int stepsNumber = 1;
int sizeX;
int sizeY;
ComputeBuffer vegetation;
ComputeBuffer oldVegetation;
// Start is called before the first frame update
void Start()
{
terrain = gameObject.GetComponent<Terrain>();
sizeX = terrain.terrainData.detailWidth;
sizeY = terrain.terrainData.detailHeight;
initComputeShader();
}
bool doUpdate()
{
timePassed += Time.deltaTime;
if (timePassed < updateInterval)
{
return false;
}
else
{
timePassed = 0;
return true;
}
}
void initKillFeedBuffers()
{
//tutaj stworz
}
public void initBufferValues()
{
// tutaj uzupelnij wartosci buforow
float[] initValues = new float[sizeX * sizeY];
for (int i = 0; i < sizeX * sizeY; i++)
{
initValues[i] = Random.Range(0.0f, 1.0f);
}
vegetation.SetData(initValues);
oldVegetation.SetData(initValues);
}
public void resetGrass()
{
initBufferValues();
//var detail = new int[sizeX, sizeY];
//for (int i = 0; i < sizeX; i++) {
// detail[i, i] = 16;
//}
//terrain.terrainData.SetDetailLayer(0, 0, 1, detail);
}
void initParameters()
{
//tutaj zainicjalizuj parametry
computeShader.SetInt("sizeX", sizeX);
computeShader.SetInt("sizeY", sizeY);
}
void initComputeShader()
{
//tutaj zainicjalizuj compute shader
vegetation = new ComputeBuffer(sizeX * sizeY, sizeof(float));
oldVegetation = new ComputeBuffer(sizeX * sizeY, sizeof(float));
computeShader.SetBuffer(0, "vegetation", vegetation);
computeShader.SetBuffer(0, "oldVegetation", oldVegetation);
initKillFeedBuffers();
initBufferValues();
initParameters();
}
void swapBuffers()
{
//tutaj zamien bufory ze soba
var temp = vegetation;
vegetation = oldVegetation;
oldVegetation = temp;
computeShader.SetBuffer(0, "vegetation", vegetation);
computeShader.SetBuffer(0, "oldVegetation", oldVegetation);
}
void doSimulationSteps(int steps)
{
//tutaj wykonaj kroki symulacji
for (int i = 0; i < steps; i++)
{
computeShader.Dispatch(0, sizeX, sizeY, 1);
}
}
void recoverData()
{
//tutaj odczytaj bufor i przeslij wynik jako mapa detali
var result = new float[sizeX * sizeY];
vegetation.GetData(result);
int[,] detailLayer = new int[sizeX, sizeY];
for (int i = 0; i < sizeX; i++)
{
for (int j = 0; j < sizeX; j++)
{
detailLayer[i, j] = Mathf.FloorToInt(result[i + j * sizeX] * 10);
}
}
terrain.terrainData.SetDetailLayer(0, 0, 1, detailLayer);
}
// Update is called once per frame
void Update()
{
if (doUpdate())
{
terrain = gameObject.GetComponent<Terrain>();
initParameters();
doSimulationSteps(stepsNumber);
recoverData();
}
}
}