ZMWSLI0-SL2021-GR11/Projekt/MWSProjekt/Assets/Scripts/Environment.cs

303 lines
12 KiB
C#

using System.Collections.Generic;
using UnityEngine;
public class Environment : MonoBehaviour
{
public int sizeX = 100;
public int sizeY = 100;
public int sizeZ = 100;
public float voxelSize = 0.1f;
public bool visualizeLigth = true;
public int visualizeEveryNVoxel = 100;
// Voxel[,,] voxelSpace;
byte[,,] voxelSpace;
public bool rotateTowardsLight = false;
public bool sendShadowToLSystem = true;
public bool cutBranchesWithMaxShadow = false;
List<List<Matrix4x4>> transformListJ;
// Start is called before the first frame update
public void Reset()
{
Start();
}
void Start()
{
voxelSpace = new byte[sizeX, sizeY, sizeZ];
for (int i = 0; i < sizeX; i++)
{
for (int k = 0; k < sizeZ; k++)
{
for (int j = sizeY - 1; j >= 0; j--)
{
voxelSpace[i, j, k] = (byte)1;
if (i == 0 || i == sizeX - 1 || k == 0 || k == sizeZ - 1)
{
voxelSpace[i, j, k] = (byte)255;
}
}
}
}
List<Matrix4x4> transformList = new List<Matrix4x4>();
transformListJ = new List<List<Matrix4x4>>();
for (int i = 0; i < sizeX; i++)
{
for (int k = 0; k < sizeZ; k++)
{
for (int j = sizeY - 1; j >= 0; j--)
{
if (visualizeLigth &&
(i % visualizeEveryNVoxel == 0 && j % visualizeEveryNVoxel == 0 && k % visualizeEveryNVoxel == 0))
{
Vector3 position = gameObject.GetComponent<Transform>().position;
Matrix4x4 matrixLigth = new Matrix4x4();
//Take the origin position, and apply the offsets
position.x += i * voxelSize;
position.y += j * voxelSize;
position.z += k * voxelSize;
//Create a matrix for the position created from this iteration of the loop
//Set the position/rotation/scale for this matrix
if (voxelSpace[i, j, k] != null)
{
matrixLigth.SetTRS(position, Quaternion.Euler(Vector3.zero), new Vector3(voxelSpace[i, j, k] * voxelSize * visualizeEveryNVoxel / 255.0f, voxelSpace[i, j, k] * voxelSize * visualizeEveryNVoxel / 255.0f, voxelSpace[i, j, k] * voxelSize * visualizeEveryNVoxel / 255.0f));
}
else
{
matrixLigth.SetTRS(position, Quaternion.Euler(Vector3.zero), new Vector3(0, 0, 0));
}
transformList.Add(matrixLigth);
}
if (transformList.Count > 1020)
{
transformListJ.Add(transformList);
transformList = new List<Matrix4x4>();
}
}
}
}
if (transformList.Count > 0)
{
transformListJ.Add(transformList);
transformList = new List<Matrix4x4>();
}
}
// Update is called once per frame
int frame = 0;
void Update()
{
if (frame % 300 == 0)
{
int mxx = 0;
Vector3 pos = new Vector3(0, 0, 0);
for (int j = sizeY - 1; j >= 0; j--)
{
for (int i = 0; i < sizeX; i++)
{
for (int k = 0; k < sizeZ; k++)
{
if (voxelSpace[i, j, k] > mxx)
{
mxx = voxelSpace[i, j, k];
pos = new Vector3(i, j, k);
// Debug.Log("mxPos = "+mxx+" "+pos);
}
}
}
}
}
frame += 1;
// Debug.Log("frame"+frame);
}
public void addShadowPoint(Vector3 position, sbyte strength) // negative value to remove
{
Vector3 voxelPosition = positionInVoxel(position);
Debug.Log(voxelPosition + " adding " + strength);
if (inVoxelSpace((int)voxelPosition.x, (int)voxelPosition.y, (int)voxelPosition.z))
{
voxelSpace[(int)voxelPosition.x, (int)voxelPosition.y, (int)voxelPosition.z] += (byte)strength;
}
else
{
Debug.Log("not in vexel space: " + voxelPosition + " - error adding");
}
}
public void removeShadow(Vector3 position, sbyte strength) // negative value to remove
{
addShadow(position, (sbyte)-strength);
}
public void addShadow(Vector3 position, sbyte strength) // negative value to remove
{
// 6.2 / 0.1 = 62.0
Vector3 voxelPosition = positionInVoxel(position);
for (int j = (int)voxelPosition.y; j >= 0; j--)
{
if (voxelPosition.y - j > 250)
{
break;
}
int rotj = (int)(voxelPosition.y - j) * 1;
for (int i = (int)voxelPosition.x - rotj; i <= (int)voxelPosition.x + rotj; i++)
{
for (int k = (int)voxelPosition.z - rotj; k <= (int)voxelPosition.z + rotj; k++)
{
if (inVoxelSpace(i, j, k) &&
(i % visualizeEveryNVoxel == 0 && j % visualizeEveryNVoxel == 0 && k % visualizeEveryNVoxel == 0))
{
float secondaryStrength = 1.0f * strength;
secondaryStrength = secondaryStrength / ((Mathf.Abs(k - (int)voxelPosition.z) + 1 + Mathf.Abs(i - (int)voxelPosition.x)) / 8.0f);
if (voxelSpace[i, j, k] == null)
{
voxelSpace[i, j, k] = 0;
}
if (secondaryStrength > 0)
{
if (voxelSpace[i, j, k] >= 255 - (byte)secondaryStrength)
{
voxelSpace[i, j, k] = 255;
}
else
{
voxelSpace[i, j, k] += (byte)secondaryStrength;
}
}
else
{
if (voxelSpace[i, j, k] > (byte)secondaryStrength)
{
voxelSpace[i, j, k] -= (byte)(-1 * secondaryStrength);
}
else
{
voxelSpace[i, j, k] = 1;
}
}
if ((i % visualizeEveryNVoxel == 0 && j % visualizeEveryNVoxel == 0 && k % visualizeEveryNVoxel == 0) && visualizeLigth)
{
Vector3 positionBox = gameObject.GetComponent<Transform>().position;
Matrix4x4 matrixLigth = new Matrix4x4();
//Take the origin position, and apply the offsets
positionBox.x += i * voxelSize;
positionBox.y += j * voxelSize;
positionBox.z += k * voxelSize;
//Create a matrix for the position created from this iteration of the loop
//Set the position/rotation/scale for this matrix
matrixLigth.SetTRS(positionBox, Quaternion.Euler(Vector3.zero), new Vector3(voxelSpace[i, j, k] * voxelSize * visualizeEveryNVoxel / 255.0f, voxelSpace[i, j, k] * voxelSize * visualizeEveryNVoxel / 255.0f, voxelSpace[i, j, k] * voxelSize * visualizeEveryNVoxel / 255.0f));
int l = (i * sizeZ * sizeY / (visualizeEveryNVoxel * visualizeEveryNVoxel * visualizeEveryNVoxel) + k * sizeY / (visualizeEveryNVoxel * visualizeEveryNVoxel) + j / visualizeEveryNVoxel);
transformListJ[l / 1021][l % 1021] = matrixLigth;
}
}
}
}
}
}
public void addShadowLine(Vector3 positionStart, Vector3 positionEnd, sbyte strength) // negative value to remove
{
int linePoints = (int)((Mathf.Abs(positionEnd.x - positionStart.x) + Mathf.Abs(positionEnd.z - positionStart.z)) / (voxelSize));
if (linePoints < 3)
{
linePoints = 3;
}
Vector3 stepChange = new Vector3(
(positionEnd.x - positionStart.x) / linePoints,
(positionEnd.y - positionStart.y) / linePoints,
(positionEnd.z - positionStart.z) / linePoints);
Vector3 positionNow = positionStart;
sbyte newStrength = (sbyte)(2 * (strength / linePoints));
if (newStrength == 0)
{
if (strength > 0)
{
if (strength > 0.4f)
newStrength = (sbyte)1;
}
if (strength < 0)
{
newStrength = (sbyte)-1;
}
}
for (int i = 0; i < linePoints; i++)
{
addShadow(positionNow, newStrength);
positionNow += stepChange;
}
}
bool inVoxelSpace(int a, int b, int c)
{
return (a < sizeX && a >= 0 && b < sizeY && b >= 0 && c < sizeZ && c >= 0);
}
public Vector3 positionInVoxel(Vector3 positionInWorld)
{
Vector3 voxelPosition = new Vector3(0.0f, 0.0f, 0.0f);
positionInWorld -= gameObject.GetComponent<Transform>().position;
voxelPosition.x = (int)(0.5f + (positionInWorld.x / voxelSize));
voxelPosition.y = (int)(0.5f + (positionInWorld.y / voxelSize));
voxelPosition.z = (int)(0.5f + (positionInWorld.z / voxelSize));
return voxelPosition;
}
public Vector3 positionInWorld(Vector3 positionInVoxel)
{
return positionInVoxel * voxelSize + gameObject.GetComponent<Transform>().position;
}
public void groundShape()
{
for (int i = 0; i < sizeX; i++)
{
for (int k = 0; k < sizeZ; k++)
{
for (int j = sizeY - 1; j >= 0; j--)
{
Collider[] hitColliders = Physics.OverlapSphere(new Vector3(i * voxelSize, j * voxelSize, k * voxelSize), voxelSize / 2.0f);
foreach (var hitCollider in hitColliders)
{
addShadow(new Vector3(i * voxelSize, j * voxelSize, k * voxelSize), 100);
}
}
}
}
}
public byte shadowStrength(Vector3 pos)
{
Vector3 shadowPosition = positionInVoxel(pos);//pos - gameObject.GetComponent<Transform>().position;
if (inVoxelSpace((int)((shadowPosition.x)), (int)((shadowPosition.y)), (int)((shadowPosition.z))))
{
byte mx = voxelSpace[0 + (int)((shadowPosition.x)), (int)((shadowPosition.y)), 0 + (int)((shadowPosition.z))];
return mx;
}
return 255;
}
public bool isShadow(Vector3 pos)
{
if (shadowStrength(pos) > 10)
{
// Debug.Log("#shadow");
return true;
}
else
{
return false;
}
}
}