feat(textures): atlas blocs tileable + UV mapping Chunk.gd (supprime vertex colors)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
BIN
assets/textures/block_atlas.png
Normal file
BIN
assets/textures/block_atlas.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
181
assets/textures/gen_atlas.py
Normal file
181
assets/textures/gen_atlas.py
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
"""
|
||||||
|
Generate block_atlas.png — 4x4 atlas (256x256), 64x64 tiles
|
||||||
|
Row 0: SAND, ROCK, CORAL_RED, CORAL_BLUE
|
||||||
|
Row 1: KELP, WRECK_WOOD, ICE, BEDROCK
|
||||||
|
Row 2-3: unused (blank)
|
||||||
|
"""
|
||||||
|
from PIL import Image, ImageDraw
|
||||||
|
import random
|
||||||
|
|
||||||
|
TILE = 64
|
||||||
|
ATLAS_COLS = 4
|
||||||
|
ATLAS_ROWS = 4
|
||||||
|
W = TILE * ATLAS_COLS
|
||||||
|
H = TILE * ATLAS_ROWS
|
||||||
|
|
||||||
|
atlas = Image.new("RGBA", (W, H), (0, 0, 0, 255))
|
||||||
|
|
||||||
|
|
||||||
|
def noise_tile(base_color, variation=20, seed=0):
|
||||||
|
r = random.Random(seed)
|
||||||
|
img = Image.new("RGBA", (TILE, TILE))
|
||||||
|
px = img.load()
|
||||||
|
br, bg, bb = base_color
|
||||||
|
for y in range(TILE):
|
||||||
|
for x in range(TILE):
|
||||||
|
v = r.randint(-variation, variation)
|
||||||
|
px[x, y] = (
|
||||||
|
max(0, min(255, br + v)),
|
||||||
|
max(0, min(255, bg + v)),
|
||||||
|
max(0, min(255, bb + v)),
|
||||||
|
255
|
||||||
|
)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def sand_tile():
|
||||||
|
img = noise_tile((194, 178, 128), variation=18, seed=2)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(2)
|
||||||
|
for _ in range(60):
|
||||||
|
x, y = r.randint(0, TILE-1), r.randint(0, TILE-1)
|
||||||
|
c = r.randint(160, 210)
|
||||||
|
draw.point((x, y), fill=(c, c-10, c-30, 255))
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def rock_tile():
|
||||||
|
img = noise_tile((115, 115, 115), variation=25, seed=3)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(3)
|
||||||
|
for _ in range(4):
|
||||||
|
y = r.randint(5, TILE-5)
|
||||||
|
x0 = r.randint(0, 10)
|
||||||
|
x1 = r.randint(TILE-10, TILE-1)
|
||||||
|
draw.line([(x0, y), (x1, y + r.randint(-2, 2))], fill=(80, 80, 80, 255), width=1)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def coral_red_tile():
|
||||||
|
img = noise_tile((230, 64, 52), variation=15, seed=4)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(4)
|
||||||
|
for _ in range(20):
|
||||||
|
x, y = r.randint(0, TILE-3), r.randint(0, TILE-3)
|
||||||
|
draw.ellipse([x, y, x+2, y+2], fill=(255, 200, 180, 255))
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def coral_blue_tile():
|
||||||
|
img = noise_tile((51, 127, 242), variation=15, seed=5)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(5)
|
||||||
|
for _ in range(20):
|
||||||
|
x, y = r.randint(0, TILE-3), r.randint(0, TILE-3)
|
||||||
|
draw.ellipse([x, y, x+2, y+2], fill=(180, 220, 255, 255))
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def kelp_tile():
|
||||||
|
img = noise_tile((38, 153, 51), variation=12, seed=6)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(6)
|
||||||
|
for i in range(0, TILE, 8):
|
||||||
|
x = i + r.randint(-2, 2)
|
||||||
|
draw.line([(x, 0), (x, TILE-1)], fill=(20, 100, 30, 255), width=2)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def wood_tile():
|
||||||
|
img = noise_tile((89, 56, 31), variation=12, seed=7)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(7)
|
||||||
|
for i in range(0, TILE, 6):
|
||||||
|
y = i + r.randint(-1, 1)
|
||||||
|
shade = r.randint(50, 90)
|
||||||
|
draw.line([(0, y), (TILE-1, y + r.randint(-1, 1))], fill=(shade, shade//2, shade//4, 255), width=1)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def ice_tile():
|
||||||
|
img = noise_tile((191, 230, 255), variation=10, seed=8)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(8)
|
||||||
|
for _ in range(5):
|
||||||
|
x0, y0 = r.randint(0, TILE-1), r.randint(0, TILE-1)
|
||||||
|
x1 = x0 + r.randint(-15, 15)
|
||||||
|
y1 = y0 + r.randint(-15, 15)
|
||||||
|
draw.line([(x0, y0), (x1, y1)], fill=(140, 200, 240, 255), width=1)
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def bedrock_tile():
|
||||||
|
img = noise_tile((38, 38, 38), variation=10, seed=9)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(9)
|
||||||
|
for _ in range(12):
|
||||||
|
x, y = r.randint(0, TILE-5), r.randint(0, TILE-5)
|
||||||
|
c = r.randint(20, 50)
|
||||||
|
draw.ellipse([x, y, x+4, y+4], fill=(c, c, c, 255))
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def glow_coral_cyan_tile():
|
||||||
|
img = noise_tile((51, 204, 255), variation=12, seed=10)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(10)
|
||||||
|
for _ in range(25):
|
||||||
|
x, y = r.randint(0, TILE-3), r.randint(0, TILE-3)
|
||||||
|
draw.ellipse([x, y, x+3, y+3], fill=(180, 255, 255, 255))
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def glow_coral_violet_tile():
|
||||||
|
img = noise_tile((178, 77, 230), variation=12, seed=11)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(11)
|
||||||
|
for _ in range(25):
|
||||||
|
x, y = r.randint(0, TILE-3), r.randint(0, TILE-3)
|
||||||
|
draw.ellipse([x, y, x+3, y+3], fill=(230, 180, 255, 255))
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
def lava_vent_tile():
|
||||||
|
img = noise_tile((60, 30, 10), variation=10, seed=12)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
r = random.Random(12)
|
||||||
|
# glowing cracks in orange/red
|
||||||
|
for _ in range(8):
|
||||||
|
x0, y0 = r.randint(10, TILE-10), r.randint(10, TILE-10)
|
||||||
|
x1 = x0 + r.randint(-12, 12)
|
||||||
|
y1 = y0 + r.randint(-12, 12)
|
||||||
|
draw.line([(x0, y0), (x1, y1)], fill=(255, 120, 20, 255), width=2)
|
||||||
|
# hot center glow
|
||||||
|
for _ in range(6):
|
||||||
|
x, y = r.randint(20, TILE-20), r.randint(20, TILE-20)
|
||||||
|
draw.ellipse([x, y, x+5, y+5], fill=(255, 200, 50, 255))
|
||||||
|
return img
|
||||||
|
|
||||||
|
|
||||||
|
tiles = [
|
||||||
|
(0, 0, sand_tile()),
|
||||||
|
(1, 0, rock_tile()),
|
||||||
|
(2, 0, coral_red_tile()),
|
||||||
|
(3, 0, coral_blue_tile()),
|
||||||
|
(0, 1, kelp_tile()),
|
||||||
|
(1, 1, wood_tile()),
|
||||||
|
(2, 1, ice_tile()),
|
||||||
|
(3, 1, bedrock_tile()),
|
||||||
|
(0, 2, glow_coral_cyan_tile()),
|
||||||
|
(1, 2, glow_coral_violet_tile()),
|
||||||
|
(2, 2, lava_vent_tile()),
|
||||||
|
]
|
||||||
|
|
||||||
|
for col, row, tile in tiles:
|
||||||
|
atlas.paste(tile, (col * TILE, row * TILE))
|
||||||
|
|
||||||
|
out = "block_atlas.png"
|
||||||
|
atlas.save(out)
|
||||||
|
import os
|
||||||
|
size = os.path.getsize(out)
|
||||||
|
print(f"Atlas saved: {out} ({W}x{H}) — {size} bytes ({size//1024} Ko)")
|
||||||
@@ -10,72 +10,120 @@ enum BlockType {
|
|||||||
KELP = 6,
|
KELP = 6,
|
||||||
WRECK_WOOD = 7,
|
WRECK_WOOD = 7,
|
||||||
ICE = 8,
|
ICE = 8,
|
||||||
BEDROCK = 9
|
BEDROCK = 9,
|
||||||
|
GLOW_CORAL_CYAN = 10,
|
||||||
|
GLOW_CORAL_VIOLET = 11,
|
||||||
|
LAVA_VENT = 12
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Atlas is 4x4 tiles, each tile = 0.25 of atlas width/height
|
||||||
|
const ATLAS_TILE_SIZE: Vector2 = Vector2(0.25, 0.25)
|
||||||
|
|
||||||
const _BLOCKS: Dictionary = {
|
const _BLOCKS: Dictionary = {
|
||||||
BlockType.AIR: {
|
BlockType.AIR: {
|
||||||
"name": "Air",
|
"name": "Air",
|
||||||
"color": Color(0.0, 0.0, 0.0, 0.0),
|
"color": Color(0.0, 0.0, 0.0, 0.0),
|
||||||
"hardness": 0.0,
|
"hardness": 0.0,
|
||||||
"drops": []
|
"drops": [],
|
||||||
|
"atlas_uv": Vector2(0.0, 0.0) # unused, AIR not rendered
|
||||||
},
|
},
|
||||||
BlockType.WATER: {
|
BlockType.WATER: {
|
||||||
"name": "Eau",
|
"name": "Eau",
|
||||||
"color": Color(0.1, 0.4, 0.8, 0.6),
|
"color": Color(0.1, 0.4, 0.8, 0.6),
|
||||||
"hardness": 0.0,
|
"hardness": 0.0,
|
||||||
"drops": []
|
"drops": [],
|
||||||
|
"atlas_uv": Vector2(0.0, 0.0) # unused, WATER not solid
|
||||||
},
|
},
|
||||||
BlockType.SAND: {
|
BlockType.SAND: {
|
||||||
"name": "Sable",
|
"name": "Sable",
|
||||||
"color": Color(0.76, 0.70, 0.50, 1.0),
|
"color": Color(0.76, 0.70, 0.50, 1.0),
|
||||||
"hardness": 0.5,
|
"hardness": 0.5,
|
||||||
"drops": [BlockType.SAND]
|
"drops": [BlockType.SAND],
|
||||||
|
"atlas_uv": Vector2(0.0, 0.0) # row 0, col 0
|
||||||
},
|
},
|
||||||
BlockType.ROCK: {
|
BlockType.ROCK: {
|
||||||
"name": "Roche",
|
"name": "Roche",
|
||||||
"color": Color(0.45, 0.45, 0.45, 1.0),
|
"color": Color(0.45, 0.45, 0.45, 1.0),
|
||||||
"hardness": 2.0,
|
"hardness": 2.0,
|
||||||
"drops": [BlockType.ROCK]
|
"drops": [BlockType.ROCK],
|
||||||
|
"atlas_uv": Vector2(0.25, 0.0) # row 0, col 1
|
||||||
},
|
},
|
||||||
BlockType.CORAL_RED: {
|
BlockType.CORAL_RED: {
|
||||||
"name": "Corail Rouge",
|
"name": "Corail Rouge",
|
||||||
"color": Color(0.90, 0.25, 0.20, 1.0),
|
"color": Color(0.90, 0.25, 0.20, 1.0),
|
||||||
"hardness": 0.3,
|
"hardness": 0.3,
|
||||||
"drops": [BlockType.CORAL_RED]
|
"drops": [BlockType.CORAL_RED],
|
||||||
|
"atlas_uv": Vector2(0.5, 0.0) # row 0, col 2
|
||||||
},
|
},
|
||||||
BlockType.CORAL_BLUE: {
|
BlockType.CORAL_BLUE: {
|
||||||
"name": "Corail Bleu",
|
"name": "Corail Bleu",
|
||||||
"color": Color(0.20, 0.50, 0.95, 1.0),
|
"color": Color(0.20, 0.50, 0.95, 1.0),
|
||||||
"hardness": 0.3,
|
"hardness": 0.3,
|
||||||
"drops": [BlockType.CORAL_BLUE]
|
"drops": [BlockType.CORAL_BLUE],
|
||||||
|
"atlas_uv": Vector2(0.75, 0.0) # row 0, col 3
|
||||||
},
|
},
|
||||||
BlockType.KELP: {
|
BlockType.KELP: {
|
||||||
"name": "Algue",
|
"name": "Algue",
|
||||||
"color": Color(0.15, 0.60, 0.20, 1.0),
|
"color": Color(0.15, 0.60, 0.20, 1.0),
|
||||||
"hardness": 0.1,
|
"hardness": 0.1,
|
||||||
"drops": [BlockType.KELP]
|
"drops": [BlockType.KELP],
|
||||||
|
"atlas_uv": Vector2(0.0, 0.25) # row 1, col 0
|
||||||
},
|
},
|
||||||
BlockType.WRECK_WOOD: {
|
BlockType.WRECK_WOOD: {
|
||||||
"name": "Bois d'Épave",
|
"name": "Bois d'Épave",
|
||||||
"color": Color(0.35, 0.22, 0.12, 1.0),
|
"color": Color(0.35, 0.22, 0.12, 1.0),
|
||||||
"hardness": 1.0,
|
"hardness": 1.0,
|
||||||
"drops": [BlockType.WRECK_WOOD]
|
"drops": [BlockType.WRECK_WOOD],
|
||||||
|
"atlas_uv": Vector2(0.25, 0.25) # row 1, col 1
|
||||||
},
|
},
|
||||||
BlockType.ICE: {
|
BlockType.ICE: {
|
||||||
"name": "Glace",
|
"name": "Glace",
|
||||||
"color": Color(0.75, 0.90, 1.0, 0.85),
|
"color": Color(0.75, 0.90, 1.0, 0.85),
|
||||||
"hardness": 0.8,
|
"hardness": 0.8,
|
||||||
"drops": []
|
"drops": [],
|
||||||
|
"atlas_uv": Vector2(0.5, 0.25) # row 1, col 2
|
||||||
},
|
},
|
||||||
BlockType.BEDROCK: {
|
BlockType.BEDROCK: {
|
||||||
"name": "Bedrock",
|
"name": "Bedrock",
|
||||||
"color": Color(0.15, 0.15, 0.15, 1.0),
|
"color": Color(0.15, 0.15, 0.15, 1.0),
|
||||||
"hardness": -1.0,
|
"hardness": -1.0,
|
||||||
"drops": []
|
"drops": [],
|
||||||
|
"atlas_uv": Vector2(0.75, 0.25) # row 1, col 3
|
||||||
|
},
|
||||||
|
BlockType.GLOW_CORAL_CYAN: {
|
||||||
|
"name": "Corail Bio Cyan",
|
||||||
|
"color": Color(0.2, 0.8, 1.0, 1.0),
|
||||||
|
"hardness": 0.3,
|
||||||
|
"drops": [BlockType.GLOW_CORAL_CYAN],
|
||||||
|
"atlas_uv": Vector2(0.0, 0.5), # row 2, col 0
|
||||||
|
"emission": Color(0.2, 0.8, 1.0),
|
||||||
|
"emission_energy": 3.0
|
||||||
|
},
|
||||||
|
BlockType.GLOW_CORAL_VIOLET: {
|
||||||
|
"name": "Corail Bio Violet",
|
||||||
|
"color": Color(0.7, 0.3, 0.9, 1.0),
|
||||||
|
"hardness": 0.3,
|
||||||
|
"drops": [BlockType.GLOW_CORAL_VIOLET],
|
||||||
|
"atlas_uv": Vector2(0.25, 0.5), # row 2, col 1
|
||||||
|
"emission": Color(0.7, 0.3, 0.9),
|
||||||
|
"emission_energy": 3.0
|
||||||
|
},
|
||||||
|
BlockType.LAVA_VENT: {
|
||||||
|
"name": "Cheminée Hydrothermale",
|
||||||
|
"color": Color(1.0, 0.5, 0.1, 1.0),
|
||||||
|
"hardness": 3.0,
|
||||||
|
"drops": [BlockType.LAVA_VENT],
|
||||||
|
"atlas_uv": Vector2(0.5, 0.5), # row 2, col 2
|
||||||
|
"emission": Color(1.0, 0.5, 0.1),
|
||||||
|
"emission_energy": 3.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func get_atlas_uv(id: int) -> Vector2:
|
||||||
|
if _BLOCKS.has(id):
|
||||||
|
return _BLOCKS[id]["atlas_uv"]
|
||||||
|
return Vector2(0.0, 0.0)
|
||||||
|
|
||||||
func is_solid(id: int) -> bool:
|
func is_solid(id: int) -> bool:
|
||||||
if id == BlockType.AIR or id == BlockType.WATER or id == BlockType.KELP:
|
if id == BlockType.AIR or id == BlockType.WATER or id == BlockType.KELP:
|
||||||
return false
|
return false
|
||||||
@@ -100,3 +148,18 @@ func get_drops(id: int) -> Array:
|
|||||||
if _BLOCKS.has(id):
|
if _BLOCKS.has(id):
|
||||||
return _BLOCKS[id]["drops"]
|
return _BLOCKS[id]["drops"]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
func is_emissive(id: int) -> bool:
|
||||||
|
if _BLOCKS.has(id):
|
||||||
|
return _BLOCKS[id].has("emission")
|
||||||
|
return false
|
||||||
|
|
||||||
|
func get_emission_color(id: int) -> Color:
|
||||||
|
if _BLOCKS.has(id) and _BLOCKS[id].has("emission"):
|
||||||
|
return _BLOCKS[id]["emission"]
|
||||||
|
return Color(0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
func get_emission_energy(id: int) -> float:
|
||||||
|
if _BLOCKS.has(id) and _BLOCKS[id].has("emission_energy"):
|
||||||
|
return _BLOCKS[id]["emission_energy"]
|
||||||
|
return 1.0
|
||||||
|
|||||||
@@ -7,6 +7,16 @@ var _blocks: PackedInt32Array = PackedInt32Array()
|
|||||||
var _mesh_instance: MeshInstance3D = null
|
var _mesh_instance: MeshInstance3D = null
|
||||||
var _static_body: StaticBody3D = null
|
var _static_body: StaticBody3D = null
|
||||||
|
|
||||||
|
static var shared_material: StandardMaterial3D = null
|
||||||
|
|
||||||
|
static func _init_material() -> void:
|
||||||
|
if shared_material == null:
|
||||||
|
shared_material = StandardMaterial3D.new()
|
||||||
|
shared_material.albedo_texture = load("res://assets/textures/block_atlas.png")
|
||||||
|
shared_material.texture_filter = BaseMaterial3D.TEXTURE_FILTER_NEAREST_WITH_MIPMAPS
|
||||||
|
shared_material.vertex_color_use_as_albedo = false
|
||||||
|
shared_material.shading_mode = BaseMaterial3D.SHADING_MODE_PER_VERTEX
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if _blocks.size() == 0:
|
if _blocks.size() == 0:
|
||||||
_blocks.resize(4096)
|
_blocks.resize(4096)
|
||||||
@@ -32,11 +42,16 @@ func generate_mesh() -> void:
|
|||||||
_static_body.queue_free()
|
_static_body.queue_free()
|
||||||
_static_body = null
|
_static_body = null
|
||||||
|
|
||||||
|
_init_material()
|
||||||
|
|
||||||
var st: SurfaceTool = SurfaceTool.new()
|
var st: SurfaceTool = SurfaceTool.new()
|
||||||
st.begin(Mesh.PRIMITIVE_TRIANGLES)
|
st.begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||||
|
|
||||||
var has_faces: bool = false
|
var has_faces: bool = false
|
||||||
|
|
||||||
|
var tile_w: float = BlockDatabase.ATLAS_TILE_SIZE.x
|
||||||
|
var tile_h: float = BlockDatabase.ATLAS_TILE_SIZE.y
|
||||||
|
|
||||||
for x: int in range(CHUNK_SIZE):
|
for x: int in range(CHUNK_SIZE):
|
||||||
for y: int in range(CHUNK_SIZE):
|
for y: int in range(CHUNK_SIZE):
|
||||||
for z: int in range(CHUNK_SIZE):
|
for z: int in range(CHUNK_SIZE):
|
||||||
@@ -44,25 +59,25 @@ func generate_mesh() -> void:
|
|||||||
if not BlockDatabase.is_solid(block_id):
|
if not BlockDatabase.is_solid(block_id):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
var color: Color = BlockDatabase.get_color(block_id)
|
var uv_tl: Vector2 = BlockDatabase.get_atlas_uv(block_id)
|
||||||
|
|
||||||
if not _is_opaque_at(x, y + 1, z):
|
if not _is_opaque_at(x, y + 1, z):
|
||||||
_add_face_top(st, x, y, z, color)
|
_add_face_top(st, x, y, z, uv_tl, tile_w, tile_h)
|
||||||
has_faces = true
|
has_faces = true
|
||||||
if not _is_opaque_at(x, y - 1, z):
|
if not _is_opaque_at(x, y - 1, z):
|
||||||
_add_face_bottom(st, x, y, z, color)
|
_add_face_bottom(st, x, y, z, uv_tl, tile_w, tile_h)
|
||||||
has_faces = true
|
has_faces = true
|
||||||
if not _is_opaque_at(x + 1, y, z):
|
if not _is_opaque_at(x + 1, y, z):
|
||||||
_add_face_right(st, x, y, z, color)
|
_add_face_right(st, x, y, z, uv_tl, tile_w, tile_h)
|
||||||
has_faces = true
|
has_faces = true
|
||||||
if not _is_opaque_at(x - 1, y, z):
|
if not _is_opaque_at(x - 1, y, z):
|
||||||
_add_face_left(st, x, y, z, color)
|
_add_face_left(st, x, y, z, uv_tl, tile_w, tile_h)
|
||||||
has_faces = true
|
has_faces = true
|
||||||
if not _is_opaque_at(x, y, z + 1):
|
if not _is_opaque_at(x, y, z + 1):
|
||||||
_add_face_front(st, x, y, z, color)
|
_add_face_front(st, x, y, z, uv_tl, tile_w, tile_h)
|
||||||
has_faces = true
|
has_faces = true
|
||||||
if not _is_opaque_at(x, y, z - 1):
|
if not _is_opaque_at(x, y, z - 1):
|
||||||
_add_face_back(st, x, y, z, color)
|
_add_face_back(st, x, y, z, uv_tl, tile_w, tile_h)
|
||||||
has_faces = true
|
has_faces = true
|
||||||
|
|
||||||
if not has_faces:
|
if not has_faces:
|
||||||
@@ -70,15 +85,11 @@ func generate_mesh() -> void:
|
|||||||
|
|
||||||
st.generate_normals()
|
st.generate_normals()
|
||||||
|
|
||||||
var mat: StandardMaterial3D = StandardMaterial3D.new()
|
|
||||||
mat.vertex_color_use_as_albedo = true
|
|
||||||
mat.shading_mode = BaseMaterial3D.SHADING_MODE_PER_VERTEX
|
|
||||||
st.set_material(mat)
|
|
||||||
|
|
||||||
var mesh: ArrayMesh = st.commit()
|
var mesh: ArrayMesh = st.commit()
|
||||||
|
|
||||||
_mesh_instance = MeshInstance3D.new()
|
_mesh_instance = MeshInstance3D.new()
|
||||||
_mesh_instance.mesh = mesh
|
_mesh_instance.mesh = mesh
|
||||||
|
_mesh_instance.material_override = shared_material
|
||||||
add_child(_mesh_instance)
|
add_child(_mesh_instance)
|
||||||
|
|
||||||
var shape: ConcavePolygonShape3D = ConcavePolygonShape3D.new()
|
var shape: ConcavePolygonShape3D = ConcavePolygonShape3D.new()
|
||||||
@@ -96,80 +107,109 @@ func _is_opaque_at(x: int, y: int, z: int) -> bool:
|
|||||||
return false
|
return false
|
||||||
return BlockDatabase.is_solid(get_block(x, y, z))
|
return BlockDatabase.is_solid(get_block(x, y, z))
|
||||||
|
|
||||||
func _add_face_top(st: SurfaceTool, x: int, y: int, z: int, color: Color) -> void:
|
# UV layout for a quad: TL, TR, BR, BL
|
||||||
|
# Face vertices are added as two triangles: TL-TR-BR and TL-BR-BL
|
||||||
|
|
||||||
|
func _add_face_top(st: SurfaceTool, x: int, y: int, z: int, uv_tl: Vector2, tw: float, th: float) -> void:
|
||||||
var fx: float = float(x)
|
var fx: float = float(x)
|
||||||
var fy: float = float(y)
|
var fy: float = float(y)
|
||||||
var fz: float = float(z)
|
var fz: float = float(z)
|
||||||
st.set_color(color)
|
# tri 1
|
||||||
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, 0.0))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
||||||
st.set_color(color)
|
# tri 2
|
||||||
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(0.0, th))
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz + 1.0))
|
||||||
|
|
||||||
func _add_face_bottom(st: SurfaceTool, x: int, y: int, z: int, color: Color) -> void:
|
func _add_face_bottom(st: SurfaceTool, x: int, y: int, z: int, uv_tl: Vector2, tw: float, th: float) -> void:
|
||||||
var fx: float = float(x)
|
var fx: float = float(x)
|
||||||
var fy: float = float(y)
|
var fy: float = float(y)
|
||||||
var fz: float = float(z)
|
var fz: float = float(z)
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, 0.0))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(0.0, th))
|
||||||
st.add_vertex(Vector3(fx, fy, fz))
|
st.add_vertex(Vector3(fx, fy, fz))
|
||||||
|
|
||||||
func _add_face_right(st: SurfaceTool, x: int, y: int, z: int, color: Color) -> void:
|
func _add_face_right(st: SurfaceTool, x: int, y: int, z: int, uv_tl: Vector2, tw: float, th: float) -> void:
|
||||||
var fx: float = float(x)
|
var fx: float = float(x)
|
||||||
var fy: float = float(y)
|
var fy: float = float(y)
|
||||||
var fz: float = float(z)
|
var fz: float = float(z)
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, 0.0))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(0.0, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz))
|
||||||
|
|
||||||
func _add_face_left(st: SurfaceTool, x: int, y: int, z: int, color: Color) -> void:
|
func _add_face_left(st: SurfaceTool, x: int, y: int, z: int, uv_tl: Vector2, tw: float, th: float) -> void:
|
||||||
var fx: float = float(x)
|
var fx: float = float(x)
|
||||||
var fy: float = float(y)
|
var fy: float = float(y)
|
||||||
var fz: float = float(z)
|
var fz: float = float(z)
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, 0.0))
|
||||||
st.add_vertex(Vector3(fx, fy, fz))
|
st.add_vertex(Vector3(fx, fy, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(0.0, th))
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz + 1.0))
|
||||||
|
|
||||||
func _add_face_front(st: SurfaceTool, x: int, y: int, z: int, color: Color) -> void:
|
func _add_face_front(st: SurfaceTool, x: int, y: int, z: int, uv_tl: Vector2, tw: float, th: float) -> void:
|
||||||
var fx: float = float(x)
|
var fx: float = float(x)
|
||||||
var fy: float = float(y)
|
var fy: float = float(y)
|
||||||
var fz: float = float(z)
|
var fz: float = float(z)
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, 0.0))
|
||||||
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz + 1.0))
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz + 1.0))
|
||||||
|
st.set_uv(uv_tl + Vector2(0.0, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz + 1.0))
|
||||||
|
|
||||||
func _add_face_back(st: SurfaceTool, x: int, y: int, z: int, color: Color) -> void:
|
func _add_face_back(st: SurfaceTool, x: int, y: int, z: int, uv_tl: Vector2, tw: float, th: float) -> void:
|
||||||
var fx: float = float(x)
|
var fx: float = float(x)
|
||||||
var fy: float = float(y)
|
var fy: float = float(y)
|
||||||
var fz: float = float(z)
|
var fz: float = float(z)
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx, fy, fz))
|
st.add_vertex(Vector3(fx, fy, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, 0.0))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz))
|
||||||
st.set_color(color)
|
st.set_uv(uv_tl)
|
||||||
st.add_vertex(Vector3(fx, fy, fz))
|
st.add_vertex(Vector3(fx, fy, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(tw, th))
|
||||||
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx + 1.0, fy + 1.0, fz))
|
||||||
|
st.set_uv(uv_tl + Vector2(0.0, th))
|
||||||
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
st.add_vertex(Vector3(fx, fy + 1.0, fz))
|
||||||
|
|||||||
Reference in New Issue
Block a user