-
Notifications
You must be signed in to change notification settings - Fork 1
/
PolyGen.gd
111 lines (88 loc) · 2.86 KB
/
PolyGen.gd
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
@tool
extends Node3D
# Author: Jason Rametta
@export var sides: int = 8
@export var layers: int = 5
@export var width_curve: Curve
@export var height_curve: Curve
@export var x_offset_curve: Curve
@export var material: StandardMaterial3D = StandardMaterial3D.new()
@export var uv_scale: Vector2 = Vector2(1.0, 1.0)
@onready var mesh_instance: MeshInstance3D = $MeshInstance3D
func uv(vertex: Vector3) -> Vector2:
var normed = vertex.normalized()
return abs(Vector2(normed.x, normed.y) * uv_scale)
func _process(_delta) -> void:
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.set_material(material)
var center = Vector3.ZERO
st.set_uv(uv(center))
st.add_vertex(center)
var points_index = 0
var first_width_sample = width_curve.sample(0)
for side in range(sides):
var u = float(side) / sides
var x = cos(u * PI * 2.0) * first_width_sample
var z = sin(u * PI * 2.0) * first_width_sample
var point = Vector3(x, 0, z)
st.set_uv(uv(point))
st.add_vertex(point)
points_index += 1
if side > 1:
st.add_index(side - 1)
st.add_index(side)
st.add_index(0)
st.add_index(sides)
st.add_index(1)
st.add_index(0)
st.add_index(0)
st.add_index(sides - 1)
st.add_index(sides)
for layer in range(layers):
var curve_sample = float(layer) / float(layers)
var width_sample = width_curve.sample(curve_sample)
var height_sample = height_curve.sample(curve_sample)
var x_offset_sample = x_offset_curve.sample(curve_sample)
var y = height_sample * layer
var prev_row_first_index = points_index - sides + 1
var prev_row_last_index = points_index
var this_row_first_index = points_index + 1
for side in range(sides):
var u = float(side) / sides
var x = cos(u * PI * 2.0) * width_sample + x_offset_sample
var z = sin(u * PI * 2.0) * width_sample
var point = Vector3(x, y, z)
st.set_uv(uv(point))
st.add_vertex(point)
points_index += 1
if side > 0:
st.add_index(points_index)
st.add_index(points_index - sides)
st.add_index(points_index - sides - 1)
st.add_index(points_index - sides - 1)
st.add_index(points_index - 1)
st.add_index(points_index)
st.add_index(prev_row_first_index)
st.add_index(points_index)
st.add_index(this_row_first_index)
st.add_index(points_index)
st.add_index(prev_row_first_index)
st.add_index(prev_row_last_index)
# close the shape
var height_sample_last = height_curve.sample(1)
var y = height_sample_last * (layers - 1)
var last_center = Vector3(0, y, 0)
st.set_uv(uv(last_center))
st.add_vertex(last_center)
points_index += 1
for side in range(sides):
st.add_index(points_index)
st.add_index(points_index - side)
st.add_index(points_index - side - 1)
st.add_index(points_index - sides)
st.add_index(points_index - 1)
st.add_index(points_index)
st.generate_normals()
st.generate_tangents()
mesh_instance.mesh = st.commit()