Compare commits

...

8 Commits

Author SHA1 Message Date
Jonas Weinz 43c31d59f0 fixed bug in chunk caching 2019-01-15 11:49:30 +01:00
Jonas Weinz 4b93ca2c4d bugfix 2019-01-06 21:45:16 +01:00
Jonas Weinz 03f5fbcb6a updated scene 2019-01-06 21:38:59 +01:00
Jonas Weinz fb6b622ed7 bugfices 2019-01-06 21:11:45 +01:00
Jonas Weinz 3fa38762d5 crazy updates 2019-01-06 20:15:26 +01:00
Jonas Weinz 4f8bd555d9 created chankData class 2019-01-06 14:17:13 +01:00
Jonas Weinz 5614574261 better chunk border management 2019-01-06 13:50:11 +01:00
Jonas Weinz 3b031e825e inefficient and incomplete neighbor handling 2019-01-06 12:42:56 +01:00
5 changed files with 1141 additions and 284 deletions

View File

@ -153,15 +153,15 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: a5f06ccd15360461ea85cd374d1c8a29, type: 3}
m_Name:
m_EditorClassIdentifier:
min_range: {x: 6, y: 3, z: 6}
max_range: {x: 16, y: 16, z: 16}
min_range: {x: 5, y: 3, z: 5}
max_range: {x: 9, y: 16, z: 9}
cache_range: {x: 48, y: 48, z: 48}
server_host: 127.0.0.1
server_port: 5050
chunkPrefab: {fileID: 114418011670574046, guid: ef7e3e7be15a440f4ab23c93edf6b0fd,
type: 2}
max_geometry_updates_per_frame: 15
n_chunk_build_threads: 3
max_geometry_updates_per_frame: 10
n_chunk_build_threads: 4
position_reference: {fileID: 1846517683}
--- !u!1 &1237971281
GameObject:
@ -301,7 +301,7 @@ Transform:
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1846517680}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalPosition: {x: 256, y: 1, z: 256}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}

View File

