MeshData GetMesh(NBTChunk chunk, Vector3Int pos) { byte eastType = chunk.GetBlockByte(pos + Vector3Int.right); bool eastConnect = !NBTGeneratorManager.IsTransparent(eastType) || NBTGeneratorManager.IsFence(eastType); byte southType = chunk.GetBlockByte(pos + Vector3Int.back); bool southConnect = !NBTGeneratorManager.IsTransparent(southType) || NBTGeneratorManager.IsFence(southType); byte westType = chunk.GetBlockByte(pos + Vector3Int.left); bool westConnect = !NBTGeneratorManager.IsTransparent(westType) || NBTGeneratorManager.IsFence(westType); byte northType = chunk.GetBlockByte(pos + Vector3Int.forward); bool northConnect = !NBTGeneratorManager.IsTransparent(northType) || NBTGeneratorManager.IsFence(northType); int index = 0; if (westConnect) { index += 8; } if (northConnect) { index += 4; } if (eastConnect) { index += 2; } if (southConnect) { index += 1; } return(meshes[index]); }
//input is local position public bool HasOpaqueBlock(int xInChunk, int worldY, int zInChunk) { byte type = GetBlockByte(xInChunk, worldY, zInChunk); return(!NBTGeneratorManager.IsTransparent(type)); }
public override void AddCube(NBTChunk chunk, byte blockData, Vector3Int pos, NBTGameObject nbtGO) { ca.pos = pos; ca.blockData = blockData; chunk.GetBlockData(pos.x, pos.y, pos.z - 1, out byte frontType, out byte frontData); chunk.GetBlockData(pos.x, pos.y, pos.z + 1, out byte backType, out byte backData); chunk.GetBlockData(pos.x - 1, pos.y, pos.z, out byte leftType, out byte leftData); chunk.GetBlockData(pos.x + 1, pos.y, pos.z, out byte rightType, out byte rightData); chunk.GetBlockData(pos.x, pos.y - 1, pos.z, out byte bottomType, out byte bottomData); chunk.GetBlockData(pos.x, pos.y + 1, pos.z, out byte topType, out byte topData); bool selfIsVerticalWater = IsVerticalWater(blockData); chunk.GetLights(pos.x, pos.y, pos.z, out float skyLight, out float blockLight); fa.color = Color.white; fa.skyLight = skylight_default; fa.blockLight = blocklight_default; fa.uv = uv_zero; if (NBTGeneratorManager.IsTransparent(frontType) && frontType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = nearBottomLeft; fa.pos[1] = nearTopLeft; fa.pos[2] = nearTopRight; fa.pos[3] = nearBottomRight; } else { fa.pos[0] = nearBottomLeft; fa.pos[1] = nearTopLeft_still; fa.pos[2] = nearTopRight_still; fa.pos[3] = nearBottomRight; } fa.normal = Vector3.forward; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(backType) && backType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = farBottomRight; fa.pos[1] = farTopRight; fa.pos[2] = farTopLeft; fa.pos[3] = farBottomLeft; } else { fa.pos[0] = farBottomRight; fa.pos[1] = farTopRight_still; fa.pos[2] = farTopLeft_still; fa.pos[3] = farBottomLeft; } fa.normal = Vector3.back; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(leftType) && leftType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = farBottomLeft; fa.pos[1] = farTopLeft; fa.pos[2] = nearTopLeft; fa.pos[3] = nearBottomLeft; } else { fa.pos[0] = farBottomLeft; fa.pos[1] = farTopLeft_still; fa.pos[2] = nearTopLeft_still; fa.pos[3] = nearBottomLeft; } fa.normal = Vector3.left; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(rightType) && rightType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = nearBottomRight; fa.pos[1] = nearTopRight; fa.pos[2] = farTopRight; fa.pos[3] = farBottomRight; } else { fa.pos[0] = nearBottomRight; fa.pos[1] = nearTopRight_still; fa.pos[2] = farTopRight_still; fa.pos[3] = farBottomRight; } fa.normal = Vector3.right; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(topType) && topType != TYPE_WATER) { if (selfIsVerticalWater) { fa.pos[0] = farTopRight; fa.pos[1] = nearTopRight; fa.pos[2] = nearTopLeft; fa.pos[3] = farTopLeft; } else { bool leftIsVerticalWater = IsVerticalWater(leftData, leftType); bool rightIsVerticalWater = IsVerticalWater(rightData, rightType); bool frontIsVerticalWater = IsVerticalWater(frontData, frontType); bool backIsVerticalWater = IsVerticalWater(backData, backType); fa.pos[0] = backIsVerticalWater || rightIsVerticalWater ? farTopRight : farTopRight_still; fa.pos[1] = frontIsVerticalWater || rightIsVerticalWater ? nearTopRight : nearTopRight_still; fa.pos[2] = frontIsVerticalWater || leftIsVerticalWater ? nearTopLeft : nearTopLeft_still; fa.pos[3] = backIsVerticalWater || leftIsVerticalWater ? farTopLeft : farTopLeft_still; } fa.normal = Vector3.up; AddFace(nbtGO.nbtMesh, fa, ca); } if (NBTGeneratorManager.IsTransparent(bottomType) && bottomType != TYPE_WATER) { fa.pos[0] = nearBottomRight; fa.pos[1] = farBottomRight; fa.pos[2] = farBottomLeft; fa.pos[3] = nearBottomLeft; fa.normal = Vector3.down; AddFace(nbtGO.nbtMesh, fa, ca); } }
bool ShouldAddFace(byte type) { return(NBTGeneratorManager.IsTransparent(type) && type != TYPE_WATER); }
public static void UpdateLighting(int x, int y, int z) { //Debug.Log("update lighting"); //float start = Time.realtimeSinceStartup; Queue <Vector3Int> skyLightQueue = new Queue <Vector3Int>(); Vector3Int p = new Vector3Int(); // init for (int i = -15; i <= 15; i++) { for (int j = -15; j <= 15; j++) { p.Set(x + i, y, z + j); int chunkX = Mathf.FloorToInt(p.x / 16f); int chunkZ = Mathf.FloorToInt(p.z / 16f); int xInChunk = p.x - chunkX * 16; int zInChunk = p.z - chunkZ * 16; NBTChunk chunk = GetChunk(chunkX, chunkZ); for (int temp_y = chunk.Sections.Count * 16 - 1; temp_y >= 0; temp_y--) { chunk.SetSkyLightByte(xInChunk, temp_y, zInChunk, 0); } } } HashSet <Vector3Int> skyLightSet = new HashSet <Vector3Int>(); // light from sun (no vertical falloff) for (int i = -15; i <= 15; i++) { for (int j = -15; j <= 15; j++) { p.Set(x + i, y, z + j); int chunkX = Mathf.FloorToInt(p.x / 16f); int chunkZ = Mathf.FloorToInt(p.z / 16f); int xInChunk = p.x - chunkX * 16; int zInChunk = p.z - chunkZ * 16; NBTChunk chunk = GetChunk(chunkX, chunkZ); int temp_y = chunk.Sections.Count * 16 - 1; while (NBTGeneratorManager.LightCanTravel(chunk.GetBlockByte(xInChunk, temp_y, zInChunk))) { chunk.SetSkyLightByte(xInChunk, temp_y, zInChunk, 15); skyLightSet.Add(new Vector3Int(p.x, temp_y, p.z)); if (temp_y == 0) { break; } else { temp_y--; } } } } foreach (Vector3Int skyLightPos in skyLightSet) { if (skyLightSet.Contains(skyLightPos + Vector3Int.left) && skyLightSet.Contains(skyLightPos + Vector3Int.right) && skyLightSet.Contains(skyLightPos + Vector3Int.forward) && skyLightSet.Contains(skyLightPos + Vector3Int.back)) { continue; } skyLightQueue.Enqueue(new Vector3Int(skyLightPos.x, skyLightPos.y, skyLightPos.z)); } int count = 0; int setcount = 0; // light propagation (use flood fill) Vector3Int[] arr = new Vector3Int[6]; while (skyLightQueue.Count > 0) { count++; p = skyLightQueue.Dequeue(); byte skyLight = GetSkyLightByte(p.x, p.y, p.z); arr[0] = p + Vector3Int.left; arr[1] = p + Vector3Int.right; arr[2] = p + Vector3Int.up; arr[3] = p + Vector3Int.down; arr[4] = p + Vector3Int.forward; arr[5] = p + Vector3Int.back; for (int i = 0; i < 6; i++) { Vector3Int nextPos = arr[i]; if (NBTGeneratorManager.IsTransparent(GetBlockByte(nextPos.x, nextPos.y, nextPos.z))) { byte nextSkyLight = GetSkyLightByte(nextPos.x, nextPos.y, nextPos.z); if (nextSkyLight < skyLight - 1) { setcount++; //Debug.Log("SetSkyLightByte,nextPos=" + nextPos.x + "," + nextPos.y + "," + nextPos.z); SetSkyLightByte(nextPos.x, nextPos.y, nextPos.z, (byte)(skyLight - 1)); if (skyLight > 2) { skyLightQueue.Enqueue(nextPos); } } } } } //float end = Time.realtimeSinceStartup; //Debug.Log("time cost =" + (end - start) + ", actual propagation count=" + count + ",setcount=" + setcount); }