// vertex value dependent on local incline byte InclinedVertexFromOffset(int3 offset, int3 direction, int3 vecId, byte corner) { if (math.abs(direction).Equals(offset)) { return(0); } int3 directionOffset = !math.abs(direction).Equals(direction) ? new int3(0, 0, 0) : direction; byte offset_P = blocks[vecId + directionOffset + offset]; byte offset_N = blocks[vecId + directionOffset - offset]; byte offset_2P = blocks[vecId + directionOffset + offset * 2]; byte offset_2N = blocks[vecId + directionOffset - offset * 2]; if (InclineCondition.Check(offset_N, offset_P, offset_2N, offset_2P)) // incline condition { return((byte)InclineCondition.Evaluate(offset_N, offset_P, corner)); } return(0); }
// modify closest to hitInfo.point visible block private void ModifyClosestExposedBlock(RaycastHit hitInfo, int value) { Vector3 position = hitInfo.point; Vector3Int cubePosition = new Vector3Int(Mathf.FloorToInt(position.x), Mathf.FloorToInt(position.y), Mathf.FloorToInt(position.z)); float minDistance = 10; Vector3Int targetBlock = Vector3Int.zero; for (int cornerIndex = 0; cornerIndex < 8; cornerIndex++) { Vector3Int blockPosition = new Vector3Int(cubePosition.x + (cornerIndex & 1), cubePosition.y + ((cornerIndex & 2) >> 1), cubePosition.z + ((cornerIndex & 4) >> 2)); Vector3Int chunkCoord = blockPosition.ToChunkCoord(); // ProTerra.WorldPositionToChunkCoord(blockPosition); Vector3Int localBlockPosition = blockPosition.ToChunkPosition(); //ProTerra.WorldPositionToChunkPosition(blockPosition); byte blockValue = _terrain.GetBlockValue(localBlockPosition, chunkCoord); if (blockValue > 0) { for (int directionIndex = 0; directionIndex < 3; directionIndex++) { Vector3Int direction = new Vector3Int(directionIndex == 0 ? (blockPosition.x == cubePosition.x ? 1 : -1) : 0, directionIndex == 1 ? (blockPosition.y == cubePosition.y ? 1 : -1) : 0, directionIndex == 2 ? (blockPosition.z == cubePosition.z ? 1 : -1) : 0); if (_terrain.GetBlockValue(blockPosition + direction) == 0) { Vector3Int target = blockPosition; float maxVertexValue = blockValue; Vector3Int offsetDirection = Vector3Int.zero; if (directionIndex == 0) { offsetDirection.y = 1; } else { offsetDirection.x = 1; } byte offset_P = _terrain.GetBlockValue(blockPosition + direction + offsetDirection); byte offset_N = _terrain.GetBlockValue(blockPosition + direction - offsetDirection); byte offset_2P = _terrain.GetBlockValue(blockPosition + direction + offsetDirection * 2); byte offset_2N = _terrain.GetBlockValue(blockPosition + direction - offsetDirection * 2); if (InclineCondition.Check(offset_N, offset_P, offset_2N, offset_2P)) { float vertexValue = InclineCondition.Evaluate(offset_N, offset_P, blockValue); if (vertexValue > maxVertexValue) { maxVertexValue = vertexValue; target = blockPosition + direction + (offset_N > 0 ? -offsetDirection : offsetDirection); } } offsetDirection = Vector3Int.zero; if (directionIndex == 2) { offsetDirection.y = 1; } else { offsetDirection.z = 1; } offset_P = _terrain.GetBlockValue(blockPosition + direction + offsetDirection); offset_N = _terrain.GetBlockValue(blockPosition + direction - offsetDirection); offset_2P = _terrain.GetBlockValue(blockPosition + direction + offsetDirection * 2); offset_2N = _terrain.GetBlockValue(blockPosition + direction - offsetDirection * 2); if (InclineCondition.Check(offset_N, offset_P, offset_2N, offset_2P)) { float vertexValue = InclineCondition.Evaluate(offset_N, offset_P, blockValue); if (vertexValue > maxVertexValue) { maxVertexValue = vertexValue; target = blockPosition + direction + (offset_N > 0 ? -offsetDirection : offsetDirection); } } float distance = (target - position).magnitude; if (distance < minDistance) { minDistance = distance; targetBlock = target; } } } } } if (minDistance < 10) { _terrain.ModifyBlock(targetBlock, value); } }