xiandie/scene/ground/script/c02/s09_麻绳.gd

93 lines
2.7 KiB
GDScript

@tool
extends MeshInstance2D
@export var pixels_per_subdivision: float = 10.0 # 每个细分包含的像素数
@export_tool_button("重置 mesh") var reset_mesh = create_rope_mesh
func create_rope_mesh():
var texture_size = texture.get_size()
var texture_width = texture_size.x
var texture_height = texture_size.y
var aspect_ratio = texture_width / texture_height
# 整体缩放系数
var scale_factor := float(texture_height)
# 根据纹理宽度和期望的细分密度计算水平细分数
var horizontal_subdivisions = max(int(texture_width / pixels_per_subdivision), 1000)
# 垂直细分较少,因为麻绳主要是水平变形
var vertical_subdivisions = max(int(texture_height / pixels_per_subdivision), 10)
# 计算实际显示尺寸(保持纹理比例)
var display_width = aspect_ratio * scale_factor
var display_height = 1.0 * scale_factor
var array_mesh = ArrayMesh.new()
var arrays = []
arrays.resize(Mesh.ARRAY_MAX)
var vertices = PackedVector2Array()
var uvs = PackedVector2Array()
var indices = PackedInt32Array()
# 创建网格顶点
for y in range(vertical_subdivisions + 1):
for x in range(horizontal_subdivisions + 1):
var u = float(x) / float(horizontal_subdivisions)
var v = float(y) / float(vertical_subdivisions)
# 顶点位置(居中)
var vertex_x = (u - 0.5) * display_width
var vertex_y = (v - 0.5) * display_height
vertices.append(Vector2(vertex_x, vertex_y))
uvs.append(Vector2(u, v))
# 创建三角形索引
for y in range(vertical_subdivisions):
for x in range(horizontal_subdivisions):
var top_left = y * (horizontal_subdivisions + 1) + x
var top_right = top_left + 1
var bottom_left = (y + 1) * (horizontal_subdivisions + 1) + x
var bottom_right = bottom_left + 1
# 第一个三角形
indices.append(top_left)
indices.append(bottom_left)
indices.append(top_right)
# 第二个三角形
indices.append(top_right)
indices.append(bottom_left)
indices.append(bottom_right)
arrays[Mesh.ARRAY_VERTEX] = vertices
arrays[Mesh.ARRAY_TEX_UV] = uvs
arrays[Mesh.ARRAY_INDEX] = indices
array_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
mesh = array_mesh
print(
(
"创建网格: %dx%d 细分, 纹理尺寸: %dx%d, 显示尺寸: %.2fx%.2f"
% [
horizontal_subdivisions,
vertical_subdivisions,
texture_width,
texture_height,
display_width,
display_height
]
)
)
# 运行时调整隆起参数的便捷方法
func set_bulge(pos: float, height: float):
if material and material is ShaderMaterial:
material.set_shader_parameter("bulge_position", pos)
material.set_shader_parameter("bulge_height", height)
# material.set_shader_parameter("bulge_height", height)
# material.set_shader_parameter("bulge_width", width)