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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
tool
extends Reference
class_name SS2D_Edge
var quads: Array = []
var first_point_key: int = -1
var last_point_key: int = -1
var z_index: int = 0
var z_as_relative: bool = false
# If final point is connected to first point
var wrap_around: bool = false
var material: Material = null
static func different_render(q1: SS2D_Quad, q2: SS2D_Quad) -> bool:
"""
Will return true if the 2 quads must be drawn in two calls
"""
if q1.matches_quad(q2):
return false
return true
static func get_consecutive_quads_for_mesh(_quads: Array) -> Array:
if _quads.empty():
return []
var quad_ranges = []
var quad_range = []
quad_range.push_back(_quads[0])
for i in range(1, _quads.size(), 1):
var quad_prev = _quads[i - 1]
var quad = _quads[i]
if different_render(quad, quad_prev):
quad_ranges.push_back(quad_range)
quad_range = [quad]
else:
quad_range.push_back(quad)
quad_ranges.push_back(quad_range)
return quad_ranges
static func generate_array_mesh_from_quad_sequence(_quads: Array, wrap_around: bool) -> ArrayMesh:
"""
Assumes each quad in the sequence is of the same render type
same textures, values, etc...
quads passed in as an argument should have been generated by get_consecutive_quads_for_mesh
"""
if _quads.empty():
return ArrayMesh.new()
var total_length: float = 0.0
for q in _quads:
total_length += q.get_length_average()
if total_length == 0.0:
return ArrayMesh.new()
var first_quad = _quads[0]
var tex: Texture = first_quad.texture
# The change in length required to apply to each quad
# to make the textures begin and end at the start and end of each texture
var change_in_length: float = -1.0
if tex != null:
# How many times the texture is repeated
var texture_reps = round(total_length / tex.get_size().x)
# Length required to display all the reps with the texture's full width
var texture_full_length = texture_reps * tex.get_size().x
# How much each quad's texture must be offset to make up the difference in full length vs total length
change_in_length = (texture_full_length / total_length)
if first_quad.fit_texture == SS2D_Material_Edge.FITMODE.CROP:
change_in_length = 1.0
var length_elapsed: float = 0.0
var st = SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
for q in _quads:
var section_length: float = q.get_length_average() * change_in_length
var highest_value: float = max(q.get_height_left(), q.get_height_right())
# When welding and using different widths, quads can look a little weird
# This is because they are no longer parallelograms
# This is a tough problem to solve
# See http://reedbeta.com/blog/quadrilateral-interpolation-part-1/
var uv_a = Vector2(0, 0)
var uv_b = Vector2(0, 1)
var uv_c = Vector2(1, 1)
var uv_d = Vector2(1, 0)
# If we have a valid texture and this quad isn't a corner
if tex != null and q.corner == q.CORNER.NONE:
var x_left = (length_elapsed) / tex.get_size().x
var x_right = (length_elapsed + section_length) / tex.get_size().x
uv_a.x = x_left
uv_b.x = x_left
uv_c.x = x_right
uv_d.x = x_right
if q.flip_texture:
var t = uv_a
uv_a = uv_b
uv_b = t
t = uv_c
uv_c = uv_d
uv_d = t
# A
_add_uv_to_surface_tool(st, uv_a)
st.add_color(q.color)
st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_a))
# B
_add_uv_to_surface_tool(st, uv_b)
st.add_color(q.color)
st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_b))
# C
_add_uv_to_surface_tool(st, uv_c)
st.add_color(q.color)
st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_c))
# A
_add_uv_to_surface_tool(st, uv_a)
st.add_color(q.color)
st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_a))
# C
_add_uv_to_surface_tool(st, uv_c)
st.add_color(q.color)
st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_c))
# D
_add_uv_to_surface_tool(st, uv_d)
st.add_color(q.color)
st.add_vertex(SS2D_Common_Functions.to_vector3(q.pt_d))
length_elapsed += section_length
st.index()
st.generate_normals()
return st.commit()
func get_meshes() -> Array:
"""
Returns an array of SS2D_Mesh
# Get Arrays of consecutive quads with the same mesh data
# For each array
## Generate Mesh Data from the quad
"""
var consecutive_quad_arrays = get_consecutive_quads_for_mesh(quads)
#print("Arrays: %s" % consecutive_quad_arrays.size())
var meshes = []
for consecutive_quads in consecutive_quad_arrays:
if consecutive_quads.empty():
continue
var st: SurfaceTool = SurfaceTool.new()
var array_mesh: ArrayMesh = generate_array_mesh_from_quad_sequence(
consecutive_quads, wrap_around
)
var tex: Texture = consecutive_quads[0].texture
var tex_normal: Texture = consecutive_quads[0].texture_normal
var flip = consecutive_quads[0].flip_texture
var transform = Transform2D()
var mesh_data = SS2D_Mesh.new(tex, tex_normal, flip, transform, [array_mesh], material)
mesh_data.z_index = z_index
mesh_data.z_as_relative = z_as_relative
meshes.push_back(mesh_data)
return meshes
static func _add_uv_to_surface_tool(surface_tool: SurfaceTool, uv: Vector2):
surface_tool.add_uv(uv)
surface_tool.add_uv2(uv)
|