-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathVoxel.cs
144 lines (126 loc) · 4.79 KB
/
Voxel.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using UnityEngine;
namespace Voxels
{
public static class VoxelTexture
{
public const byte Solid = 0, Checkered = 1, Striped = 2, Speckled = 3, Last = Speckled;
public static string Name(byte id) => id switch
{
Solid => nameof(Solid),
Checkered => nameof(Checkered),
Striped => nameof(Striped),
Speckled => nameof(Speckled),
_ => throw new ArgumentOutOfRangeException(nameof(id), id, null)
};
}
public static class Orientation
{
public const byte None = 0, North = 1, East = 2, South = 3, West = 4, Up = 5, Down = 6;
}
[Flags]
public enum VoxelFlags : ushort
{
None = 0,
Block = 1,
Breakable = 2,
Natural = 4,
Breathable = 8
}
public struct Voxel
{
public static readonly Color32 Dirt = new(39, 25, 10, 255),
Stone = new(39, 39, 39, 255),
// Grass = new Color32(68, 144, 71, 255),
Grass = new(68, 144, 71, 255),
Wood = new(132, 83, 40, 255);
public const float
TileSize = 256.0f,
ImageSize = 1024.0f,
TileRatio = TileSize / ImageSize,
PixelRatio = 1.0f / ImageSize;
public byte texture, density, orientation;
public VoxelFlags flags;
public Color32 color;
public bool HasBlock
{
get => (flags & VoxelFlags.Block) == VoxelFlags.Block;
private set
{
if (value) flags |= VoxelFlags.Block;
else flags &= ~VoxelFlags.Block;
}
}
public bool OnlySmooth => !HasBlock;
public bool IsBreakable
{
get => (flags & VoxelFlags.Breakable) == VoxelFlags.Breakable;
private set
{
if (value) flags |= VoxelFlags.Breakable;
else flags &= ~VoxelFlags.Breakable;
}
}
public bool IsUnbreakable => !IsBreakable;
public bool IsNatural
{
get => (flags & VoxelFlags.Natural) == VoxelFlags.Natural;
private set
{
if (value) flags |= VoxelFlags.Natural;
else flags &= ~VoxelFlags.Natural;
}
}
public bool IsBreathable
{
get => (flags & VoxelFlags.Breathable) == VoxelFlags.Breathable;
private set
{
if (value) flags |= VoxelFlags.Breathable;
else flags &= ~VoxelFlags.Breathable;
}
}
public void SetVoxelData(in VoxelChange change)
{
if (change.texture.HasValue) texture = change.texture.Value;
if (change.hasBlock.HasValue) HasBlock = change.hasBlock.Value;
if (change.density.HasValue) density = change.density.Value;
if (change.isBreakable.HasValue) IsBreakable = change.isBreakable.Value;
if (change.orientation.HasValue) orientation = change.orientation.Value;
if (change.natural.HasValue) IsNatural = change.natural.Value;
if (change.isBreathable.HasValue) IsBreathable = change.isBreathable.Value;
if (change.color.HasValue) color = change.color.Value;
}
public Vector2Int TexturePosition() => texture switch
{
VoxelTexture.Checkered => new Vector2Int(0, 0),
VoxelTexture.Solid => new Vector2Int(1, 0),
VoxelTexture.Striped => new Vector2Int(0, 1),
VoxelTexture.Speckled => new Vector2Int(1, 1),
_ => throw new ArgumentOutOfRangeException(nameof(texture), texture, null)
};
public int FaceUVs(Vector2[] uvs)
{
Vector2Int tilePos = TexturePosition();
if (HasBlock)
{
float x = TileRatio * tilePos.x, y = TileRatio * tilePos.y;
uvs[0] = new Vector2(x + TileRatio, y);
uvs[1] = new Vector2(x + TileRatio, y + TileRatio);
uvs[2] = new Vector2(x, y + TileRatio);
uvs[3] = new Vector2(x, y);
return 4;
}
else
{
float x = TileRatio * tilePos.x, y = TileRatio * tilePos.y;
uvs[0] = new Vector2(x, y);
uvs[2] = new Vector2(x + TileRatio, y);
uvs[1] = new Vector2(x, y + TileRatio);
return 3;
}
}
public override string ToString() => $"Texture: {texture}, Density: {density}, Orientation: {orientation}, Flags: {flags}";
public bool ShouldRenderBlock(byte direction) => OnlySmooth;
}
}