Align original Half-Life office walls and ceiling with explicit room UVs
This commit is contained in:
+45
-5
@@ -7,6 +7,8 @@ const W: float = 18.0 # larghezza (x)
|
||||
const D: float = 18.0 # profondita (z)
|
||||
const H: float = 5.0 # altezza (y)
|
||||
const WALL_T: float = 0.3
|
||||
const WALL_REPEAT_M := 4.0 # 128x160 texture spans 4x5m: equal texel density
|
||||
const CEILING_REPEAT_M := 1.2 # CEIL5 contains 2x2 panels: each panel = 0.6m
|
||||
|
||||
# Finestra: 4 m x 2 m, bordo basso a 1.5 m
|
||||
const WIN_W: float = 4.0
|
||||
@@ -167,7 +169,22 @@ func _add_box_to(parent: Node3D, s: Vector3, c: Vector3, m: StandardMaterial3D)
|
||||
var bm := BoxMesh.new()
|
||||
bm.size = s
|
||||
bm.material = m
|
||||
mi.mesh = bm
|
||||
if m.has_meta("office_surface"):
|
||||
# BoxMesh's per-face UVs reset on every wall segment. Rebuild only UVs;
|
||||
# geometry, normals, indices and collision boxes remain identical.
|
||||
var arrays := bm.surface_get_arrays(0)
|
||||
var vertices: PackedVector3Array = arrays[Mesh.ARRAY_VERTEX]
|
||||
var uv := PackedVector2Array()
|
||||
for vertex in vertices:
|
||||
uv.append(office_uv(vertex + c, c, m.get_meta("office_surface")))
|
||||
arrays[Mesh.ARRAY_TEX_UV] = uv
|
||||
var mesh := ArrayMesh.new()
|
||||
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
|
||||
mesh.surface_set_material(0, m)
|
||||
mi.mesh = mesh
|
||||
mi.add_to_group("office_surfaces")
|
||||
else:
|
||||
mi.mesh = bm
|
||||
parent.add_child(mi)
|
||||
var cs := CollisionShape3D.new()
|
||||
var bs := BoxShape3D.new()
|
||||
@@ -181,16 +198,39 @@ func _add_box_to(parent: Node3D, s: Vector3, c: Vector3, m: StandardMaterial3D)
|
||||
|
||||
func _surface_material(texture_name: String, rough: float) -> StandardMaterial3D:
|
||||
var material := StandardMaterial3D.new()
|
||||
material.albedo_texture = load("res://assets/textures/" + texture_name + ".png")
|
||||
var office := texture_name in ["wall", "ceiling"]
|
||||
var directory := "res://assets/textures/office/" if office else "res://assets/textures/"
|
||||
material.albedo_texture = load(directory + texture_name + ".png")
|
||||
material.albedo_color = Color.WHITE
|
||||
material.roughness = rough
|
||||
material.texture_filter = BaseMaterial3D.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC
|
||||
material.texture_repeat = true
|
||||
material.uv1_triplanar = true
|
||||
material.uv1_world_triplanar = true
|
||||
material.uv1_scale = Vector3.ONE * 0.5
|
||||
if office:
|
||||
material.set_meta("office_surface", texture_name)
|
||||
else:
|
||||
# Existing floor projection intentionally unchanged.
|
||||
material.uv1_triplanar = true
|
||||
material.uv1_world_triplanar = true
|
||||
material.uv1_scale = Vector3.ONE * 0.5
|
||||
return material
|
||||
|
||||
## Shared room-space UVs, independent of each window/wall segment size.
|
||||
static func office_uv(point: Vector3, center: Vector3, surface: String) -> Vector2:
|
||||
if surface == "ceiling":
|
||||
return Vector2(point.x + W * 0.5, point.z + D * 0.5) / CEILING_REPEAT_M
|
||||
var along: float
|
||||
if center.z < -D * 0.5:
|
||||
along = point.x + W * 0.5 # north, clockwise
|
||||
elif center.x > W * 0.5:
|
||||
along = W + point.z + D * 0.5 # east
|
||||
elif center.z > D * 0.5:
|
||||
along = W + D + W * 0.5 - point.x # south
|
||||
else:
|
||||
along = W * 2 + D + D * 0.5 - point.z # west
|
||||
# Top pixel at ceiling, bottom at floor: no vertical texture repeats.
|
||||
# Half-texel inset avoids sampling the opposite edge at exact 0/1.
|
||||
return Vector2(along / WALL_REPEAT_M, clampf(1.0 - point.y / H, 0.5 / 160.0, 1.0 - 0.5 / 160.0))
|
||||
|
||||
func _mat(color: Color, rough: float) -> StandardMaterial3D:
|
||||
var m := StandardMaterial3D.new()
|
||||
m.albedo_color = color
|
||||
|
||||
Reference in New Issue
Block a user