mirror of
https://github.com/tetreum/brickcraft.git
synced 2026-05-07 09:29:32 -05:00
+ Marry building system with world terrain - phase 1
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using UnityEngine;
|
||||
using Brickcraft.UI;
|
||||
using Brickcraft.World;
|
||||
|
||||
namespace Brickcraft
|
||||
{
|
||||
@@ -102,6 +103,13 @@ namespace Brickcraft
|
||||
// ignore collisions with studs
|
||||
if (other.name.StartsWith("GridStud")) {
|
||||
return;
|
||||
} else if (other.name.StartsWith("ChunkSlice")) {
|
||||
/*
|
||||
RaycastHit hit;
|
||||
Physics.Raycast(transform.position, other.transform.position, out hit);
|
||||
var pos = other.gameObject.GetComponent<Collider>().ClosestPointOnBounds(transform.position);
|
||||
Debug.Log(other.transform.InverseTransformPoint(pos) + "-" + transform.InverseTransformPoint(pos));
|
||||
*/
|
||||
}
|
||||
|
||||
// prevent resetting those vars each frame
|
||||
@@ -123,8 +131,14 @@ namespace Brickcraft
|
||||
StudInfo stud = new StudInfo();
|
||||
|
||||
// get grid dimensions
|
||||
string[] tmp = hit.collider.name.Replace("GridStud ", "").Replace("GridStudBottom ", "").Split('x');
|
||||
stud.gridDimensions = new Vector2Int(int.Parse(tmp[0]), int.Parse(tmp[1]));
|
||||
if (hit.collider.name.StartsWith("GridStud")) {
|
||||
string[] tmp = hit.collider.name.Replace("GridStud ", "").Replace("GridStudBottom ", "").Split('x');
|
||||
stud.gridDimensions = new Vector2Int(int.Parse(tmp[0]), int.Parse(tmp[1]));
|
||||
} else {
|
||||
// is looking at world stud
|
||||
// so grid is a 16x16 (chunk slice) made by 2x2 bricks
|
||||
stud.gridDimensions = new Vector2Int(Chunk.SliceHeight * 2, Chunk.SliceHeight * 2);
|
||||
}
|
||||
|
||||
// 1x1 are easy xD
|
||||
if (stud.gridDimensions.x == 1 && stud.gridDimensions.y == 1) {
|
||||
@@ -132,7 +146,12 @@ namespace Brickcraft
|
||||
}
|
||||
|
||||
// convert world coords to local ones
|
||||
var localHitpoint = hit.collider.transform.InverseTransformPoint(hit.point);
|
||||
Vector3 localHitpoint = hit.collider.transform.InverseTransformPoint(hit.point);
|
||||
|
||||
if (hit.collider.name.StartsWith("ChunkSlice")) { // chunkSlices have center wrongly set
|
||||
Vector3 localCenter = hit.collider.transform.InverseTransformPoint(hit.collider.transform.GetComponent<Collider>().bounds.center);
|
||||
localHitpoint -= localCenter;
|
||||
}
|
||||
|
||||
// since localHitpoint is based on the center of the object, we need to sum half
|
||||
// of it's size
|
||||
@@ -157,6 +176,32 @@ namespace Brickcraft
|
||||
return stud;
|
||||
}
|
||||
|
||||
public bool isLookingAtWorldStud (RaycastHit hit) {
|
||||
Vector3[] vertices = getTriangleVertices(hit.transform.GetComponent<MeshCollider>().sharedMesh, hit.triangleIndex);
|
||||
|
||||
Vector3Int equal = new Vector3Int(
|
||||
vertices[0].x == vertices[1].x && vertices[1].x == vertices[2].x ? 1 : 0,
|
||||
vertices[0].y == vertices[1].y && vertices[1].y == vertices[2].y ? 1 : 0,
|
||||
vertices[0].z == vertices[1].z && vertices[1].z == vertices[2].z ? 1 : 0
|
||||
);
|
||||
|
||||
// y is the same OR there are no equal values (round triangle) then we know that is top or bottom face
|
||||
return vertices[0].y == vertices[1].y && vertices[1].y == vertices[2].y || equal == Vector3Int.zero;
|
||||
}
|
||||
|
||||
Vector3[] getTriangleVertices(Mesh mesh, int triangleIndex) {
|
||||
Vector3[] vertices = mesh.vertices;
|
||||
int[] triangles = mesh.triangles;
|
||||
|
||||
Vector3[] output = new Vector3[3];
|
||||
|
||||
output[0] = vertices[triangles[triangleIndex * 3 + 0]];
|
||||
output[1] = vertices[triangles[triangleIndex * 3 + 1]];
|
||||
output[2] = vertices[triangles[triangleIndex * 3 + 2]];
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public void lookingAtStud(RaycastHit hit) {
|
||||
// player is not holding a brick
|
||||
if (PlayerPanel.Instance.selectedItem == null || PlayerPanel.Instance.selectedItem.item.type != Item.Type.Brick) {
|
||||
@@ -168,9 +213,8 @@ namespace Brickcraft
|
||||
if (hit.transform == latestStudGrid && stud.gridPosition == latestStud) {
|
||||
return;
|
||||
}
|
||||
GameObject brickObj = hit.collider.transform.parent.gameObject;
|
||||
|
||||
Quaternion rot = pivot.rotation; // kepp current rotation
|
||||
Quaternion rot = pivot.rotation; // keep current rotation
|
||||
|
||||
// if old stud and new stud don't have the same rotation,
|
||||
// pivot rotation will be invalid, so we reset it to new stud's rotation
|
||||
@@ -182,15 +226,23 @@ namespace Brickcraft
|
||||
latestStud = stud.gridPosition;
|
||||
|
||||
Vector3 studPos = hit.collider.transform.TransformPoint(stud.center);
|
||||
|
||||
|
||||
// height needs to be corrected for bottom studs
|
||||
if (hit.collider.name.Contains("Bottom")) {
|
||||
studPos.y -= PlayerPanel.Instance.selectedItem.item.brickModel.heightInPlates * Server.plateHeight;
|
||||
} else if (hit.collider.name.StartsWith("ChunkSlice")) { // chunkSlices have center wrongly set
|
||||
Vector3 localCenter = hit.collider.transform.InverseTransformPoint(hit.collider.transform.GetComponent<Collider>().bounds.center);
|
||||
studPos += localCenter;
|
||||
studPos.y = hit.point.y;
|
||||
studPos.y -= 0.089f; // supper ugly hack
|
||||
}
|
||||
|
||||
|
||||
currentStud = studPos;
|
||||
|
||||
if (!Server.bricks.ContainsKey(brickObj.name)) {
|
||||
GameObject brickObj = hit.collider.transform.parent.gameObject;
|
||||
|
||||
if (!Server.bricks.ContainsKey(brickObj.name) && !hit.collider.name.StartsWith("ChunkSlice")) {
|
||||
Debug.LogError("Brick not found in server list " + brickObj.name);
|
||||
return;
|
||||
}
|
||||
@@ -216,6 +268,7 @@ namespace Brickcraft
|
||||
pivot.position = pos;
|
||||
pivot.rotation = rotation;
|
||||
transform.localRotation = Quaternion.identity; // localy reset child rotation as it should always be identity
|
||||
isColliding = false;
|
||||
setValid(true);
|
||||
lastPos = pos;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,12 @@ namespace Brickcraft
|
||||
|
||||
private void Start() {
|
||||
PlayerPanel.Instance.reload();
|
||||
|
||||
// temporal for testing
|
||||
addItem(new UserItem() {
|
||||
id = 1,
|
||||
quantity = 100,
|
||||
});
|
||||
}
|
||||
|
||||
private void Update() {
|
||||
@@ -68,7 +74,12 @@ namespace Brickcraft
|
||||
//Debug.DrawRay(ray.origin, ray.direction * rayLength, Color.red);
|
||||
|
||||
if (Physics.Raycast(ray, out latestHit, rayLength)) {
|
||||
if (latestHit.collider.name.StartsWith("GridStud")) {
|
||||
if (latestHit.collider.name.StartsWith("ChunkSlice")) {
|
||||
if (BrickCollisionDetector.Instance != null && BrickCollisionDetector.Instance.isLookingAtWorldStud(latestHit)) {
|
||||
BrickCollisionDetector.Instance.lookingAtStud(latestHit);
|
||||
}
|
||||
lookedBrick = latestHit.transform.parent.gameObject;
|
||||
} else if (latestHit.collider.name.StartsWith("GridStud")) {
|
||||
if (BrickCollisionDetector.Instance != null) {
|
||||
BrickCollisionDetector.Instance.lookingAtStud(latestHit);
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ namespace Brickcraft
|
||||
public const float brickWidth = 0.796f; // 2x2
|
||||
|
||||
public GameObject[] prefabs;
|
||||
public GameObject playerPrefab;
|
||||
|
||||
void Awake() {
|
||||
Instance = this;
|
||||
@@ -97,6 +98,10 @@ namespace Brickcraft
|
||||
}
|
||||
}
|
||||
|
||||
public void spawnPlayer () {
|
||||
Instantiate(playerPrefab, new Vector3(0, 160, 0), Quaternion.identity);
|
||||
}
|
||||
|
||||
void processPrefabs() {
|
||||
foreach (var prefab in prefabs) {
|
||||
brickPrefabs.Add(prefab.name, prefab);
|
||||
|
||||
@@ -11,6 +11,9 @@ public class CameraController : MonoBehaviour
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
movementSpeed = Mathf.Max(movementSpeed += Input.GetAxis("Mouse ScrollWheel"), 0.0f);
|
||||
if (Input.GetAxis("Vertical") != 0) {
|
||||
transform.Translate(Vector3.forward * movementSpeed * Input.GetAxis("Vertical"));
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Brickcraft.World
|
||||
{
|
||||
ChunkObject = new GameObject(String.Format("X {0} Z {1}", X, Z));
|
||||
|
||||
ChunkObject.transform.position = new Vector3(X*16,0,Z*16);
|
||||
ChunkObject.transform.position = new Vector3(X * 16, 0, Z * 16);
|
||||
}
|
||||
|
||||
public void InitRenderableSlices()
|
||||
@@ -64,6 +64,7 @@ namespace Brickcraft.World
|
||||
meshRenderer.material.mainTexture = WorldBehaviour.AtlasTexture;
|
||||
meshRenderer.sharedMaterial = WorldBehaviour.BlockMaterial;
|
||||
newObject.AddComponent(typeof(MeshFilter));
|
||||
newObject.AddComponent<MeshCollider>();
|
||||
|
||||
Vector3 pos = new Vector3(ChunkObject.transform.position.x, ChunkObject.transform.position.y + (i * Chunk.SliceHeight), ChunkObject.transform.position.z);
|
||||
if (WorldBehaviour.mode == 3) {
|
||||
@@ -376,12 +377,12 @@ namespace Brickcraft.World
|
||||
public void RecalculateHeight()
|
||||
{
|
||||
LowestY = 255;
|
||||
HeightMap = new byte[16, 16];
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
for (int z = 0; z < 16; z++)
|
||||
RecalculateHeight(x, z);
|
||||
}
|
||||
HeightMap = new byte[16, 16];
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
for (int z = 0; z < 16; z++)
|
||||
RecalculateHeight(x, z);
|
||||
}
|
||||
|
||||
MinSliceIndex = (LowestY / Chunk.SliceHeight) - 1;
|
||||
}
|
||||
@@ -393,8 +394,8 @@ namespace Brickcraft.World
|
||||
for (height = 127; height > 0 && (GetBlockType(x, height - 1, z) == 0 || (blockType = GetBlockType(x, height - 1, z)) == BlockType.Leaves || blockType == BlockType.Water || blockType == BlockType.Still_Water); height--) ;
|
||||
HeightMap[x, z] = (byte)height;
|
||||
|
||||
if (height < LowestY)
|
||||
LowestY = height;
|
||||
if (height < LowestY)
|
||||
LowestY = height;
|
||||
}
|
||||
|
||||
public void ClearDirtySlices()
|
||||
@@ -406,5 +407,8 @@ namespace Brickcraft.World
|
||||
slice.ClearDirtyLight();
|
||||
}
|
||||
}
|
||||
public static int CorrectBlockCoordinate(int axis) {
|
||||
return axis >= 0 ? axis : (axis + Chunk.SliceHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,18 +53,17 @@ namespace Brickcraft.World
|
||||
genWait[i] = new ManualResetEvent(false);
|
||||
|
||||
ChunkGenThreadEntry chunkGenEntry = new ChunkGenThreadEntry(currStartX, currEndX, GenPool, (chunkGen, x) => {
|
||||
int xComponent = (x + Math.Abs(fromChunkX)) * (toChunkX - fromChunkX);
|
||||
for(int z = fromChunkX; z < toChunkX; ++z)
|
||||
{
|
||||
ushort index = WorldBehaviour.ChunkIndexFromCoords(x,z);
|
||||
Chunk chunk = new Chunk(x,z, worldManager, (z + x) % 2 == 0? Color.black : Color.gray);
|
||||
chunkGen.GenerateChunk(chunk, x, z);
|
||||
int xComponent = (x + Math.Abs(fromChunkX)) * (toChunkX - fromChunkX);
|
||||
for(int z = fromChunkX; z < toChunkX; ++z)
|
||||
{
|
||||
ushort index = WorldBehaviour.ChunkIndexFromCoords(x, z);
|
||||
Chunk chunk = new Chunk(x,z, worldManager, (z + x) % 2 == 0 ? Color.black : Color.gray);
|
||||
chunkGen.GenerateChunk(chunk, x, z);
|
||||
|
||||
int entryIndex = xComponent + (z + Math.Abs(fromChunkX));
|
||||
chunkEntries[entryIndex] = new ChunkMeshThreadEntry(chunk);
|
||||
WorldBehaviour.ChunksMap[index] = chunk;
|
||||
}
|
||||
|
||||
int entryIndex = xComponent + (z + Math.Abs(fromChunkX));
|
||||
chunkEntries[entryIndex] = new ChunkMeshThreadEntry(chunk);
|
||||
WorldBehaviour.ChunksMap[index] = chunk;
|
||||
}
|
||||
});
|
||||
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback(chunkGenEntry.ThreadCallback), genWait[i]);
|
||||
|
||||
@@ -504,6 +504,23 @@ namespace Brickcraft.World
|
||||
throw new System.Exception("wrong face name: " + face);
|
||||
}
|
||||
|
||||
// temporal | testing
|
||||
Vector2 xt = new Vector2(0, 0);
|
||||
Vector2 zt = new Vector2(0, 0);
|
||||
|
||||
foreach (Vector3 vertice in faceMap.vertices) {
|
||||
if (vertice.x > xt.x) {
|
||||
xt.x = vertice.x;
|
||||
} else if (vertice.x < xt.y) {
|
||||
xt.y = vertice.x;
|
||||
}
|
||||
if (vertice.z > zt.x) {
|
||||
zt.x = vertice.z;
|
||||
} else if (vertice.x < zt.y) {
|
||||
zt.y = vertice.z;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Vector3 vertice in faceMap.vertices) {
|
||||
Vector3 pos = new Vector3(
|
||||
vertice.x + (x * Server.brickWidth),
|
||||
@@ -512,7 +529,12 @@ namespace Brickcraft.World
|
||||
);
|
||||
vertices.Add(pos);
|
||||
colors.Add(color);
|
||||
uvs.Add(new Vector2(vertice.x, vertice.z));
|
||||
|
||||
if (face == "top" || face == "bottom") {
|
||||
uvs.Add(new Vector2(xt.x, zt.x));
|
||||
} else {
|
||||
uvs.Add(new Vector2(xt.y, zt.y));
|
||||
}
|
||||
}
|
||||
foreach (int index in faceMap.triangles) {
|
||||
triangles.Add(index + vertexIndex);
|
||||
@@ -530,343 +552,5 @@ namespace Brickcraft.World
|
||||
|
||||
meshes[block].Add(pos);
|
||||
}
|
||||
|
||||
public void RenderSliceLight(ChunkSlice chunkSlice)
|
||||
{
|
||||
|
||||
Chunk parentChunk = chunkSlice.ParentChunk;
|
||||
MeshFilter meshFilter = parentChunk.ChunkSliceObjects[chunkSlice.Index].GetComponent<MeshFilter>();
|
||||
|
||||
if(meshFilter.mesh.vertexCount == 0)
|
||||
{
|
||||
chunkSlice.ClearDirtyLight();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
WorldBehaviour world = chunkSlice.ParentChunk.World;
|
||||
|
||||
int minHeight = parentChunk.MinSliceIndex == chunkSlice.Index ? (parentChunk.LowestY & Chunk.SliceHeightLimit) : 0;
|
||||
|
||||
colors.Clear();
|
||||
vertices.Clear();
|
||||
uvs.Clear();
|
||||
triangles.Clear();
|
||||
|
||||
float epsilon = 0;
|
||||
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
for (int y = Chunk.SliceHeight - 1; y >= 0 && y >= minHeight; --y)
|
||||
{
|
||||
byte block = chunkSlice[x, y, z];
|
||||
int light = 0;
|
||||
byte top;
|
||||
|
||||
if(block == 0)
|
||||
continue;
|
||||
|
||||
if(y + 1 > Chunk.SliceHeightLimit)
|
||||
{
|
||||
if(chunkSlice.Index + 1 > Chunk.MaxSliceIndex)
|
||||
top = 0;
|
||||
else
|
||||
{
|
||||
int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + (y + 1);
|
||||
top = (byte)parentChunk.GetBlockType(x, worldY, z);
|
||||
light = parentChunk.GetSkylight(x, worldY, z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
top = chunkSlice[x, y + 1, z];
|
||||
light = chunkSlice.GetSkylight(x, y + 1, z);
|
||||
}
|
||||
|
||||
// we are checking the top face of the block, so see if the top is exposed
|
||||
if (top == 0)
|
||||
{
|
||||
int vertexIndex = vertices.Count;
|
||||
vertices.Add(new Vector3(x, y + 1, z));
|
||||
vertices.Add(new Vector3(x, y + 1, z + 1));
|
||||
vertices.Add(new Vector3(x + 1, y + 1, z + 1));
|
||||
vertices.Add(new Vector3(x + 1, y + 1, z));
|
||||
|
||||
triangles.Add(vertexIndex);
|
||||
triangles.Add(vertexIndex+1);
|
||||
triangles.Add(vertexIndex+2);
|
||||
|
||||
triangles.Add(vertexIndex+2);
|
||||
triangles.Add(vertexIndex+3);
|
||||
triangles.Add(vertexIndex);
|
||||
|
||||
|
||||
float attenuation = (light / 15.0f);
|
||||
Color withLight = new Color(topColor.r * attenuation, topColor.g * attenuation, topColor.b * attenuation, 1);
|
||||
colors.Add(withLight);
|
||||
colors.Add(withLight);
|
||||
colors.Add(withLight);
|
||||
colors.Add(withLight);
|
||||
|
||||
Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Top);
|
||||
|
||||
float yMax = coords.y + coords.height - epsilon;
|
||||
float xMax = coords.x + coords.width - epsilon;
|
||||
float xMin = coords.x + epsilon;
|
||||
float yMin = coords.y + epsilon;
|
||||
|
||||
uvs.Add(new Vector2(xMin, yMax));
|
||||
uvs.Add(new Vector2(xMin, yMin));
|
||||
uvs.Add(new Vector2(xMax, yMin));
|
||||
uvs.Add(new Vector2(xMax, yMax));
|
||||
}
|
||||
|
||||
int front;
|
||||
if(z - 1 < 0)
|
||||
{
|
||||
int worldX = (parentChunk.X << 4) + x;
|
||||
int worldZ = (parentChunk.Z << 4) - 1;
|
||||
int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + y;
|
||||
|
||||
front = (byte)world.GetBlockType(worldX, worldY, worldZ);
|
||||
}
|
||||
else
|
||||
front = chunkSlice[x, y, z - 1];
|
||||
|
||||
if (front == 0)
|
||||
{
|
||||
int vertexIndex = vertices.Count;
|
||||
vertices.Add(new Vector3(x, y, z));
|
||||
vertices.Add(new Vector3(x, y + 1, z));
|
||||
vertices.Add(new Vector3(x + 1, y + 1, z));
|
||||
vertices.Add(new Vector3(x + 1, y, z));
|
||||
|
||||
triangles.Add(vertexIndex);
|
||||
triangles.Add(vertexIndex+1);
|
||||
triangles.Add(vertexIndex+2);
|
||||
|
||||
triangles.Add(vertexIndex+2);
|
||||
triangles.Add(vertexIndex+3);
|
||||
triangles.Add(vertexIndex);
|
||||
|
||||
colors.Add(firstSideColor);
|
||||
colors.Add(firstSideColor);
|
||||
colors.Add(firstSideColor);
|
||||
colors.Add(firstSideColor);
|
||||
|
||||
Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Side);
|
||||
|
||||
float yMax = coords.y + coords.height - epsilon;
|
||||
float xMax = coords.x + coords.width - epsilon;
|
||||
float xMin = coords.x + epsilon;
|
||||
float yMin = coords.y + epsilon;
|
||||
|
||||
uvs.Add(new Vector2(xMin, yMin));
|
||||
uvs.Add(new Vector2(xMin, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMin));
|
||||
}
|
||||
|
||||
int right;
|
||||
|
||||
if(x + 1 > 15)
|
||||
{
|
||||
int worldX = (parentChunk.X << 4) + 16;
|
||||
int worldZ = (parentChunk.Z << 4) + z;
|
||||
int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + y;
|
||||
|
||||
right = (byte)world.GetBlockType(worldX, worldY, worldZ);
|
||||
}
|
||||
else
|
||||
right = chunkSlice[x + 1, y, z];
|
||||
|
||||
if (right == 0)
|
||||
{
|
||||
int vertexIndex = vertices.Count;
|
||||
vertices.Add(new Vector3(x + 1, y, z));
|
||||
vertices.Add(new Vector3(x + 1, y + 1, z));
|
||||
vertices.Add(new Vector3(x + 1, y + 1, z + 1));
|
||||
vertices.Add(new Vector3(x + 1, y, z + 1));
|
||||
|
||||
triangles.Add(vertexIndex);
|
||||
triangles.Add(vertexIndex+1);
|
||||
triangles.Add(vertexIndex+2);
|
||||
|
||||
triangles.Add(vertexIndex+2);
|
||||
triangles.Add(vertexIndex+3);
|
||||
triangles.Add(vertexIndex);
|
||||
|
||||
colors.Add(secondSideColor);
|
||||
colors.Add(secondSideColor);
|
||||
colors.Add(secondSideColor);
|
||||
colors.Add(secondSideColor);
|
||||
|
||||
Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Side);
|
||||
|
||||
float yMax = coords.y + coords.height - epsilon;
|
||||
float xMax = coords.x + coords.width - epsilon;
|
||||
float xMin = coords.x + epsilon;
|
||||
float yMin = coords.y + epsilon;
|
||||
|
||||
uvs.Add(new Vector2(xMin, yMin));
|
||||
uvs.Add(new Vector2(xMin, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMin));
|
||||
}
|
||||
|
||||
int back;
|
||||
|
||||
if(z + 1 > 15)
|
||||
{
|
||||
int worldX = (parentChunk.X << 4) + x;
|
||||
int worldZ = (parentChunk.Z << 4) + 16;
|
||||
int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + y;
|
||||
|
||||
back = (byte)world.GetBlockType(worldX, worldY, worldZ);
|
||||
}
|
||||
else
|
||||
back = chunkSlice[x, y, z + 1];
|
||||
|
||||
if (back == 0)
|
||||
{
|
||||
int vertexIndex = vertices.Count;
|
||||
vertices.Add(new Vector3(x + 1, y, z + 1));
|
||||
vertices.Add(new Vector3(x + 1, y + 1, z + 1));
|
||||
vertices.Add(new Vector3(x, y + 1, z + 1));
|
||||
vertices.Add(new Vector3(x, y, z + 1));
|
||||
|
||||
triangles.Add(vertexIndex);
|
||||
triangles.Add(vertexIndex+1);
|
||||
triangles.Add(vertexIndex+2);
|
||||
|
||||
triangles.Add(vertexIndex+2);
|
||||
triangles.Add(vertexIndex+3);
|
||||
triangles.Add(vertexIndex);
|
||||
|
||||
colors.Add(firstSideColor);
|
||||
colors.Add(firstSideColor);
|
||||
colors.Add(firstSideColor);
|
||||
colors.Add(firstSideColor);
|
||||
|
||||
Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Side);
|
||||
|
||||
float yMax = coords.y + coords.height - epsilon;
|
||||
float xMax = coords.x + coords.width - epsilon;
|
||||
float xMin = coords.x + epsilon;
|
||||
float yMin = coords.y + epsilon;
|
||||
|
||||
uvs.Add(new Vector2(xMin, yMin));
|
||||
uvs.Add(new Vector2(xMin, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMin));
|
||||
}
|
||||
|
||||
int left;
|
||||
|
||||
if(x - 1 < 0)
|
||||
{
|
||||
int worldX = (parentChunk.X << 4) - 1;
|
||||
int worldZ = (parentChunk.Z << 4) + z;
|
||||
int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + y;
|
||||
|
||||
left = (byte)world.GetBlockType(worldX, worldY, worldZ);
|
||||
}
|
||||
else
|
||||
left = chunkSlice[x - 1, y, z];
|
||||
|
||||
if (left == 0)
|
||||
{
|
||||
int vertexIndex = vertices.Count;
|
||||
vertices.Add(new Vector3(x, y, z + 1));
|
||||
vertices.Add(new Vector3(x, y + 1, z + 1));
|
||||
vertices.Add(new Vector3(x, y + 1, z));
|
||||
vertices.Add(new Vector3(x, y, z));
|
||||
|
||||
triangles.Add(vertexIndex);
|
||||
triangles.Add(vertexIndex+1);
|
||||
triangles.Add(vertexIndex+2);
|
||||
|
||||
triangles.Add(vertexIndex+2);
|
||||
triangles.Add(vertexIndex+3);
|
||||
triangles.Add(vertexIndex);
|
||||
|
||||
colors.Add(secondSideColor);
|
||||
colors.Add(secondSideColor);
|
||||
colors.Add(secondSideColor);
|
||||
colors.Add(secondSideColor);
|
||||
|
||||
Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Side);
|
||||
|
||||
float yMax = coords.y + coords.height - epsilon;
|
||||
float xMax = coords.x + coords.width - epsilon;
|
||||
float xMin = coords.x + epsilon;
|
||||
float yMin = coords.y + epsilon;
|
||||
|
||||
uvs.Add(new Vector2(xMin, yMin));
|
||||
uvs.Add(new Vector2(xMin, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMin));
|
||||
}
|
||||
|
||||
byte bottom;
|
||||
|
||||
if(y - 1 < 0)
|
||||
bottom = 1;
|
||||
else
|
||||
bottom = chunkSlice[x, y - 1, z];
|
||||
|
||||
if (bottom == 0)
|
||||
{
|
||||
int vertexIndex = vertices.Count;
|
||||
vertices.Add(new Vector3(x, y, z + 1));
|
||||
vertices.Add(new Vector3(x, y, z));
|
||||
vertices.Add(new Vector3(x + 1, y, z));
|
||||
vertices.Add(new Vector3(x + 1, y, z + 1));
|
||||
|
||||
triangles.Add(vertexIndex);
|
||||
triangles.Add(vertexIndex+1);
|
||||
triangles.Add(vertexIndex+2);
|
||||
|
||||
triangles.Add(vertexIndex+2);
|
||||
triangles.Add(vertexIndex+3);
|
||||
triangles.Add(vertexIndex);
|
||||
|
||||
/*triangles.Add(vertexIndex);
|
||||
triangles.Add(vertexIndex+1);
|
||||
triangles.Add(vertexIndex+2);
|
||||
triangles.Add(vertexIndex+3);*/
|
||||
|
||||
colors.Add(bottomColor);
|
||||
colors.Add(bottomColor);
|
||||
colors.Add(bottomColor);
|
||||
colors.Add(bottomColor);
|
||||
|
||||
Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Bottom);
|
||||
float yMax = coords.y + coords.height - epsilon;
|
||||
float xMax = coords.x + coords.width - epsilon;
|
||||
float xMin = coords.x + epsilon;
|
||||
float yMin = coords.y + epsilon;
|
||||
|
||||
uvs.Add(new Vector2(xMin, yMin));
|
||||
uvs.Add(new Vector2(xMin, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMax));
|
||||
uvs.Add(new Vector2(xMax, yMin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//meshFilter.mesh.Clear();
|
||||
|
||||
//meshFilter.mesh.vertices = vertices.ToArray();
|
||||
if(colors.Count != meshFilter.mesh.vertices.Length)
|
||||
UnityEngine.Debug.Log("vertices: " + meshFilter.mesh.vertices.Length + " colors: " + colors.Count);
|
||||
//meshFilter.mesh.triangles = triangles.ToArray();
|
||||
//meshFilter.mesh.uv = uvs.ToArray();
|
||||
meshFilter.mesh.colors = colors.ToArray();
|
||||
chunkSlice.ClearDirtyLight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Brickcraft.World
|
||||
|
||||
public static readonly short TotalBlockNumber = (short)(SizeX * SizeY * SizeZ);
|
||||
|
||||
private byte[] _Types = new byte[SizeX*SizeY*SizeZ];
|
||||
private byte[] _Types = new byte[SizeX * SizeY * SizeZ];
|
||||
private NibbleArray _Skylight = new NibbleArray(TotalBlockNumber / 2);
|
||||
|
||||
private short solidBlocks;
|
||||
|
||||
@@ -60,9 +60,6 @@ namespace Brickcraft.World
|
||||
Debug.Log("Terrain texture not loaded");
|
||||
}
|
||||
|
||||
GameObject camera = Camera.main.gameObject;
|
||||
camera.transform.position = new Vector3(0,160,0);
|
||||
|
||||
ChunkMeshThreadEntry[] chunkEntries = new ChunkMeshThreadEntry[ChunksNum];
|
||||
|
||||
ChunkGenManager chunkGenManager = new ChunkGenManager(MapMinChunkX, MapMaxChunkX + 1, 6, this, 13284938921, chunkEntries);
|
||||
@@ -84,51 +81,24 @@ namespace Brickcraft.World
|
||||
{
|
||||
return (ushort)((x + 127) << 8 | (z + 127));
|
||||
}
|
||||
|
||||
private void CalculateStartLight()
|
||||
{
|
||||
for(int x = MapMinChunkX; x < MapMaxChunkX + 1; ++x)
|
||||
{
|
||||
for(int z = MapMinChunkX; z < MapMaxChunkX + 1; ++z)
|
||||
{
|
||||
Chunk chunk = ChunksMap[ChunkIndexFromCoords(x,z)];
|
||||
chunk.RecalculateSkyLight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateTestLight()
|
||||
{
|
||||
for(int x = MapMinChunkX; x < MapMaxChunkX; ++x)
|
||||
{
|
||||
for(int z = MapMinChunkX; z < MapMaxChunkX; ++z)
|
||||
{
|
||||
Chunk chunk = ChunksMap[ChunkIndexFromCoords(x,z)];
|
||||
chunk.RecalculateTestSkyLight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Update () {
|
||||
/*
|
||||
foreach (Chunk chunk in ChunksMap) {
|
||||
if (chunk == null) {
|
||||
continue;
|
||||
}
|
||||
foreach (ChunkSlice slice in chunk.Slices) {
|
||||
if (slice.IsEmpty) {
|
||||
|
||||
/*
|
||||
void Update () {
|
||||
|
||||
foreach (Chunk chunk in ChunksMap) {
|
||||
if (chunk == null) {
|
||||
continue;
|
||||
}
|
||||
slice.FrustrumCulling();
|
||||
foreach (ChunkSlice slice in chunk.Slices) {
|
||||
if (slice.IsEmpty) {
|
||||
continue;
|
||||
}
|
||||
slice.FrustrumCulling();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (Input.GetKeyUp(KeyCode.Escape))
|
||||
Application.Quit();
|
||||
else if(Input.GetKeyUp(KeyCode.L))
|
||||
CalculateTestLight();
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
++accumulator;
|
||||
@@ -146,6 +116,10 @@ namespace Brickcraft.World
|
||||
{
|
||||
ChunkSliceBuildEntry chunkEntry = ChunkSlicesWorkingQueue.Dequeue();
|
||||
BuildChunkSliceMesh(chunkEntry);
|
||||
|
||||
if (ChunkSlicesWorkingQueue.Count == 0) {
|
||||
Server.Instance.spawnPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
lock(SliceLock)
|
||||
@@ -247,6 +221,7 @@ namespace Brickcraft.World
|
||||
mesh.RecalculateBounds();
|
||||
|
||||
filter.mesh = mesh;
|
||||
chunkSliceObject.GetComponent<MeshCollider>().sharedMesh = mesh;
|
||||
}
|
||||
chunkEntry.ParentChunk.ClearDirtySlices();
|
||||
}
|
||||
@@ -266,7 +241,38 @@ namespace Brickcraft.World
|
||||
|
||||
public Chunk GetChunk(int x, int z)
|
||||
{
|
||||
return ChunksMap[ChunkIndexFromCoords(x,z)];
|
||||
return ChunksMap[ChunkIndexFromCoords(x, z)];
|
||||
}
|
||||
|
||||
public static Chunk WorldCoordinateToChunk(Vector3 coordinates) {
|
||||
coordinates /= Chunk.SliceHeight;
|
||||
return ChunksMap[ChunkIndexFromCoords(Mathf.RoundToInt(coordinates.x), Mathf.RoundToInt(coordinates.z))];
|
||||
}
|
||||
|
||||
public static BlockType WorldCoordinateToBlock(Vector3 coordinates) {
|
||||
Chunk chunk = WorldCoordinateToChunk(coordinates);
|
||||
coordinates /= Chunk.SliceHeight;
|
||||
|
||||
if (chunk == null) {
|
||||
return BlockType.NULL; // We return NULL so that is different from air and we don't build side faces of the blocks
|
||||
}
|
||||
|
||||
return chunk.GetBlockType(Mathf.RoundToInt(coordinates.x) & 0xF, Mathf.RoundToInt(coordinates.y), Mathf.RoundToInt(coordinates.z) & 0xF);
|
||||
|
||||
/*
|
||||
return new Vector3Int(
|
||||
Chunk.CorrectBlockCoordinate(Mathf.RoundToInt(coordinates.x % Chunk.SliceHeight)),
|
||||
Chunk.CorrectBlockCoordinate(Mathf.RoundToInt(coordinates.y % Chunk.SliceHeight)),
|
||||
Chunk.CorrectBlockCoordinate(Mathf.RoundToInt(coordinates.z % Chunk.SliceHeight))
|
||||
);*/
|
||||
}
|
||||
|
||||
public static Vector3 WorldCoordinateToBlockCoordinate(Vector3 coordinates) {
|
||||
return new Vector3(
|
||||
Mathf.RoundToInt(coordinates.x) * Server.brickWidth,
|
||||
Mathf.RoundToInt(coordinates.y) * Server.brickHeight,
|
||||
Mathf.RoundToInt(coordinates.z) * Server.brickWidth
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user