attempt to impl infinite water

This commit is contained in:
in0finite 2021-08-01 17:02:50 +02:00
parent 946690f154
commit 04be0ad46c
2 changed files with 89 additions and 7 deletions

View file

@ -91,6 +91,8 @@ namespace SanAndreasUnity.Behaviours.World
}
}
public int WorldSize { get; } = 6000;
public float[] drawDistancesPerLayers = new float[] { 301, 801, 1501 };
private WorldSystemWithDistanceLevels<MapObject> _worldSystem;
@ -143,11 +145,9 @@ namespace SanAndreasUnity.Behaviours.World
UnityEngine.Debug.Log("Num static geometries " + m_insts.Count);
uint worldSize = 6000;
_worldSystem = new WorldSystemWithDistanceLevels<MapObject>(
this.drawDistancesPerLayers,
this.xzWorldSystemNumAreasPerDrawDistanceLevel.Select(_ => new WorldSystemParams { worldSize = worldSize, numAreasPerAxis = _ }).ToArray(),
this.xzWorldSystemNumAreasPerDrawDistanceLevel.Select(_ => new WorldSystemParams { worldSize = (uint) this.WorldSize, numAreasPerAxis = _ }).ToArray(),
Enumerable.Range(0, this.drawDistancesPerLayers.Length).Select(_ => new WorldSystemParams { worldSize = this.yWorldSystemSize, numAreasPerAxis = this.yWorldSystemNumAreas }).ToArray(),
this.OnAreaChangedVisibility);
}
@ -196,7 +196,9 @@ namespace SanAndreasUnity.Behaviours.World
if (Water != null)
{
Water.Initialize(new WaterFile(Importing.Archive.ArchiveManager.PathToCaseSensitivePath(Config.GetPath("water_path"))));
Water.Initialize(
new WaterFile(Importing.Archive.ArchiveManager.PathToCaseSensitivePath(Config.GetPath("water_path"))),
Vector2.one * this.WorldSize);
}
}

View file

@ -10,7 +10,7 @@ namespace SanAndreasUnity.Behaviours.World
public GameObject WaterPrefab;
public void Initialize(WaterFile file)
public void Initialize(WaterFile file, Vector2 worldSize)
{
if (this.WaterPrefab == null)
{
@ -22,8 +22,16 @@ namespace SanAndreasUnity.Behaviours.World
var faces = file.Faces.Where(f => (f.Flags & WaterFlags.Visible) == WaterFlags.Visible);
int totalNumVertexes = faces.Sum(f => f.Vertices.Length);
int totalNumIndexes = faces.Sum(f => (f.Vertices.Length - 2) * 3);
// we need total of 4 quads for "infinite" water:
// - upper side (from upper world boundary to positive infinity)
// - lower side (from lower world boundary to negative infinity)
// - left side (between first 2 quads)
// - right side (between first 2 quads)
const int numQuadsForInfiniteWater = 4;
int totalNumVertexes = faces.Sum(f => f.Vertices.Length) + numQuadsForInfiniteWater * GetNumVertexesForQuad();
int totalNumIndexes = faces.Sum(f => (f.Vertices.Length - 2) * 3) + numQuadsForInfiniteWater * GetNumIndexesForQuad();
Vector3[] vertices = new Vector3[totalNumVertexes];
Vector3[] normals = new Vector3[totalNumVertexes];
@ -52,6 +60,46 @@ namespace SanAndreasUnity.Behaviours.World
indicesIndex += (face.Vertices.Length - 2) * 3;
}
// add "infinite" water
const float infiniteWaterOffset = 20000f;
// upper quad
CreateQuad(
new Vector2( -worldSize.x / 2f - infiniteWaterOffset, worldSize.y / 2f),
new Vector2(worldSize.x / 2f + infiniteWaterOffset, worldSize.y / 2f + infiniteWaterOffset),
vertices,
normals,
ref verticesIndex,
indices,
ref indicesIndex);
// lower quad
CreateQuad(
new Vector2( -worldSize.x / 2f - infiniteWaterOffset, - worldSize.y / 2f - infiniteWaterOffset),
new Vector2(worldSize.x / 2f + infiniteWaterOffset, - worldSize.y / 2f),
vertices,
normals,
ref verticesIndex,
indices,
ref indicesIndex);
// left quad
CreateQuad(
new Vector2( -worldSize.x / 2f - infiniteWaterOffset, - worldSize.y / 2f),
new Vector2(- worldSize.x / 2f, worldSize.y / 2f),
vertices,
normals,
ref verticesIndex,
indices,
ref indicesIndex);
// right quad
CreateQuad(
new Vector2( worldSize.x / 2f, - worldSize.y / 2f),
new Vector2(worldSize.x / 2f + infiniteWaterOffset, worldSize.y / 2f),
vertices,
normals,
ref verticesIndex,
indices,
ref indicesIndex);
var mesh = new Mesh();
mesh.vertices = vertices;
@ -66,5 +114,37 @@ namespace SanAndreasUnity.Behaviours.World
go.GetComponent<MeshFilter>().sharedMesh = mesh;
}
void CreateQuad(Vector2 min, Vector2 max, Vector3[] vertexes, Vector3[] normals, ref int vertexIndex, int[] indexes, ref int indexesIndex)
{
vertexes[vertexIndex++] = new Vector3(min.x, 0f, min.y); // low left
vertexes[vertexIndex++] = new Vector3(max.x, 0f, min.y); // low right
vertexes[vertexIndex++] = new Vector3(min.x, 0f, max.y); // up left
vertexes[vertexIndex++] = new Vector3(max.x, 0f, max.y); // up right
normals[vertexIndex - 4] = Vector3.up;
normals[vertexIndex - 3] = Vector3.up;
normals[vertexIndex - 2] = Vector3.up;
normals[vertexIndex - 1] = Vector3.up;
// triangle 1: low left, low right, up right
// triangle 2: low left, up right, up left
int lowLeft = vertexIndex - 4;
int lowRight = vertexIndex - 3;
int upLeft = vertexIndex - 2;
int upRight = vertexIndex - 1;
indexes[indexesIndex++] = lowLeft;
indexes[indexesIndex++] = lowRight;
indexes[indexesIndex++] = upRight;
indexes[indexesIndex++] = lowLeft;
indexes[indexesIndex++] = upRight;
indexes[indexesIndex++] = upLeft;
}
int GetNumVertexesForQuad() => 4;
int GetNumIndexesForQuad() => 6;
}
}