@ -4,7 +4,7 @@ using UnityEngine;
public class Chunk : MonoBehaviour {
public enum Direction {x_neg, y_neg, z_neg, x_pos, y_pos, z_pos};
// rawData:
public const int N_CHUNK_SIDELENGTH = 16; // FIXME: bad naming
@ -12,28 +12,45 @@ public class Chunk : MonoBehaviour {
public const int N_CHUNK_SIDELENGTH_SQRD = 256; //16 * 16
public const int N_CHUNK_BLOCKS=4096; //16*16*16
private int[] data = new int[N_CHUNK_BLOCKS];
public ChunkData chunk_data = null;
protected MeshFilter meshFilter;
protected MeshFilter meshFilter;
protected List<Vector3> all_vertices;
protected List<int> all_tris;
protected List<Vector3> all_normals;
protected List<Color> all_colors;
protected List<Vector3> vertices;
protected List<int> tris;
protected List<Vector3> normals;
protected List<Color> colors;
protected List<Vector3> inner_vertices;
protected List<int> inner_tris;
protected List<Vector3> inner_normals;
protected List<Color> inner_colors;
// data for the border area:
protected List<Vector3>[] border_vertices;
protected List<int>[] border_tris;
protected List<Vector3>[] border_normals;
protected List<Color>[] border_colors;
protected object border_handle = new object();
public object borderHandle
{
get{
return border_handle;
}
}
protected int[] chunk_position = new int[3] {0,0,0};
protected Vector3Int chunk_position_vec;
public int[] ChunkPosition
{
get
{
return chunk_position;
return chunk_data.ChunkPosition;
}
set
{
chunk_position = value;
chunk_position_vec = new Vector3Int(value[0], value[1], value[2]);
chunk_data.ChunkPosition = value;
}
}
@ -41,22 +58,11 @@ public class Chunk : MonoBehaviour {
{
get
{
return chunk_position_vec;
return chunk_data.ChunkPositionVec;
}
set
{
chunk_position_vec = value;
chunk_position = new int[3] {value.x, value.y, value.z};
}
}
protected Chunk[] neighbor_chunks = new Chunk[6];
public Chunk[] NeighborChunks
{
get
{
return neighbor_chunks;
chunk_data.ChunkPositionVec = value;
}
}
@ -64,20 +70,22 @@ public class Chunk : MonoBehaviour {
{
get
{
return data;
return chunk_data.Data;
}
set
{
data = value;
}
}
public void ConnectChunk(Chunk chunk, Direction direction)
public void DeleteBorderVertices(ChunkData.Direction dir)
{
neighbor_chunks[(int) direction] = chunk;
chunk.neighbor_chunks[((int) direction + 3) % 6] = this;
int d = (int)dir;
lock(border_handle)
{
border_vertices[d] = null;
border_tris[d] = null;
border_normals[d] = null;
border_colors[d] = null;
}
}
void Awake()
@ -86,10 +94,28 @@ public class Chunk : MonoBehaviour {
meshFilter.mesh.MarkDynamic();
vertices = new List<Vector3>();
tris = new List<int>();
normals = new List<Vector3>();
colors = new List<Color>();
all_vertices = new List<Vector3>();
all_tris = new List<int>();
all_normals = new List<Vector3>();
all_colors = new List<Color>();
inner_vertices = new List<Vector3>();
inner_tris = new List<int>();
inner_normals = new List<Vector3>();
inner_colors = new List<Color>();
border_vertices = new List<Vector3>[6];
border_tris = new List<int>[6];
border_normals = new List<Vector3>[6];
border_colors = new List<Color>[6];
for (int i = 0; i < 6; i++)
{
border_vertices[i] = null;
border_tris[i] = null;
border_normals[i] = null;
border_colors[i] = null;
}
}
@ -98,21 +124,6 @@ public class Chunk : MonoBehaviour {
}
public void SetDataFromMessageObject(MessageObject mo)
{
if (mo.data == null)
{
throw new System.Exception("received empty data block");
}
if (mo.data.Length != 4096)
{
throw new System.Exception("bad data received");
}
Data = mo.data;
}
public void Index2Coords(int i, int[] coords)
{
@ -128,10 +139,16 @@ public class Chunk : MonoBehaviour {
protected Color CalculateColor(int[] coords)
{
return Color.blue + (((float)coords[1] + chunk_position[1] * N_CHUNK_SIDELENGTH) / (float)WorldManager.Instance.WorldHeight) * (Color.green - Color.blue);
return Color.blue + (((float)coords[1] + chunk_data.ChunkPosition[1] * N_CHUNK_SIDELENGTH) / (float)WorldManager.Instance.WorldHeight) * (Color.green - Color.blue);
}
protected void AddPlane(Vector3 normal, Vector3 pos, Color color)
protected void AddPlane(Vector3 normal,
Vector3 pos,
Color color,
List<Vector3> verts,
List<int> tris,
List<Vector3> normals,
List<Color> colors)
{
/*
@ -185,12 +202,12 @@ normal a |
c += pos;
d += pos;
int n = vertices.Count;
int n = verts.Count;
vertices.Add(a);
vertices.Add(half_normal > 0 ? d : b); // forcing clockwise built triangles
vertices.Add(c);
vertices.Add(half_normal > 0 ? b : d);
verts.Add(a);
verts.Add(half_normal > 0 ? d : b); // forcing clockwise built triangles
verts.Add(c);
verts.Add(half_normal > 0 ? b : d);
tris.Add(n + 0);
tris.Add(n + 1);
@ -212,13 +229,13 @@ normal a |
}
// Build the chunk mesh from ground up
public void BuildMesh()
public void BuildInnerMesh()
{
vertices.Clear();
tris.Clear();
normals.Clear();
colors.Clear();
inner_vertices.Clear();
inner_tris.Clear();
inner_normals.Clear();
inner_colors.Clear();
int i = 0;
int[] pos = new int[3];
@ -247,23 +264,17 @@ normal a |
k = Coords2Index(pos_buffer);
if (Data[k] != 0)
{
AddPlane(Vector3.right, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
AddPlane(Vector3.right,
new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]),
CalculateColor(pos_buffer),
inner_vertices,
inner_tris,
inner_normals,
inner_colors);
}
pos_buffer[0] += 1;
}
else if (neighbor_chunks[(int)Direction.x_neg])
{
//wraparound
pos_buffer[0] = N_CHUNK_SIDELENGTH - 1;
k = Coords2Index(pos_buffer);
pos_buffer[0] = -1;
if (neighbor_chunks[(int) Direction.x_neg].Data[k] != 0)
{
AddPlane(Vector3.right, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
}
pos_buffer[0] = 0;
}
if (pos[0] + 1 < N_CHUNK_SIDELENGTH)
{
@ -271,23 +282,16 @@ normal a |
k = Coords2Index(pos_buffer);
if (Data[k] != 0)
{
AddPlane(Vector3.left, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
AddPlane(Vector3.left,
new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]),
CalculateColor(pos_buffer),
inner_vertices,
inner_tris,
inner_normals,
inner_colors);
}
pos_buffer[0] -= 1;
}
else if (neighbor_chunks[(int)Direction.x_pos])
{
//wraparound
pos_buffer[0] = 0;
k = Coords2Index(pos_buffer);
pos_buffer[0] = N_CHUNK_SIDELENGTH;
if (neighbor_chunks[(int) Direction.x_pos].Data[k] != 0)
{
AddPlane(Vector3.left, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
}
pos_buffer[0] = N_CHUNK_SIDELENGTH - 1;
}
// y axis
if (pos[1] > 0)
@ -296,23 +300,16 @@ normal a |
k = Coords2Index(pos_buffer);
if (Data[k] != 0)
{
AddPlane(Vector3.up, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
AddPlane(Vector3.up,
new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]),
CalculateColor(pos_buffer),
inner_vertices,
inner_tris,
inner_normals,
inner_colors);
}
pos_buffer[1] += 1;
}
else if (neighbor_chunks[(int)Direction.y_neg])
{
//wraparound
pos_buffer[1] = N_CHUNK_SIDELENGTH - 1;
k = Coords2Index(pos_buffer);
pos_buffer[1] = -1;
if (neighbor_chunks[(int) Direction.y_neg].Data[k] != 0)
{
AddPlane(Vector3.up, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
}
pos_buffer[1] = 0;
}
if (pos[1] + 1 < N_CHUNK_SIDELENGTH)
@ -321,22 +318,16 @@ normal a |
k = Coords2Index(pos_buffer);
if (Data[k] != 0)
{
AddPlane(Vector3.down, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
AddPlane(Vector3.down,
new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]),
CalculateColor(pos_buffer),
inner_vertices,
inner_tris,
inner_normals,
inner_colors);
}
pos_buffer[1] -= 1;
}
else if (neighbor_chunks[(int)Direction.y_pos])
{
//wraparound
pos_buffer[1] = 0;
k = Coords2Index(pos_buffer);
pos_buffer[1] = N_CHUNK_SIDELENGTH;
if (neighbor_chunks[(int) Direction.y_pos].Data[k] != 0)
{
AddPlane(Vector3.down, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
}
pos_buffer[1] = N_CHUNK_SIDELENGTH - 1;
}
// z axis
if (pos[2] > 0)
@ -345,23 +336,17 @@ normal a |
k = Coords2Index(pos_buffer);
if (Data[k] != 0)
{
AddPlane(Vector3.forward, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
AddPlane(Vector3.forward,
new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]),
CalculateColor(pos_buffer),
inner_vertices,
inner_tris,
inner_normals,
inner_colors);
}
pos_buffer[2] += 1;
}
else if (neighbor_chunks[(int)Direction.z_neg])
{
//wraparound
pos_buffer[2] = N_CHUNK_SIDELENGTH - 1;
k = Coords2Index(pos_buffer);
pos_buffer[2] = -1;
if (neighbor_chunks[(int) Direction.z_neg].Data[k] != 0)
{
AddPlane(Vector3.forward, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
}
pos_buffer[2] = 0;
}
if (pos[2] + 1 < N_CHUNK_SIDELENGTH)
{
@ -369,22 +354,16 @@ normal a |
k = Coords2Index(pos_buffer);
if (Data[k] != 0)
{
AddPlane(Vector3.back, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
AddPlane(Vector3.back,
new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]),
CalculateColor(pos_buffer),
inner_vertices,
inner_tris,
inner_normals,
inner_colors);
}
pos_buffer[2] -= 1;
}
else if (neighbor_chunks[(int)Direction.z_pos])
{
//wraparound
pos_buffer[2] = 0;
k = Coords2Index(pos_buffer);
pos_buffer[2] = N_CHUNK_SIDELENGTH;
if (neighbor_chunks[(int) Direction.z_pos].Data[k] != 0)
{
AddPlane(Vector3.back, new Vector3(pos_buffer[0], pos_buffer[1], pos_buffer[2]), CalculateColor(pos_buffer));
}
pos_buffer[2] = N_CHUNK_SIDELENGTH - 1;
}
}
i += 1;
@ -394,16 +373,278 @@ normal a |
}
}
public void BuildBorderGeometry(ChunkData.Direction dir)
{
if (chunk_data.Neighbors[(int)dir] == null)
{
Debug.LogWarning("tried to build geometry from non existing chunk: " + (chunk_data.ChunkPositionVec + ChunkData.DirectionNormalsInt[(int)dir]).ToString());
return;
}
// depending on direction iterate throug different dimensions
int d = (int) dir;
int op_d = (d + 3) % 6;
int[] pos = new int[3];
int neighbor_index;
int index;
lock(border_handle)
{
border_vertices[d] = new List<Vector3>();
border_tris[d] = new List<int>();
border_normals[d] = new List<Vector3>();
border_colors[d] = new List<Color>();
// X
if (dir == ChunkData.Direction.x_neg)
{
for (int y = 0; y < N_CHUNK_SIDELENGTH; y++)
{
for (int z = 0; z < N_CHUNK_SIDELENGTH; z++)
{
pos[0] = N_CHUNK_SIDELENGTH - 1;
pos[1] = y;
pos[2] = z;
neighbor_index = Coords2Index(pos);
pos[0] = 0;
index = Coords2Index(pos);
pos[0] = -1;
if (chunk_data.Neighbors[d].Data[neighbor_index] != 0 && Data[index] == 0)
{
AddPlane(ChunkData.DirectionNormals[op_d],
new Vector3(pos[0], pos[1], pos[2]),
CalculateColor(pos),
border_vertices[d],
border_tris[d],
border_normals[d],
border_colors[d]);
}
}
}
}
else if (dir == ChunkData.Direction.x_pos)
{
for (int y = 0; y < N_CHUNK_SIDELENGTH; y++)
{
for (int z = 0; z < N_CHUNK_SIDELENGTH; z++)
{
pos[0] = 0;
pos[1] = y;
pos[2] = z;
neighbor_index = Coords2Index(pos);
pos[0] = N_CHUNK_SIDELENGTH - 1;
index = Coords2Index(pos);
pos[0] = N_CHUNK_SIDELENGTH;
if (chunk_data.Neighbors[d].Data[neighbor_index] != 0 && Data[index] == 0)
{
AddPlane(ChunkData.DirectionNormals[op_d],
new Vector3(pos[0], pos[1], pos[2]),
CalculateColor(pos),
border_vertices[d],
border_tris[d],
border_normals[d],
border_colors[d]);
}
}
}
}
// Y
else if (dir == ChunkData.Direction.y_neg)
{
for (int x = 0; x < N_CHUNK_SIDELENGTH; x++)
{
for (int z = 0; z < N_CHUNK_SIDELENGTH; z++)
{
pos[0] = x;
pos[1] = N_CHUNK_SIDELENGTH - 1;
pos[2] = z;
neighbor_index = Coords2Index(pos);
pos[1] = 0;
index = Coords2Index(pos);
pos[1] = -1;
if (chunk_data.Neighbors[d].Data[neighbor_index] != 0 && Data[index] == 0)
{
AddPlane(ChunkData.DirectionNormals[op_d],
new Vector3(pos[0], pos[1], pos[2]),
CalculateColor(pos),
border_vertices[d],
border_tris[d],
border_normals[d],
border_colors[d]);
}
}
}
}
else if (dir == ChunkData.Direction.y_pos)
{
for (int x = 0; x < N_CHUNK_SIDELENGTH; x++)
{
for (int z = 0; z < N_CHUNK_SIDELENGTH; z++)
{
pos[0] = x;
pos[1] = 0;
pos[2] = z;
neighbor_index = Coords2Index(pos);
pos[1] = N_CHUNK_SIDELENGTH - 1;
index = Coords2Index(pos);
pos[1] = N_CHUNK_SIDELENGTH;
if (chunk_data.Neighbors[d].Data[neighbor_index] != 0 && Data[index] == 0)
{
AddPlane(ChunkData.DirectionNormals[op_d],
new Vector3(pos[0], pos[1], pos[2]),
CalculateColor(pos),
border_vertices[d],
border_tris[d],
border_normals[d],
border_colors[d]);
}
}
}
}
// Z
else if (dir == ChunkData.Direction.z_neg)
{
for (int x = 0; x < N_CHUNK_SIDELENGTH; x++)
{
for (int y = 0; y < N_CHUNK_SIDELENGTH; y++)
{
pos[0] = x;
pos[1] = y;
pos[2] = N_CHUNK_SIDELENGTH - 1;
neighbor_index = Coords2Index(pos);
pos[2] = 0;
index = Coords2Index(pos);
pos[2] = -1;
if (chunk_data.Neighbors[d].Data[neighbor_index] != 0 && Data[index] == 0)
{
AddPlane(ChunkData.DirectionNormals[op_d],
new Vector3(pos[0], pos[1], pos[2]),
CalculateColor(pos),
border_vertices[d],
border_tris[d],
border_normals[d],
border_colors[d]);
}
}
}
}
else if (dir == ChunkData.Direction.z_pos)
{
for (int x = 0; x < N_CHUNK_SIDELENGTH; x++)
{
for (int y = 0; y < N_CHUNK_SIDELENGTH; y++)
{
pos[0] = x;
pos[1] = y;
pos[2] = 0;
neighbor_index = Coords2Index(pos);
pos[2] = N_CHUNK_SIDELENGTH - 1;
index = Coords2Index(pos);
pos[2] = N_CHUNK_SIDELENGTH;
if (chunk_data.Neighbors[d].Data[neighbor_index] != 0 && Data[index] == 0)
{
AddPlane(ChunkData.DirectionNormals[op_d],
new Vector3(pos[0], pos[1], pos[2]),
CalculateColor(pos),
border_vertices[d],
border_tris[d],
border_normals[d],
border_colors[d]);
}
}
}
}
}
}
public void ConcatenateGeometry()
{
int n_inner = inner_vertices.Count;
all_vertices = new List<Vector3>(inner_vertices);
all_tris = new List<int>(inner_tris);
all_normals = new List<Vector3>(inner_normals);
all_colors = new List<Color>(inner_colors);
int c_verts = n_inner;
int c_tris = inner_tris.Count;
lock (border_handle)
{
//get vertices count of border areas:
for (int i = 0; i < 6; i++)
{
if (border_vertices[i] != null)
{
all_vertices.AddRange(border_vertices[i]);
all_tris.AddRange(border_tris[i]);
all_normals.AddRange(border_normals[i]);
all_colors.AddRange(border_colors[i]);
// correct triangle indices
for (int tri_i = c_tris; tri_i < c_tris + border_tris[i].Count; tri_i++)
{
all_tris[tri_i] += c_verts;
}
c_tris += border_tris[i].Count;
c_verts += border_vertices[i].Count;
}
}
}
}
public void AssignMesh()
{
meshFilter.mesh.Clear();
meshFilter.mesh.vertices = vertices.ToArray();
meshFilter.mesh.triangles = tris.ToArray();
meshFilter.mesh.normals = normals.ToArray();
meshFilter.mesh.colors = colors.ToArray();
meshFilter.mesh.vertices = all_vertices.ToArray();
meshFilter.mesh.triangles = all_tris.ToArray();
meshFilter.mesh.normals = all_normals.ToArray();
meshFilter.mesh.colors = all_colors.ToArray();
}
// Update is called once per frame
void OnDestroy()
{
// Disconnect from all neighbors
chunk_data.DisconnectChunkData(ChunkData.Direction.x_neg);
chunk_data.DisconnectChunkData(ChunkData.Direction.y_neg);
chunk_data.DisconnectChunkData(ChunkData.Direction.z_neg);
chunk_data.DisconnectChunkData(ChunkData.Direction.x_pos);
chunk_data.DisconnectChunkData(ChunkData.Direction.y_pos);
chunk_data.DisconnectChunkData(ChunkData.Direction.z_pos);
}
// Update is called once per frame
void Update () {
//Pulse();
}

440
Assets/Scripts/ChunkData.cs Normal file
View File

@ -0,0 +1,440 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChunkData {
public enum ChunkGeometryType
{
Unknown,
Mixed,
Full,
Empty
};
public enum Direction {x_neg, y_neg, z_neg, x_pos, y_pos, z_pos};
protected static Vector3Int[] direction_normals_int = new Vector3Int[] {Vector3Int.left,
Vector3Int.down,
new Vector3Int(0,0,-1),
Vector3Int.right,
Vector3Int.up,
new Vector3Int(0,0,1)};
protected static Vector3[] direction_normals = new Vector3[] {Vector3.left,
Vector3.down,
new Vector3(0,0,-1),
Vector3.right,
Vector3.up,
new Vector3(0,0,1)};
public static Vector3Int[] DirectionNormalsInt
{
get
{
return direction_normals_int;
}
}
public static Vector3[] DirectionNormals
{
get
{
return direction_normals;
}
}
public const int N_CHUNK_SIDELENGTH = 16; // FIXME: bad naming
public const int N_CHUNK_SIDELENGTH_SQRD = 256; //16 * 16
public const int N_CHUNK_BLOCKS=4096; //16*16*16
private int[] data = new int[N_CHUNK_BLOCKS];
private ChunkGeometryType m_chunk_geometry_type = ChunkGeometryType.Unknown;
private ChunkGeometryType[] m_chunk_geometry_type_borders = new ChunkGeometryType[] {ChunkGeometryType.Unknown,
ChunkGeometryType.Unknown,
ChunkGeometryType.Unknown,
ChunkGeometryType.Unknown,
ChunkGeometryType.Unknown,
ChunkGeometryType.Unknown};
private bool m_is_built_necessary = false;
private Chunk m_chunk = null;
private object neighbor_lock = new object();
private ChunkData[] m_neighbors = new ChunkData[] {null, null, null, null, null, null};
protected int[] chunk_position = new int[3] {0,0,0};
protected Vector3Int chunk_position_vec;
protected int m_connected_neighbors = 0;
protected bool m_is_fully_connected = false;
public int[] ChunkPosition
{
get
{
return chunk_position;
}
set
{
chunk_position = value;
chunk_position_vec = new Vector3Int(value[0], value[1], value[2]);
}
}
public Vector3Int ChunkPositionVec
{
get
{
return chunk_position_vec;
}
set
{
chunk_position_vec = value;
chunk_position = new int[3] {value.x, value.y, value.z};
}
}
public int ConnectedNeighbors
{
get
{
int val;
lock(neighbor_lock)
{
val = m_connected_neighbors;
}
return val;
}
}
public bool IsFullyConnected
{
get
{
bool val;
lock(neighbor_lock)
{
val = m_is_fully_connected;
}
return val;
}
}
public bool isBuiltNecessary
{
get
{
return m_is_built_necessary;
}
}
public int[] Data
{
get{
return data;
}
}
public Chunk ParentChunk
{
get
{
return m_chunk;
}
set
{
m_chunk = value;
}
}
public ChunkGeometryType GeometryType
{
get
{
return m_chunk_geometry_type;
}
}
public ChunkGeometryType[] GeometryTypeBorders
{
get
{
return m_chunk_geometry_type_borders;
}
}
public ChunkData[] Neighbors
{
get
{
return m_neighbors;
}
}
public ChunkData()
{
}
public void Index2Coords(int i, int[] coords)
{
coords[0] = i % N_CHUNK_SIDELENGTH;
coords[1] = (i / N_CHUNK_SIDELENGTH) % N_CHUNK_SIDELENGTH;
coords[2] = i / (N_CHUNK_SIDELENGTH * N_CHUNK_SIDELENGTH);
}
public int Coords2Index(int[] coords)
{
return coords[0] + coords[1] * N_CHUNK_SIDELENGTH + coords[2] * N_CHUNK_SIDELENGTH_SQRD;
}
public ChunkData(MessageObject mo)
{
SetDataFromMessageObject(mo);
}
public void analyseData ()
{
int i = 0;
if (data[i] == 0)
{
m_chunk_geometry_type = ChunkGeometryType.Empty;
// first block is air
while(i < data.Length)
{
if (data[i] != 0)
{
m_chunk_geometry_type = ChunkGeometryType.Mixed;
break;
}
i++;
}
}
else
{
m_chunk_geometry_type = ChunkGeometryType.Full;
// first block is something
while (i < data.Length)
{
if (data[i] == 0)
{
m_chunk_geometry_type = ChunkGeometryType.Mixed;
break;
}
i++;
}
}
// check borders:
int[] p = {0,0,0};
m_chunk_geometry_type_borders[(int)Direction.z_neg] = data[Coords2Index(p)] == 0 ? ChunkGeometryType.Empty : ChunkGeometryType.Full;
m_chunk_geometry_type_borders[(int)Direction.x_neg] = m_chunk_geometry_type_borders[(int)Direction.y_neg] = m_chunk_geometry_type_borders[(int)Direction.z_neg];
p[0] = N_CHUNK_SIDELENGTH - 1;
p[1] = N_CHUNK_SIDELENGTH - 1;
p[2] = N_CHUNK_SIDELENGTH - 1;
m_chunk_geometry_type_borders[(int)Direction.z_pos] = data[Coords2Index(p)] == 0 ? ChunkGeometryType.Empty : ChunkGeometryType.Full;
m_chunk_geometry_type_borders[(int)Direction.x_pos] = m_chunk_geometry_type_borders[(int)Direction.y_pos] = m_chunk_geometry_type_borders[(int)Direction.z_pos];
p[0] = 0;
p[1] = 0;
p[2] = 0;
bool empty = data[Coords2Index(p)] == 0;
for(p[0] = 0; p[0] < N_CHUNK_SIDELENGTH; p[0]++)
{
for(p[1] = 0; p[1] < N_CHUNK_SIDELENGTH; p[1]++)
{
if (data[Coords2Index(p)] != 0 && empty || data[Coords2Index(p)] == 0 && !empty)
{
m_chunk_geometry_type_borders[(int)Direction.z_neg] = ChunkGeometryType.Mixed;
break;
}
}
if (m_chunk_geometry_type_borders[(int)Direction.z_neg] == ChunkGeometryType.Mixed)
{
break;
}
}
p[0] = 0;
p[1] = 0;
empty = data[Coords2Index(p)] == 0;
for(p[0] = 0; p[0] < N_CHUNK_SIDELENGTH; p[0]++)
{
for(p[2] = 0; p[2] < N_CHUNK_SIDELENGTH; p[2]++)
{
if (data[Coords2Index(p)] != 0 && empty || data[Coords2Index(p)] == 0 && !empty)
{
m_chunk_geometry_type_borders[(int)Direction.y_neg] = ChunkGeometryType.Mixed;
break;
}
}
if (m_chunk_geometry_type_borders[(int)Direction.y_neg] == ChunkGeometryType.Mixed)
{
break;
}
}
p[0] = 0;
p[2] = 0;
empty = data[Coords2Index(p)] == 0;
for(p[1] = 0; p[1] < N_CHUNK_SIDELENGTH; p[1]++)
{
for(p[2] = 0; p[2] < N_CHUNK_SIDELENGTH; p[2]++)
{
if (data[Coords2Index(p)] != 0 && empty || data[Coords2Index(p)] == 0 && !empty)
{
m_chunk_geometry_type_borders[(int)Direction.x_neg] = ChunkGeometryType.Mixed;
break;
}
}
if (m_chunk_geometry_type_borders[(int)Direction.x_neg] == ChunkGeometryType.Mixed)
{
break;
}
}
p[1] = 0;
p[2] = N_CHUNK_SIDELENGTH - 1;
empty = data[Coords2Index(p)] == 0;
for(p[0] = 0; p[0] < N_CHUNK_SIDELENGTH; p[0]++)
{
for(p[1] = 0; p[1] < N_CHUNK_SIDELENGTH; p[1]++)
{
if (data[Coords2Index(p)] != 0 && empty || data[Coords2Index(p)] == 0 && !empty)
{
m_chunk_geometry_type_borders[(int)Direction.z_pos] = ChunkGeometryType.Mixed;
break;
}
}
if (m_chunk_geometry_type_borders[(int)Direction.z_pos] == ChunkGeometryType.Mixed)
{
break;
}
}
p[0] = 0;
p[1] = N_CHUNK_SIDELENGTH - 1;
empty = data[Coords2Index(p)] == 0;
for(p[0] = 0; p[0] < N_CHUNK_SIDELENGTH; p[0]++)
{
for(p[2] = 0; p[2] < N_CHUNK_SIDELENGTH; p[2]++)
{
if (data[Coords2Index(p)] != 0 && empty || data[Coords2Index(p)] == 0 && !empty)
{
m_chunk_geometry_type_borders[(int)Direction.y_pos] = ChunkGeometryType.Mixed;
break;
}
}
if (m_chunk_geometry_type_borders[(int)Direction.y_pos] == ChunkGeometryType.Mixed)
{
break;
}
}
p[0] = N_CHUNK_SIDELENGTH - 1;
p[2] = 0;
empty = data[Coords2Index(p)] == 0;
for(p[1] = 0; p[1] < N_CHUNK_SIDELENGTH; p[1]++)
{
for(p[2] = 0; p[2] < N_CHUNK_SIDELENGTH; p[2]++)
{
if (data[Coords2Index(p)] != 0 && empty || data[Coords2Index(p)] == 0 && !empty)
{
m_chunk_geometry_type_borders[(int)Direction.x_pos] = ChunkGeometryType.Mixed;
break;
}
}
if (m_chunk_geometry_type_borders[(int)Direction.x_pos] == ChunkGeometryType.Mixed)
{
break;
}
}
m_is_built_necessary = m_chunk_geometry_type == ChunkGeometryType.Mixed;
}
public void SetDataFromMessageObject(MessageObject mo)
{
if (mo.data == null || mo.position == null)
{
throw new System.Exception("received empty data block");
}
if (mo.data.Length != 4096)
{
throw new System.Exception("bad data received");
}
data = mo.data;
ChunkPositionVec = new Vector3Int(mo.position[2], mo.position[1], mo.position[0]);
}
public void ConnectChunkData(ChunkData cd, Direction dir)
{
int d = (int)dir;
int op_d = (d+3)%6;
lock(neighbor_lock)
{
if (m_neighbors[d] == null)
{
m_connected_neighbors++;
m_is_fully_connected = (m_connected_neighbors == 6);
}
m_neighbors[d] = cd;
}
ChunkGeometryType borderType = cd.m_chunk_geometry_type_borders[op_d];
if (borderType != ChunkGeometryType.Empty && m_chunk_geometry_type == ChunkGeometryType.Empty)
{
m_is_built_necessary = true;
}
}
public void DisconnectChunkData(Direction dir)
{
int d = (int)dir;
int op_d = (d+3)%6;
lock (neighbor_lock)
{
if (m_neighbors[d] == null)
{
return;
}
if (m_chunk != null)
{
m_chunk.DeleteBorderVertices(dir);
}
if (m_neighbors[d].m_chunk != null)
{
m_neighbors[d].m_chunk.DeleteBorderVertices((Direction) op_d);
}
m_neighbors[d].m_neighbors[op_d] = null;
m_neighbors[d] = null;
m_connected_neighbors--;
m_is_fully_connected = false;
}
}
}

View File

@ -5,12 +5,6 @@ using System.Net.Sockets;
public class ChunkManager
{
private enum ChunkGeometryType
{
Mixed,
Full,
Empty
};
// chunks inside this radius will be actively loaded and visible
private Vector3Int m_min_view_radius;
@ -29,8 +23,31 @@ public class ChunkManager
private Vector3Int m_srqd_max_view_radius;
private Vector3Int m_srqd_cached_chunk_radius;
private WorldManager m_world_manager;
private NetworkThread m_network_thread;
private bool m_end_builder_threads = false;
private Queue<MessageObject> m_received_message_queue;
private Queue<ChunkData> m_create_chunk_data_queue;
private Queue<Chunk> m_chunk_mesh_update_queue;
// queue of chunk which are waiting for geometry to be applied
private Queue<Chunk> m_chunk_geometry_build_queue;
private Queue<ChunkData> m_chunk_data_to_cache_queue;
private object m_handle = new object();
private System.Threading.Thread[] m_threads = null;
// chunks that are in our memory (either as active or inactive object in Unity)
private Dictionary<Vector3Int, Chunk> m_dict_loaded_chunks;
private Dictionary<Vector3Int, ChunkData> m_dict_cached_chunk_data;
private Dictionary<Vector3Int, Chunk> m_dict_cached_chunks;
// active (visible chunks)
private Dictionary<Vector3Int, Chunk> m_dict_active_chunks;
@ -39,29 +56,91 @@ public class ChunkManager
private Dictionary<Vector3Int, bool> m_dict_chunk_requested;
// blocked chunks. (e.g. geometry is build in another thread) They will not be removed
private Dictionary<Vector3Int, bool> m_dict_chunk_blocked;
private Dictionary<Vector3Int, bool> m_dict_chunk_blocked;
// dict of chunks that are empty. For them no geometry is build
private Dictionary<Vector3Int, bool> m_dict_empty_chunk;
private Dictionary<Vector3Int, bool> _m_dict_is_chunk_data_cached;
// dict of chunks that are full of geometry. Since they probably stay invisible, they will also not drawed
// TODO: special case: empty blocks are directly located next to that chunk
private Dictionary<Vector3Int, bool> m_dict_full_chunk;
private Dictionary<Vector3Int, bool> _m_dict_is_chunk_cached;
private WorldManager m_world_manager;
private bool isChunkDataCached(Vector3Int p)
{
bool b;
lock(_m_dict_is_chunk_data_cached)
{
b = _m_dict_is_chunk_data_cached.ContainsKey(p);
}
return b;
}
private NetworkThread m_network_thread;
private void setChunkDataCached(Vector3Int p, bool b)
{
if (b)
{
lock(_m_dict_is_chunk_data_cached)
{
_m_dict_is_chunk_data_cached[p] = true;
}
return;
}
lock(_m_dict_is_chunk_data_cached)
{
_m_dict_is_chunk_data_cached.Remove(p);
}
}
private bool m_end_builder_threads = false;
private void cacheChunkData(ChunkData cd)
{
m_dict_cached_chunk_data[cd.ChunkPositionVec] = cd;
private Queue<Chunk> m_empty_chunks_queue;
private Queue<MessageObject> m_message_queue;
setChunkDataCached(cd.ChunkPositionVec, true);
}
// queue of chunk which are waiting for geometry to be applied
private Queue<Chunk> m_chunk_mesh_queue;
private void uncacheChunkData(Vector3Int chunk_pos)
{
m_dict_cached_chunk_data.Remove(chunk_pos);
private object m_handle = new object();
private System.Threading.Thread[] m_threads = null;
setChunkDataCached(chunk_pos, false);
}
private bool isChunkCached(Vector3Int p)
{
bool b;
lock(_m_dict_is_chunk_cached)
{
b = _m_dict_is_chunk_cached.ContainsKey(p);
}
return b;
}
private void setChunkCached(Vector3Int p, bool b)
{
if (b)
{
lock(_m_dict_is_chunk_cached)
{
_m_dict_is_chunk_cached[p] = true;
}
return;
}
lock(_m_dict_is_chunk_cached)
{
_m_dict_is_chunk_cached.Remove(p);
}
}
private void cacheChunk(Chunk c)
{
m_dict_cached_chunks[c.ChunkPositionVec] = c;
setChunkCached(c.ChunkPositionVec, true);
}
private void uncacheChunk(Vector3Int chunk_pos)
{
m_dict_cached_chunks.Remove(chunk_pos);
setChunkCached(chunk_pos, false);
}
public bool end_builder_threads
{
@ -104,15 +183,19 @@ public class ChunkManager
m_reference_transform = reference_transform;
m_dict_active_chunks = new Dictionary<Vector3Int, Chunk>();
m_dict_loaded_chunks = new Dictionary<Vector3Int, Chunk>();
m_dict_cached_chunks = new Dictionary<Vector3Int, Chunk>();
m_dict_cached_chunk_data = new Dictionary<Vector3Int, ChunkData>();
m_dict_chunk_requested = new Dictionary<Vector3Int, bool>();
m_dict_chunk_blocked = new Dictionary<Vector3Int, bool>();
m_dict_empty_chunk = new Dictionary<Vector3Int, bool>();
m_dict_full_chunk = new Dictionary<Vector3Int, bool>();
_m_dict_is_chunk_data_cached = new Dictionary<Vector3Int, bool>();
_m_dict_is_chunk_cached = new Dictionary<Vector3Int, bool>();
m_empty_chunks_queue = new Queue<Chunk>();
m_message_queue = new Queue<MessageObject>();
m_chunk_mesh_queue = new Queue<Chunk>();
m_received_message_queue = new Queue<MessageObject>();
m_chunk_mesh_update_queue = new Queue<Chunk>();
m_chunk_geometry_build_queue = new Queue<Chunk>();
m_create_chunk_data_queue = new Queue<ChunkData>();
m_chunk_data_to_cache_queue = new Queue<ChunkData>();
m_threads = new System.Threading.Thread[n_threads];
@ -125,38 +208,6 @@ public class ChunkManager
}
private ChunkGeometryType analyseData (int[] data)
{
int i = 0;
if (data[i] == 0)
{
// first block is air
while(i < data.Length)
{
if (data[i] != 0)
{
return ChunkGeometryType.Mixed;
}
i++;
}
return ChunkGeometryType.Empty;
}
else
{
// first block is something
while (i < data.Length)
{
if (data[i] == 0)
{
return ChunkGeometryType.Mixed;
}
i++;
}
return ChunkGeometryType.Full;
}
}
public void processServerMessage(MessageObject mo)
{
//TODO: check datatype
@ -165,86 +216,142 @@ public class ChunkManager
if (m_dict_chunk_requested.ContainsKey(chunk_pos))
{
ChunkGeometryType cg_type = analyseData(mo.data);
m_dict_chunk_requested.Remove(chunk_pos);
if (cg_type == ChunkGeometryType.Empty)
{
m_dict_empty_chunk[chunk_pos] = true;
return;
}
if (cg_type == ChunkGeometryType.Full)
{
m_dict_full_chunk[chunk_pos] = true;
return;
}
Vector3Int tmp = chunk_pos - m_reference_chunk_position;
tmp = Vector3Int.Scale(tmp,tmp);
if (!InRange(tmp, m_srqd_max_view_radius))
{
Debug.LogWarning("Lost Chunk: " + chunk_pos.ToString());
return;
}
m_dict_chunk_blocked[chunk_pos] = true;
Chunk c = m_world_manager.InstantiateNewChunk(chunk_pos);
lock(m_handle)
ChunkData cd = new ChunkData(mo);
lock(m_create_chunk_data_queue)
{
m_empty_chunks_queue.Enqueue(c);
m_message_queue.Enqueue(mo);
m_create_chunk_data_queue.Enqueue(cd);
}
}
else
{
Debug.LogWarning("Received chunk we not asked for");
Debug.LogWarning("Received chunk we not asked for: " + mo.position.ToString());
}
}
private void AppendNewChunkToBuild(ChunkData cd)
{
Debug.Assert(cd.IsFullyConnected);
Chunk c = m_world_manager.InstantiateNewChunk(cd);
m_dict_chunk_blocked[cd.ChunkPositionVec] = true;
lock(m_handle)
{
m_chunk_geometry_build_queue.Enqueue(c);
}
}
private void RunChunkBuilderThread()
{
int count;
Chunk c;
MessageObject mo;
int count_data;
int count_geometry;
Chunk c = null;;
ChunkData cd = null;
bool success;
while (!end_builder_threads)
{
success = false;
lock(m_handle)
{
count = m_message_queue.Count;
count_geometry = m_chunk_geometry_build_queue.Count;
}
if (count > 0)
lock (m_create_chunk_data_queue)
{
lock(m_handle)
count_data = m_create_chunk_data_queue.Count;
}
if(count_geometry == 0 && count_data == 0)
{
System.Threading.Thread.Sleep(50);
continue;
}
if (count_data > count_geometry)
{
lock (m_create_chunk_data_queue)
{
c = m_empty_chunks_queue.Dequeue();
mo = m_message_queue.Dequeue();
if (m_create_chunk_data_queue.Count > 0)
{
cd = m_create_chunk_data_queue.Dequeue();
success = true;
}
}
c.SetDataFromMessageObject(mo);
c.BuildMesh();
// TODO: connect neighbors
lock(m_handle)
if (!success)
{
m_chunk_mesh_queue.Enqueue(c);
// another thread was faster
continue;
}
cd.analyseData();
lock(m_chunk_data_to_cache_queue)
{
m_chunk_data_to_cache_queue.Enqueue(cd);
}
}
System.Threading.Thread.Sleep(50);
else
{
// looking for new chunk geometry to build
lock(m_handle)
{
if (m_chunk_geometry_build_queue.Count > 0)
{
c = m_chunk_geometry_build_queue.Dequeue();
success = true;
}
}
if (!success)
{
//another thread was faster
continue;
}
c.BuildInnerMesh();
Vector3Int chunk_pos = c.ChunkPositionVec;
// TODO: connect neighbors and build border regions
for (int i = 0; i < 6; i++)
{
c.BuildBorderGeometry((ChunkData.Direction)i);
}
c.ConcatenateGeometry();
lock(m_handle)
{
m_chunk_mesh_update_queue.Enqueue(c);
}
}
}
Debug.Log("Closing Chunk Builder Thread");
}
private bool isChunkCached(Vector3Int chunk_pos)
{
return m_dict_loaded_chunks.ContainsKey(chunk_pos);
}
private bool isChunkActive(Vector3Int chunk_pos)
{
return m_dict_active_chunks.ContainsKey(chunk_pos);
@ -252,7 +359,8 @@ public class ChunkManager
public void requestChunkFromServer(Vector3Int chunk_pos)
{
if (!m_dict_chunk_requested.ContainsKey(chunk_pos) && !m_dict_loaded_chunks.ContainsKey(chunk_pos))
if (!m_dict_chunk_requested.ContainsKey(chunk_pos) && !isChunkDataCached(chunk_pos))
{
m_dict_chunk_requested[chunk_pos] = true;
//request chunk
@ -273,13 +381,13 @@ public class ChunkManager
Chunk c;
lock(m_handle)
{
n = m_chunk_mesh_queue.Count;
n = m_chunk_mesh_update_queue.Count;
}
while(n > 0 && i > 0)
{
lock(m_handle)
{
c = m_chunk_mesh_queue.Dequeue();
c = m_chunk_mesh_update_queue.Dequeue();
}
c.AssignMesh();
@ -289,7 +397,8 @@ public class ChunkManager
m_dict_chunk_blocked.Remove(c.ChunkPositionVec);
m_dict_loaded_chunks[c.ChunkPositionVec] = c;
cacheChunk(c);
m_dict_active_chunks[c.ChunkPositionVec] = c;
}
@ -307,18 +416,51 @@ public class ChunkManager
public void UpdateViewRange()
{
//getting new Chunk Data:
int cache_count;
lock(m_chunk_data_to_cache_queue)
{
cache_count = m_chunk_data_to_cache_queue.Count;
}
while (cache_count > 0)
{
ChunkData cd;
lock (m_chunk_data_to_cache_queue)
{
cd = m_chunk_data_to_cache_queue.Dequeue();
}
// check for neighbors TODO: make this in builder thread!
for (int i = 0; i < 6; i++)
{
Vector3Int neighbor_pos = cd.ChunkPositionVec + ChunkData.DirectionNormalsInt[i];
if (isChunkDataCached(neighbor_pos))
{
ChunkData neighbor = m_dict_cached_chunk_data[neighbor_pos];
cd.ConnectChunkData(neighbor, (ChunkData.Direction)i);
neighbor.ConnectChunkData(cd, (ChunkData.Direction) ((i+3)%6));
}
}
cacheChunkData(cd);
m_dict_chunk_requested.Remove(cd.ChunkPositionVec);
cache_count --;
}
Vector3Int current_chunk_position = Vector3Int.RoundToInt(m_reference_transform.position);
current_chunk_position.x /= Chunk.N_CHUNK_SIDELENGTH;
current_chunk_position.y /= Chunk.N_CHUNK_SIDELENGTH;
current_chunk_position.z /= Chunk.N_CHUNK_SIDELENGTH;
current_chunk_position.x /= ChunkData.N_CHUNK_SIDELENGTH;
current_chunk_position.y /= ChunkData.N_CHUNK_SIDELENGTH;
current_chunk_position.z /= ChunkData.N_CHUNK_SIDELENGTH;
m_reference_chunk_position = current_chunk_position;
Stack<Vector3Int> to_remove = new Stack<Vector3Int>();
// check for chunks to remove:
foreach(KeyValuePair<Vector3Int, Chunk> entry in m_dict_loaded_chunks)
foreach(KeyValuePair<Vector3Int, ChunkData> entry in m_dict_cached_chunk_data)
{
// do something with entry.Value or entry.Key
Vector3Int tmp = entry.Key - m_reference_chunk_position;
@ -329,17 +471,19 @@ public class ChunkManager
continue;
}
if (!InRange(tmp, m_srqd_max_view_radius))
if (m_dict_active_chunks.ContainsKey(entry.Key) && !InRange(tmp, m_srqd_max_view_radius))
{
entry.Value.gameObject.SetActive(false);
Debug.Assert(entry.Value.ParentChunk != null);
if (entry.Value.ParentChunk != null)
entry.Value.ParentChunk.gameObject.SetActive(false);
else
Debug.LogError("corrupted chunk: " + entry.Key.ToString());
m_dict_active_chunks.Remove(entry.Key);
//m_dict_loaded_chunks.Remove(entry.Key);
}
if (!InRange(tmp, m_srqd_cached_chunk_radius))
{
//m_dict_active_chunks.Remove(entry.Key);
to_remove.Push(entry.Key);
}
@ -348,10 +492,14 @@ public class ChunkManager
while (to_remove.Count > 0)
{
Vector3Int k = to_remove.Pop();
Chunk c = m_dict_loaded_chunks[k];
m_dict_loaded_chunks.Remove(k);
uncacheChunkData(k);
UnityEngine.Object.Destroy(c);
if (m_dict_cached_chunks.ContainsKey(k))
{
Chunk c = m_dict_cached_chunks[k];
uncacheChunk(k);
UnityEngine.Object.Destroy(c);
}
}
// reload view range:
@ -364,19 +512,41 @@ public class ChunkManager
Vector3Int p = new Vector3Int(x, y, z) + m_reference_chunk_position;
if (m_dict_active_chunks.ContainsKey(p)
|| m_dict_chunk_requested.ContainsKey(p)
|| m_dict_chunk_blocked.ContainsKey(p)
|| m_dict_empty_chunk.ContainsKey(p)
|| m_dict_full_chunk.ContainsKey(p))
|| m_dict_chunk_blocked.ContainsKey(p))
{
// TODO: the if above is a hell of a mess!
continue;
}
if (m_dict_loaded_chunks.ContainsKey(p))
if (isChunkDataCached(p))
{
Chunk c = m_dict_loaded_chunks[p];
c.gameObject.SetActive(true);
m_dict_active_chunks[p] = c;
if (!isChunkCached(p))
{
ChunkData cd = m_dict_cached_chunk_data[p];
if (cd.IsFullyConnected )
{
if (cd.isBuiltNecessary)
{
AppendNewChunkToBuild(cd);
}
}
}
else
{
Chunk c;
c = m_dict_cached_chunks[p];
c.gameObject.SetActive(true);
m_dict_active_chunks[p] = c;
}
}
else if (!m_dict_chunk_requested.ContainsKey(p))
{
requestChunkFromServer(p);

View File

@ -86,12 +86,18 @@ public class WorldManager : MonoBehaviour {
chunk_manager.UpdateViewRange();
}
public Chunk InstantiateNewChunk(Vector3Int chunk_position)
public Chunk InstantiateNewChunk(ChunkData cd)
{
Chunk c = (Chunk)Instantiate(chunkPrefab, transform);
Vector3Int chunk_position = cd.ChunkPositionVec;
c.transform.localPosition = new Vector3(chunk_position.x * Chunk.N_CHUNK_SIDELENGTH,chunk_position.y * Chunk.N_CHUNK_SIDELENGTH,chunk_position.z * Chunk.N_CHUNK_SIDELENGTH);
c.gameObject.name = "Chunk_" +chunk_position.ToString() ;
c.chunk_data = cd;
cd.ParentChunk = c;
c.ChunkPosition = new int[] {chunk_position.x, chunk_position.y, chunk_position.z};