1/**************************************************************************/
2/* mesh.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "mesh.h"
32
33#include "core/math/convex_hull.h"
34#include "core/templates/pair.h"
35#include "scene/resources/surface_tool.h"
36
37#include "scene/resources/concave_polygon_shape_3d.h"
38#include "scene/resources/convex_polygon_shape_3d.h"
39
40void MeshConvexDecompositionSettings::set_max_concavity(real_t p_max_concavity) {
41 max_concavity = CLAMP(p_max_concavity, 0.001, 1.0);
42}
43
44real_t MeshConvexDecompositionSettings::get_max_concavity() const {
45 return max_concavity;
46};
47
48void MeshConvexDecompositionSettings::set_symmetry_planes_clipping_bias(real_t p_symmetry_planes_clipping_bias) {
49 symmetry_planes_clipping_bias = CLAMP(p_symmetry_planes_clipping_bias, 0.0, 1.0);
50};
51
52real_t MeshConvexDecompositionSettings::get_symmetry_planes_clipping_bias() const {
53 return symmetry_planes_clipping_bias;
54};
55
56void MeshConvexDecompositionSettings::set_revolution_axes_clipping_bias(real_t p_revolution_axes_clipping_bias) {
57 revolution_axes_clipping_bias = CLAMP(p_revolution_axes_clipping_bias, 0.0, 1.0);
58};
59
60real_t MeshConvexDecompositionSettings::get_revolution_axes_clipping_bias() const {
61 return revolution_axes_clipping_bias;
62};
63
64void MeshConvexDecompositionSettings::set_min_volume_per_convex_hull(real_t p_min_volume_per_convex_hull) {
65 min_volume_per_convex_hull = CLAMP(p_min_volume_per_convex_hull, 0.0001, 0.01);
66}
67
68real_t MeshConvexDecompositionSettings::get_min_volume_per_convex_hull() const {
69 return min_volume_per_convex_hull;
70}
71
72void MeshConvexDecompositionSettings::set_resolution(uint32_t p_resolution) {
73 resolution = p_resolution < 10'000 ? 10'000 : (p_resolution > 100'000 ? 100'000 : p_resolution);
74}
75
76uint32_t MeshConvexDecompositionSettings::get_resolution() const {
77 return resolution;
78}
79
80void MeshConvexDecompositionSettings::set_max_num_vertices_per_convex_hull(uint32_t p_max_num_vertices_per_convex_hull) {
81 max_num_vertices_per_convex_hull = p_max_num_vertices_per_convex_hull < 4 ? 4 : (p_max_num_vertices_per_convex_hull > 1024 ? 1024 : p_max_num_vertices_per_convex_hull);
82}
83
84uint32_t MeshConvexDecompositionSettings::get_max_num_vertices_per_convex_hull() const {
85 return max_num_vertices_per_convex_hull;
86}
87
88void MeshConvexDecompositionSettings::set_plane_downsampling(uint32_t p_plane_downsampling) {
89 plane_downsampling = p_plane_downsampling < 1 ? 1 : (p_plane_downsampling > 16 ? 16 : p_plane_downsampling);
90}
91
92uint32_t MeshConvexDecompositionSettings::get_plane_downsampling() const {
93 return plane_downsampling;
94}
95
96void MeshConvexDecompositionSettings::set_convex_hull_downsampling(uint32_t p_convex_hull_downsampling) {
97 convex_hull_downsampling = p_convex_hull_downsampling < 1 ? 1 : (p_convex_hull_downsampling > 16 ? 16 : p_convex_hull_downsampling);
98}
99
100uint32_t MeshConvexDecompositionSettings::get_convex_hull_downsampling() const {
101 return convex_hull_downsampling;
102}
103
104void MeshConvexDecompositionSettings::set_normalize_mesh(bool p_normalize_mesh) {
105 normalize_mesh = p_normalize_mesh;
106}
107
108bool MeshConvexDecompositionSettings::get_normalize_mesh() const {
109 return normalize_mesh;
110}
111
112void MeshConvexDecompositionSettings::set_mode(Mode p_mode) {
113 mode = p_mode;
114}
115
116MeshConvexDecompositionSettings::Mode MeshConvexDecompositionSettings::get_mode() const {
117 return mode;
118}
119
120void MeshConvexDecompositionSettings::set_convex_hull_approximation(bool p_convex_hull_approximation) {
121 convex_hull_approximation = p_convex_hull_approximation;
122}
123
124bool MeshConvexDecompositionSettings::get_convex_hull_approximation() const {
125 return convex_hull_approximation;
126}
127
128void MeshConvexDecompositionSettings::set_max_convex_hulls(uint32_t p_max_convex_hulls) {
129 max_convex_hulls = p_max_convex_hulls < 1 ? 1 : (p_max_convex_hulls > 32 ? 32 : p_max_convex_hulls);
130}
131
132uint32_t MeshConvexDecompositionSettings::get_max_convex_hulls() const {
133 return max_convex_hulls;
134}
135
136void MeshConvexDecompositionSettings::set_project_hull_vertices(bool p_project_hull_vertices) {
137 project_hull_vertices = p_project_hull_vertices;
138}
139
140bool MeshConvexDecompositionSettings::get_project_hull_vertices() const {
141 return project_hull_vertices;
142}
143
144void MeshConvexDecompositionSettings::_bind_methods() {
145 ClassDB::bind_method(D_METHOD("set_max_concavity", "max_concavity"), &MeshConvexDecompositionSettings::set_max_concavity);
146 ClassDB::bind_method(D_METHOD("get_max_concavity"), &MeshConvexDecompositionSettings::get_max_concavity);
147
148 ClassDB::bind_method(D_METHOD("set_symmetry_planes_clipping_bias", "symmetry_planes_clipping_bias"), &MeshConvexDecompositionSettings::set_symmetry_planes_clipping_bias);
149 ClassDB::bind_method(D_METHOD("get_symmetry_planes_clipping_bias"), &MeshConvexDecompositionSettings::get_symmetry_planes_clipping_bias);
150
151 ClassDB::bind_method(D_METHOD("set_revolution_axes_clipping_bias", "revolution_axes_clipping_bias"), &MeshConvexDecompositionSettings::set_revolution_axes_clipping_bias);
152 ClassDB::bind_method(D_METHOD("get_revolution_axes_clipping_bias"), &MeshConvexDecompositionSettings::get_revolution_axes_clipping_bias);
153
154 ClassDB::bind_method(D_METHOD("set_min_volume_per_convex_hull", "min_volume_per_convex_hull"), &MeshConvexDecompositionSettings::set_min_volume_per_convex_hull);
155 ClassDB::bind_method(D_METHOD("get_min_volume_per_convex_hull"), &MeshConvexDecompositionSettings::get_min_volume_per_convex_hull);
156
157 ClassDB::bind_method(D_METHOD("set_resolution", "min_volume_per_convex_hull"), &MeshConvexDecompositionSettings::set_resolution);
158 ClassDB::bind_method(D_METHOD("get_resolution"), &MeshConvexDecompositionSettings::get_resolution);
159
160 ClassDB::bind_method(D_METHOD("set_max_num_vertices_per_convex_hull", "max_num_vertices_per_convex_hull"), &MeshConvexDecompositionSettings::set_max_num_vertices_per_convex_hull);
161 ClassDB::bind_method(D_METHOD("get_max_num_vertices_per_convex_hull"), &MeshConvexDecompositionSettings::get_max_num_vertices_per_convex_hull);
162
163 ClassDB::bind_method(D_METHOD("set_plane_downsampling", "plane_downsampling"), &MeshConvexDecompositionSettings::set_plane_downsampling);
164 ClassDB::bind_method(D_METHOD("get_plane_downsampling"), &MeshConvexDecompositionSettings::get_plane_downsampling);
165
166 ClassDB::bind_method(D_METHOD("set_convex_hull_downsampling", "convex_hull_downsampling"), &MeshConvexDecompositionSettings::set_convex_hull_downsampling);
167 ClassDB::bind_method(D_METHOD("get_convex_hull_downsampling"), &MeshConvexDecompositionSettings::get_convex_hull_downsampling);
168
169 ClassDB::bind_method(D_METHOD("set_normalize_mesh", "normalize_mesh"), &MeshConvexDecompositionSettings::set_normalize_mesh);
170 ClassDB::bind_method(D_METHOD("get_normalize_mesh"), &MeshConvexDecompositionSettings::get_normalize_mesh);
171
172 ClassDB::bind_method(D_METHOD("set_mode", "mode"), &MeshConvexDecompositionSettings::set_mode);
173 ClassDB::bind_method(D_METHOD("get_mode"), &MeshConvexDecompositionSettings::get_mode);
174
175 ClassDB::bind_method(D_METHOD("set_convex_hull_approximation", "convex_hull_approximation"), &MeshConvexDecompositionSettings::set_convex_hull_approximation);
176 ClassDB::bind_method(D_METHOD("get_convex_hull_approximation"), &MeshConvexDecompositionSettings::get_convex_hull_approximation);
177
178 ClassDB::bind_method(D_METHOD("set_max_convex_hulls", "max_convex_hulls"), &MeshConvexDecompositionSettings::set_max_convex_hulls);
179 ClassDB::bind_method(D_METHOD("get_max_convex_hulls"), &MeshConvexDecompositionSettings::get_max_convex_hulls);
180
181 ClassDB::bind_method(D_METHOD("set_project_hull_vertices", "project_hull_vertices"), &MeshConvexDecompositionSettings::set_project_hull_vertices);
182 ClassDB::bind_method(D_METHOD("get_project_hull_vertices"), &MeshConvexDecompositionSettings::get_project_hull_vertices);
183
184 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_concavity", PROPERTY_HINT_RANGE, "0.001,1.0,0.001"), "set_max_concavity", "get_max_concavity");
185 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "symmetry_planes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_symmetry_planes_clipping_bias", "get_symmetry_planes_clipping_bias");
186 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "revolution_axes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_revolution_axes_clipping_bias", "get_revolution_axes_clipping_bias");
187 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_volume_per_convex_hull", PROPERTY_HINT_RANGE, "0.0001,0.01,0.0001"), "set_min_volume_per_convex_hull", "get_min_volume_per_convex_hull");
188 ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution"), "set_resolution", "get_resolution");
189 ADD_PROPERTY(PropertyInfo(Variant::INT, "max_num_vertices_per_convex_hull"), "set_max_num_vertices_per_convex_hull", "get_max_num_vertices_per_convex_hull");
190 ADD_PROPERTY(PropertyInfo(Variant::INT, "plane_downsampling", PROPERTY_HINT_RANGE, "1,16,1"), "set_plane_downsampling", "get_plane_downsampling");
191 ADD_PROPERTY(PropertyInfo(Variant::INT, "convex_hull_downsampling", PROPERTY_HINT_RANGE, "1,16,1"), "set_convex_hull_downsampling", "get_convex_hull_downsampling");
192 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalize_mesh"), "set_normalize_mesh", "get_normalize_mesh");
193 ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Voxel,Tetrahedron"), "set_mode", "get_mode");
194 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "convex_hull_approximation"), "set_convex_hull_approximation", "get_convex_hull_approximation");
195 ADD_PROPERTY(PropertyInfo(Variant::INT, "max_convex_hulls"), "set_max_convex_hulls", "get_max_convex_hulls");
196 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "project_hull_vertices"), "set_project_hull_vertices", "get_project_hull_vertices");
197
198 BIND_ENUM_CONSTANT(CONVEX_DECOMPOSITION_MODE_VOXEL);
199 BIND_ENUM_CONSTANT(CONVEX_DECOMPOSITION_MODE_TETRAHEDRON);
200}
201
202Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr;
203
204int Mesh::get_surface_count() const {
205 int ret = 0;
206 GDVIRTUAL_REQUIRED_CALL(_get_surface_count, ret);
207 return ret;
208}
209
210int Mesh::surface_get_array_len(int p_idx) const {
211 int ret = 0;
212 GDVIRTUAL_REQUIRED_CALL(_surface_get_array_len, p_idx, ret);
213 return ret;
214}
215
216int Mesh::surface_get_array_index_len(int p_idx) const {
217 int ret = 0;
218 GDVIRTUAL_REQUIRED_CALL(_surface_get_array_index_len, p_idx, ret);
219 return ret;
220}
221
222Array Mesh::surface_get_arrays(int p_surface) const {
223 Array ret;
224 GDVIRTUAL_REQUIRED_CALL(_surface_get_arrays, p_surface, ret);
225 return ret;
226}
227
228TypedArray<Array> Mesh::surface_get_blend_shape_arrays(int p_surface) const {
229 TypedArray<Array> ret;
230 GDVIRTUAL_REQUIRED_CALL(_surface_get_blend_shape_arrays, p_surface, ret);
231 return ret;
232}
233
234Dictionary Mesh::surface_get_lods(int p_surface) const {
235 Dictionary ret;
236 GDVIRTUAL_REQUIRED_CALL(_surface_get_lods, p_surface, ret);
237 return ret;
238}
239
240BitField<Mesh::ArrayFormat> Mesh::surface_get_format(int p_idx) const {
241 uint32_t ret = 0;
242 GDVIRTUAL_REQUIRED_CALL(_surface_get_format, p_idx, ret);
243 return ret;
244}
245
246Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const {
247 uint32_t ret = PRIMITIVE_MAX;
248 GDVIRTUAL_REQUIRED_CALL(_surface_get_primitive_type, p_idx, ret);
249 return (Mesh::PrimitiveType)ret;
250}
251
252void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
253 GDVIRTUAL_REQUIRED_CALL(_surface_set_material, p_idx, p_material);
254}
255
256Ref<Material> Mesh::surface_get_material(int p_idx) const {
257 Ref<Material> ret;
258 GDVIRTUAL_REQUIRED_CALL(_surface_get_material, p_idx, ret);
259 return ret;
260}
261
262int Mesh::get_blend_shape_count() const {
263 int ret = 0;
264 GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_count, ret);
265 return ret;
266}
267
268StringName Mesh::get_blend_shape_name(int p_index) const {
269 StringName ret;
270 GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_name, p_index, ret);
271 return ret;
272}
273
274void Mesh::set_blend_shape_name(int p_index, const StringName &p_name) {
275 GDVIRTUAL_REQUIRED_CALL(_set_blend_shape_name, p_index, p_name);
276}
277
278AABB Mesh::get_aabb() const {
279 AABB ret;
280 GDVIRTUAL_REQUIRED_CALL(_get_aabb, ret);
281 return ret;
282}
283
284Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
285 if (triangle_mesh.is_valid()) {
286 return triangle_mesh;
287 }
288
289 int faces_size = 0;
290
291 for (int i = 0; i < get_surface_count(); i++) {
292 switch (surface_get_primitive_type(i)) {
293 case PRIMITIVE_TRIANGLES: {
294 int len = (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? surface_get_array_index_len(i) : surface_get_array_len(i);
295 // Don't error if zero, it's valid (we'll just skip it later).
296 ERR_CONTINUE_MSG((len % 3) != 0, vformat("Ignoring surface %d, incorrect %s count: %d (for PRIMITIVE_TRIANGLES).", i, (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? "index" : "vertex", len));
297 faces_size += len;
298 } break;
299 case PRIMITIVE_TRIANGLE_STRIP: {
300 int len = (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? surface_get_array_index_len(i) : surface_get_array_len(i);
301 // Don't error if zero, it's valid (we'll just skip it later).
302 ERR_CONTINUE_MSG(len != 0 && len < 3, vformat("Ignoring surface %d, incorrect %s count: %d (for PRIMITIVE_TRIANGLE_STRIP).", i, (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? "index" : "vertex", len));
303 faces_size += (len == 0) ? 0 : (len - 2) * 3;
304 } break;
305 default: {
306 } break;
307 }
308 }
309
310 if (faces_size == 0) {
311 return triangle_mesh;
312 }
313
314 Vector<Vector3> faces;
315 faces.resize(faces_size);
316 Vector<int32_t> surface_indices;
317 surface_indices.resize(faces_size / 3);
318 Vector3 *facesw = faces.ptrw();
319 int32_t *surface_indicesw = surface_indices.ptrw();
320
321 int widx = 0;
322
323 for (int i = 0; i < get_surface_count(); i++) {
324 Mesh::PrimitiveType primitive = surface_get_primitive_type(i);
325 if (primitive != PRIMITIVE_TRIANGLES && primitive != PRIMITIVE_TRIANGLE_STRIP) {
326 continue;
327 }
328 int len = (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? surface_get_array_index_len(i) : surface_get_array_len(i);
329 if ((primitive == PRIMITIVE_TRIANGLES && (len == 0 || (len % 3) != 0)) ||
330 (primitive == PRIMITIVE_TRIANGLE_STRIP && len < 3) ||
331 (surface_get_format(i) & ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY)) {
332 // Error was already shown, just skip (including zero).
333 continue;
334 }
335
336 Array a = surface_get_arrays(i);
337 ERR_FAIL_COND_V(a.is_empty(), Ref<TriangleMesh>());
338
339 int vc = surface_get_array_len(i);
340 Vector<Vector3> vertices = a[ARRAY_VERTEX];
341 ERR_FAIL_COND_V(vertices.is_empty(), Ref<TriangleMesh>());
342 const Vector3 *vr = vertices.ptr();
343
344 int32_t from_index = widx / 3;
345
346 if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
347 int ic = surface_get_array_index_len(i);
348 Vector<int> indices = a[ARRAY_INDEX];
349 const int *ir = indices.ptr();
350
351 if (primitive == PRIMITIVE_TRIANGLES) {
352 for (int j = 0; j < ic; j++) {
353 int index = ir[j];
354 ERR_FAIL_COND_V(index >= vc, Ref<TriangleMesh>());
355 facesw[widx++] = vr[index];
356 }
357 } else { // PRIMITIVE_TRIANGLE_STRIP
358 for (int j = 2; j < ic; j++) {
359 facesw[widx++] = vr[ir[j - 2]];
360 facesw[widx++] = vr[ir[j - 1]];
361 facesw[widx++] = vr[ir[j]];
362 }
363 }
364
365 } else {
366 if (primitive == PRIMITIVE_TRIANGLES) {
367 for (int j = 0; j < vc; j++) {
368 facesw[widx++] = vr[j];
369 }
370 } else { // PRIMITIVE_TRIANGLE_STRIP
371 for (int j = 2; j < vc; j++) {
372 facesw[widx++] = vr[j - 2];
373 facesw[widx++] = vr[j - 1];
374 facesw[widx++] = vr[j];
375 }
376 }
377 }
378
379 int32_t to_index = widx / 3;
380
381 for (int j = from_index; j < to_index; j++) {
382 surface_indicesw[j] = i;
383 }
384 }
385
386 triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh));
387 triangle_mesh->create(faces);
388
389 return triangle_mesh;
390}
391
392Ref<TriangleMesh> Mesh::generate_surface_triangle_mesh(int p_surface) const {
393 ERR_FAIL_INDEX_V(p_surface, get_surface_count(), Ref<TriangleMesh>());
394
395 if (surface_triangle_meshes.size() != get_surface_count()) {
396 surface_triangle_meshes.resize(get_surface_count());
397 }
398
399 if (surface_triangle_meshes[p_surface].is_valid()) {
400 return surface_triangle_meshes[p_surface];
401 }
402
403 int facecount = 0;
404
405 if (surface_get_primitive_type(p_surface) != PRIMITIVE_TRIANGLES) {
406 return Ref<TriangleMesh>();
407 }
408
409 if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) {
410 facecount += surface_get_array_index_len(p_surface);
411 } else {
412 facecount += surface_get_array_len(p_surface);
413 }
414
415 Vector<Vector3> faces;
416 faces.resize(facecount);
417 Vector3 *facesw = faces.ptrw();
418
419 Array a = surface_get_arrays(p_surface);
420 ERR_FAIL_COND_V(a.is_empty(), Ref<TriangleMesh>());
421
422 int vc = surface_get_array_len(p_surface);
423 Vector<Vector3> vertices = a[ARRAY_VERTEX];
424 const Vector3 *vr = vertices.ptr();
425 int widx = 0;
426
427 if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) {
428 int ic = surface_get_array_index_len(p_surface);
429 Vector<int> indices = a[ARRAY_INDEX];
430 const int *ir = indices.ptr();
431
432 for (int j = 0; j < ic; j++) {
433 int index = ir[j];
434 facesw[widx++] = vr[index];
435 }
436
437 } else {
438 for (int j = 0; j < vc; j++) {
439 facesw[widx++] = vr[j];
440 }
441 }
442
443 Ref<TriangleMesh> tr_mesh = Ref<TriangleMesh>(memnew(TriangleMesh));
444 tr_mesh->create(faces);
445 surface_triangle_meshes.set(p_surface, tr_mesh);
446
447 return tr_mesh;
448}
449
450void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) {
451 if (debug_lines.size() > 0) {
452 r_lines = debug_lines;
453 return;
454 }
455
456 Ref<TriangleMesh> tm = generate_triangle_mesh();
457 if (tm.is_null()) {
458 return;
459 }
460
461 Vector<int> triangle_indices;
462 tm->get_indices(&triangle_indices);
463 const int triangles_num = tm->get_triangles().size();
464 Vector<Vector3> vertices = tm->get_vertices();
465
466 debug_lines.resize(tm->get_triangles().size() * 6); // 3 lines x 2 points each line
467
468 const int *ind_r = triangle_indices.ptr();
469 const Vector3 *ver_r = vertices.ptr();
470 for (int j = 0, x = 0, i = 0; i < triangles_num; j += 6, x += 3, ++i) {
471 // Triangle line 1
472 debug_lines.write[j + 0] = ver_r[ind_r[x + 0]];
473 debug_lines.write[j + 1] = ver_r[ind_r[x + 1]];
474
475 // Triangle line 2
476 debug_lines.write[j + 2] = ver_r[ind_r[x + 1]];
477 debug_lines.write[j + 3] = ver_r[ind_r[x + 2]];
478
479 // Triangle line 3
480 debug_lines.write[j + 4] = ver_r[ind_r[x + 2]];
481 debug_lines.write[j + 5] = ver_r[ind_r[x + 0]];
482 }
483
484 r_lines = debug_lines;
485}
486
487void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
488 Ref<TriangleMesh> tm = generate_triangle_mesh();
489 if (tm.is_null()) {
490 return;
491 }
492
493 Vector<Vector3> vertices = tm->get_vertices();
494
495 int vertices_size = vertices.size();
496 r_points.resize(vertices_size);
497 for (int i = 0; i < vertices_size; ++i) {
498 r_points.write[i] = vertices[i];
499 }
500}
501
502Vector<Vector3> Mesh::_get_faces() const {
503 return Variant(get_faces());
504}
505
506Vector<Face3> Mesh::get_faces() const {
507 Ref<TriangleMesh> tm = generate_triangle_mesh();
508 if (tm.is_valid()) {
509 return tm->get_faces();
510 }
511 return Vector<Face3>();
512}
513
514Vector<Face3> Mesh::get_surface_faces(int p_surface) const {
515 Ref<TriangleMesh> tm = generate_surface_triangle_mesh(p_surface);
516 if (tm.is_valid()) {
517 return tm->get_faces();
518 }
519 return Vector<Face3>();
520}
521
522Ref<ConvexPolygonShape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const {
523 if (p_simplify) {
524 Ref<MeshConvexDecompositionSettings> settings = Ref<MeshConvexDecompositionSettings>();
525 settings.instantiate();
526 settings->set_max_convex_hulls(1);
527 settings->set_max_concavity(1.0);
528 Vector<Ref<Shape3D>> decomposed = convex_decompose(settings);
529 if (decomposed.size() == 1) {
530 return decomposed[0];
531 } else {
532 ERR_PRINT("Convex shape simplification failed, falling back to simpler process.");
533 }
534 }
535
536 Vector<Vector3> vertices;
537 for (int i = 0; i < get_surface_count(); i++) {
538 Array a = surface_get_arrays(i);
539 ERR_FAIL_COND_V(a.is_empty(), Ref<ConvexPolygonShape3D>());
540 Vector<Vector3> v = a[ARRAY_VERTEX];
541 vertices.append_array(v);
542 }
543
544 Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D);
545
546 if (p_clean) {
547 Geometry3D::MeshData md;
548 Error err = ConvexHullComputer::convex_hull(vertices, md);
549 if (err == OK) {
550 shape->set_points(md.vertices);
551 return shape;
552 } else {
553 ERR_PRINT("Convex shape cleaning failed, falling back to simpler process.");
554 }
555 }
556
557 shape->set_points(vertices);
558 return shape;
559}
560
561Ref<ConcavePolygonShape3D> Mesh::create_trimesh_shape() const {
562 Vector<Face3> faces = get_faces();
563 if (faces.size() == 0) {
564 return Ref<ConcavePolygonShape3D>();
565 }
566
567 Vector<Vector3> face_points;
568 face_points.resize(faces.size() * 3);
569
570 for (int i = 0; i < face_points.size(); i += 3) {
571 Face3 f = faces.get(i / 3);
572 face_points.set(i, f.vertex[0]);
573 face_points.set(i + 1, f.vertex[1]);
574 face_points.set(i + 2, f.vertex[2]);
575 }
576
577 Ref<ConcavePolygonShape3D> shape = memnew(ConcavePolygonShape3D);
578 shape->set_faces(face_points);
579 return shape;
580}
581
582Ref<Mesh> Mesh::create_outline(float p_margin) const {
583 Array arrays;
584 int index_accum = 0;
585 for (int i = 0; i < get_surface_count(); i++) {
586 if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) {
587 continue;
588 }
589
590 Array a = surface_get_arrays(i);
591 ERR_FAIL_COND_V(a.is_empty(), Ref<ArrayMesh>());
592
593 if (i == 0) {
594 arrays = a;
595 Vector<Vector3> v = a[ARRAY_VERTEX];
596 index_accum += v.size();
597 } else {
598 int vcount = 0;
599 for (int j = 0; j < arrays.size(); j++) {
600 if (arrays[j].get_type() == Variant::NIL || a[j].get_type() == Variant::NIL) {
601 //mismatch, do not use
602 arrays[j] = Variant();
603 continue;
604 }
605
606 switch (j) {
607 case ARRAY_VERTEX:
608 case ARRAY_NORMAL: {
609 Vector<Vector3> dst = arrays[j];
610 Vector<Vector3> src = a[j];
611 if (j == ARRAY_VERTEX) {
612 vcount = src.size();
613 }
614 if (dst.size() == 0 || src.size() == 0) {
615 arrays[j] = Variant();
616 continue;
617 }
618 dst.append_array(src);
619 arrays[j] = dst;
620 } break;
621 case ARRAY_TANGENT:
622 case ARRAY_BONES:
623 case ARRAY_WEIGHTS: {
624 Vector<real_t> dst = arrays[j];
625 Vector<real_t> src = a[j];
626 if (dst.size() == 0 || src.size() == 0) {
627 arrays[j] = Variant();
628 continue;
629 }
630 dst.append_array(src);
631 arrays[j] = dst;
632
633 } break;
634 case ARRAY_COLOR: {
635 Vector<Color> dst = arrays[j];
636 Vector<Color> src = a[j];
637 if (dst.size() == 0 || src.size() == 0) {
638 arrays[j] = Variant();
639 continue;
640 }
641 dst.append_array(src);
642 arrays[j] = dst;
643
644 } break;
645 case ARRAY_TEX_UV:
646 case ARRAY_TEX_UV2: {
647 Vector<Vector2> dst = arrays[j];
648 Vector<Vector2> src = a[j];
649 if (dst.size() == 0 || src.size() == 0) {
650 arrays[j] = Variant();
651 continue;
652 }
653 dst.append_array(src);
654 arrays[j] = dst;
655
656 } break;
657 case ARRAY_INDEX: {
658 Vector<int> dst = arrays[j];
659 Vector<int> src = a[j];
660 if (dst.size() == 0 || src.size() == 0) {
661 arrays[j] = Variant();
662 continue;
663 }
664 {
665 int ss = src.size();
666 int *w = src.ptrw();
667 for (int k = 0; k < ss; k++) {
668 w[k] += index_accum;
669 }
670 }
671 dst.append_array(src);
672 arrays[j] = dst;
673 index_accum += vcount;
674
675 } break;
676 }
677 }
678 }
679 }
680
681 ERR_FAIL_COND_V(arrays.size() != ARRAY_MAX, Ref<ArrayMesh>());
682
683 {
684 int *ir = nullptr;
685 Vector<int> indices = arrays[ARRAY_INDEX];
686 bool has_indices = false;
687 Vector<Vector3> vertices = arrays[ARRAY_VERTEX];
688 int vc = vertices.size();
689 ERR_FAIL_COND_V(!vc, Ref<ArrayMesh>());
690 Vector3 *r = vertices.ptrw();
691
692 if (indices.size()) {
693 ERR_FAIL_COND_V(indices.size() % 3 != 0, Ref<ArrayMesh>());
694 vc = indices.size();
695 ir = indices.ptrw();
696 has_indices = true;
697 } else {
698 // Ensure there are enough vertices to construct at least one triangle.
699 ERR_FAIL_COND_V(vertices.size() % 3 != 0, Ref<ArrayMesh>());
700 }
701
702 HashMap<Vector3, Vector3> normal_accum;
703
704 //fill normals with triangle normals
705 for (int i = 0; i < vc; i += 3) {
706 Vector3 t[3];
707
708 if (has_indices) {
709 t[0] = r[ir[i + 0]];
710 t[1] = r[ir[i + 1]];
711 t[2] = r[ir[i + 2]];
712 } else {
713 t[0] = r[i + 0];
714 t[1] = r[i + 1];
715 t[2] = r[i + 2];
716 }
717
718 Vector3 n = Plane(t[0], t[1], t[2]).normal;
719
720 for (int j = 0; j < 3; j++) {
721 HashMap<Vector3, Vector3>::Iterator E = normal_accum.find(t[j]);
722 if (!E) {
723 normal_accum[t[j]] = n;
724 } else {
725 float d = n.dot(E->value);
726 if (d < 1.0) {
727 E->value += n * (1.0 - d);
728 }
729 //E->get()+=n;
730 }
731 }
732 }
733
734 //normalize
735
736 for (KeyValue<Vector3, Vector3> &E : normal_accum) {
737 E.value.normalize();
738 }
739
740 //displace normals
741 int vc2 = vertices.size();
742
743 for (int i = 0; i < vc2; i++) {
744 Vector3 t = r[i];
745
746 HashMap<Vector3, Vector3>::Iterator E = normal_accum.find(t);
747 ERR_CONTINUE(!E);
748
749 t += E->value * p_margin;
750 r[i] = t;
751 }
752
753 arrays[ARRAY_VERTEX] = vertices;
754
755 if (!has_indices) {
756 Vector<int> new_indices;
757 new_indices.resize(vertices.size());
758 int *iw = new_indices.ptrw();
759
760 for (int j = 0; j < vc2; j += 3) {
761 iw[j] = j;
762 iw[j + 1] = j + 2;
763 iw[j + 2] = j + 1;
764 }
765
766 arrays[ARRAY_INDEX] = new_indices;
767
768 } else {
769 for (int j = 0; j < vc; j += 3) {
770 SWAP(ir[j + 1], ir[j + 2]);
771 }
772 arrays[ARRAY_INDEX] = indices;
773 }
774 }
775
776 Ref<ArrayMesh> newmesh = memnew(ArrayMesh);
777 newmesh->add_surface_from_arrays(PRIMITIVE_TRIANGLES, arrays);
778 return newmesh;
779}
780
781void Mesh::set_lightmap_size_hint(const Size2i &p_size) {
782 lightmap_size_hint = p_size;
783}
784
785Size2i Mesh::get_lightmap_size_hint() const {
786 return lightmap_size_hint;
787}
788
789Ref<Resource> Mesh::create_placeholder() const {
790 Ref<PlaceholderMesh> placeholder;
791 placeholder.instantiate();
792 placeholder->set_aabb(get_aabb());
793 return placeholder;
794}
795
796void Mesh::_bind_methods() {
797 ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint);
798 ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint);
799 ClassDB::bind_method(D_METHOD("get_aabb"), &Mesh::get_aabb);
800 ClassDB::bind_method(D_METHOD("get_faces"), &Mesh::_get_faces);
801
802 ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint");
803
804 ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count);
805 ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &Mesh::surface_get_arrays);
806 ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &Mesh::surface_get_blend_shape_arrays);
807 ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material"), &Mesh::surface_set_material);
808 ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &Mesh::surface_get_material);
809 ClassDB::bind_method(D_METHOD("create_placeholder"), &Mesh::create_placeholder);
810
811 BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
812 BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
813 BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP);
814 BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES);
815 BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP);
816
817 BIND_ENUM_CONSTANT(ARRAY_VERTEX);
818 BIND_ENUM_CONSTANT(ARRAY_NORMAL);
819 BIND_ENUM_CONSTANT(ARRAY_TANGENT);
820 BIND_ENUM_CONSTANT(ARRAY_COLOR);
821 BIND_ENUM_CONSTANT(ARRAY_TEX_UV);
822 BIND_ENUM_CONSTANT(ARRAY_TEX_UV2);
823 BIND_ENUM_CONSTANT(ARRAY_CUSTOM0);
824 BIND_ENUM_CONSTANT(ARRAY_CUSTOM1);
825 BIND_ENUM_CONSTANT(ARRAY_CUSTOM2);
826 BIND_ENUM_CONSTANT(ARRAY_CUSTOM3);
827 BIND_ENUM_CONSTANT(ARRAY_BONES);
828 BIND_ENUM_CONSTANT(ARRAY_WEIGHTS);
829 BIND_ENUM_CONSTANT(ARRAY_INDEX);
830 BIND_ENUM_CONSTANT(ARRAY_MAX);
831
832 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_UNORM);
833 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_SNORM);
834 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_HALF);
835 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_HALF);
836 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_R_FLOAT);
837 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_FLOAT);
838 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGB_FLOAT);
839 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_FLOAT);
840 BIND_ENUM_CONSTANT(ARRAY_CUSTOM_MAX);
841
842 BIND_BITFIELD_FLAG(ARRAY_FORMAT_VERTEX);
843 BIND_BITFIELD_FLAG(ARRAY_FORMAT_NORMAL);
844 BIND_BITFIELD_FLAG(ARRAY_FORMAT_TANGENT);
845 BIND_BITFIELD_FLAG(ARRAY_FORMAT_COLOR);
846 BIND_BITFIELD_FLAG(ARRAY_FORMAT_TEX_UV);
847 BIND_BITFIELD_FLAG(ARRAY_FORMAT_TEX_UV2);
848 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM0);
849 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM1);
850 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM2);
851 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM3);
852 BIND_BITFIELD_FLAG(ARRAY_FORMAT_BONES);
853 BIND_BITFIELD_FLAG(ARRAY_FORMAT_WEIGHTS);
854 BIND_BITFIELD_FLAG(ARRAY_FORMAT_INDEX);
855
856 BIND_BITFIELD_FLAG(ARRAY_FORMAT_BLEND_SHAPE_MASK);
857
858 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM_BASE);
859 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM_BITS);
860 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM0_SHIFT);
861 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM1_SHIFT);
862 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM2_SHIFT);
863 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM3_SHIFT);
864
865 BIND_BITFIELD_FLAG(ARRAY_FORMAT_CUSTOM_MASK);
866 BIND_BITFIELD_FLAG(ARRAY_COMPRESS_FLAGS_BASE);
867
868 BIND_BITFIELD_FLAG(ARRAY_FLAG_USE_2D_VERTICES);
869 BIND_BITFIELD_FLAG(ARRAY_FLAG_USE_DYNAMIC_UPDATE);
870 BIND_BITFIELD_FLAG(ARRAY_FLAG_USE_8_BONE_WEIGHTS);
871 BIND_BITFIELD_FLAG(ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY);
872
873 BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED);
874 BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE);
875
876 GDVIRTUAL_BIND(_get_surface_count)
877 GDVIRTUAL_BIND(_surface_get_array_len, "index")
878 GDVIRTUAL_BIND(_surface_get_array_index_len, "index")
879 GDVIRTUAL_BIND(_surface_get_arrays, "index")
880 GDVIRTUAL_BIND(_surface_get_blend_shape_arrays, "index")
881 GDVIRTUAL_BIND(_surface_get_lods, "index")
882 GDVIRTUAL_BIND(_surface_get_format, "index")
883 GDVIRTUAL_BIND(_surface_get_primitive_type, "index")
884 GDVIRTUAL_BIND(_surface_set_material, "index", "material")
885 GDVIRTUAL_BIND(_surface_get_material, "index")
886 GDVIRTUAL_BIND(_get_blend_shape_count)
887 GDVIRTUAL_BIND(_get_blend_shape_name, "index")
888 GDVIRTUAL_BIND(_set_blend_shape_name, "index", "name")
889 GDVIRTUAL_BIND(_get_aabb)
890}
891
892void Mesh::clear_cache() const {
893 triangle_mesh.unref();
894 debug_lines.clear();
895}
896
897Vector<Ref<Shape3D>> Mesh::convex_decompose(const Ref<MeshConvexDecompositionSettings> &p_settings) const {
898 ERR_FAIL_NULL_V(convex_decomposition_function, Vector<Ref<Shape3D>>());
899
900 Ref<TriangleMesh> tm = generate_triangle_mesh();
901 ERR_FAIL_COND_V(!tm.is_valid(), Vector<Ref<Shape3D>>());
902
903 const Vector<TriangleMesh::Triangle> &triangles = tm->get_triangles();
904 int triangle_count = triangles.size();
905
906 Vector<uint32_t> indices;
907 {
908 indices.resize(triangle_count * 3);
909 uint32_t *w = indices.ptrw();
910 for (int i = 0; i < triangle_count; i++) {
911 for (int j = 0; j < 3; j++) {
912 w[i * 3 + j] = triangles[i].indices[j];
913 }
914 }
915 }
916
917 const Vector<Vector3> &vertices = tm->get_vertices();
918 int vertex_count = vertices.size();
919
920 Vector<Vector<Vector3>> decomposed = convex_decomposition_function((real_t *)vertices.ptr(), vertex_count, indices.ptr(), triangle_count, p_settings, nullptr);
921
922 Vector<Ref<Shape3D>> ret;
923
924 for (int i = 0; i < decomposed.size(); i++) {
925 Ref<ConvexPolygonShape3D> shape;
926 shape.instantiate();
927 shape->set_points(decomposed[i]);
928 ret.push_back(shape);
929 }
930
931 return ret;
932}
933
934int Mesh::get_builtin_bind_pose_count() const {
935 return 0;
936}
937
938Transform3D Mesh::get_builtin_bind_pose(int p_index) const {
939 return Transform3D();
940}
941
942Mesh::Mesh() {
943}
944
945enum OldArrayType {
946 OLD_ARRAY_VERTEX,
947 OLD_ARRAY_NORMAL,
948 OLD_ARRAY_TANGENT,
949 OLD_ARRAY_COLOR,
950 OLD_ARRAY_TEX_UV,
951 OLD_ARRAY_TEX_UV2,
952 OLD_ARRAY_BONES,
953 OLD_ARRAY_WEIGHTS,
954 OLD_ARRAY_INDEX,
955 OLD_ARRAY_MAX,
956};
957
958enum OldArrayFormat {
959 /* OLD_ARRAY FORMAT FLAGS */
960 OLD_ARRAY_FORMAT_VERTEX = 1 << OLD_ARRAY_VERTEX, // mandatory
961 OLD_ARRAY_FORMAT_NORMAL = 1 << OLD_ARRAY_NORMAL,
962 OLD_ARRAY_FORMAT_TANGENT = 1 << OLD_ARRAY_TANGENT,
963 OLD_ARRAY_FORMAT_COLOR = 1 << OLD_ARRAY_COLOR,
964 OLD_ARRAY_FORMAT_TEX_UV = 1 << OLD_ARRAY_TEX_UV,
965 OLD_ARRAY_FORMAT_TEX_UV2 = 1 << OLD_ARRAY_TEX_UV2,
966 OLD_ARRAY_FORMAT_BONES = 1 << OLD_ARRAY_BONES,
967 OLD_ARRAY_FORMAT_WEIGHTS = 1 << OLD_ARRAY_WEIGHTS,
968 OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX,
969
970 OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1),
971 OLD_ARRAY_COMPRESS_VERTEX = 1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE), // mandatory
972 OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE),
973 OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE),
974 OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE),
975 OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE),
976 OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE),
977 OLD_ARRAY_COMPRESS_BONES = 1 << (OLD_ARRAY_BONES + OLD_ARRAY_COMPRESS_BASE),
978 OLD_ARRAY_COMPRESS_WEIGHTS = 1 << (OLD_ARRAY_WEIGHTS + OLD_ARRAY_COMPRESS_BASE),
979 OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE),
980
981 OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1,
982 OLD_ARRAY_FLAG_USE_16_BIT_BONES = OLD_ARRAY_COMPRESS_INDEX << 2,
983 OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3,
984 OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION = OLD_ARRAY_COMPRESS_INDEX << 4,
985};
986
987#ifndef DISABLE_DEPRECATED
988static Array _convert_old_array(const Array &p_old) {
989 Array new_array;
990 new_array.resize(Mesh::ARRAY_MAX);
991 new_array[Mesh::ARRAY_VERTEX] = p_old[OLD_ARRAY_VERTEX];
992 new_array[Mesh::ARRAY_NORMAL] = p_old[OLD_ARRAY_NORMAL];
993 new_array[Mesh::ARRAY_TANGENT] = p_old[OLD_ARRAY_TANGENT];
994 new_array[Mesh::ARRAY_COLOR] = p_old[OLD_ARRAY_COLOR];
995 new_array[Mesh::ARRAY_TEX_UV] = p_old[OLD_ARRAY_TEX_UV];
996 new_array[Mesh::ARRAY_TEX_UV2] = p_old[OLD_ARRAY_TEX_UV2];
997 new_array[Mesh::ARRAY_BONES] = p_old[OLD_ARRAY_BONES];
998 new_array[Mesh::ARRAY_WEIGHTS] = p_old[OLD_ARRAY_WEIGHTS];
999 new_array[Mesh::ARRAY_INDEX] = p_old[OLD_ARRAY_INDEX];
1000 return new_array;
1001}
1002
1003static Mesh::PrimitiveType _old_primitives[7] = {
1004 Mesh::PRIMITIVE_POINTS,
1005 Mesh::PRIMITIVE_LINES,
1006 Mesh::PRIMITIVE_LINE_STRIP,
1007 Mesh::PRIMITIVE_LINES,
1008 Mesh::PRIMITIVE_TRIANGLES,
1009 Mesh::PRIMITIVE_TRIANGLE_STRIP,
1010 Mesh::PRIMITIVE_TRIANGLE_STRIP
1011};
1012#endif // DISABLE_DEPRECATED
1013
1014void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_format, uint32_t p_new_format, uint32_t p_elements, Vector<uint8_t> &vertex_data, Vector<uint8_t> &attribute_data, Vector<uint8_t> &skin_data) {
1015 uint32_t dst_vertex_stride;
1016 uint32_t dst_attribute_stride;
1017 uint32_t dst_skin_stride;
1018 uint32_t dst_offsets[Mesh::ARRAY_MAX];
1019 RenderingServer::get_singleton()->mesh_surface_make_offsets_from_format(p_new_format & (~RS::ARRAY_FORMAT_INDEX), p_elements, 0, dst_offsets, dst_vertex_stride, dst_attribute_stride, dst_skin_stride);
1020
1021 vertex_data.resize(dst_vertex_stride * p_elements);
1022 attribute_data.resize(dst_attribute_stride * p_elements);
1023 skin_data.resize(dst_skin_stride * p_elements);
1024
1025 uint8_t *dst_vertex_ptr = vertex_data.ptrw();
1026 uint8_t *dst_attribute_ptr = attribute_data.ptrw();
1027 uint8_t *dst_skin_ptr = skin_data.ptrw();
1028
1029 const uint8_t *src_vertex_ptr = p_src.ptr();
1030 uint32_t src_vertex_stride = p_src.size() / p_elements;
1031
1032 uint32_t src_offset = 0;
1033 for (uint32_t j = 0; j < OLD_ARRAY_INDEX; j++) {
1034 if (!(p_old_format & (1 << j))) {
1035 continue;
1036 }
1037 switch (j) {
1038 case OLD_ARRAY_VERTEX: {
1039 if (p_old_format & OLD_ARRAY_FLAG_USE_2D_VERTICES) {
1040 if (p_old_format & OLD_ARRAY_COMPRESS_VERTEX) {
1041 for (uint32_t i = 0; i < p_elements; i++) {
1042 const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride];
1043 float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride];
1044 dst[0] = Math::half_to_float(src[0]);
1045 dst[1] = Math::half_to_float(src[1]);
1046 }
1047 src_offset += sizeof(uint16_t) * 2;
1048 } else {
1049 for (uint32_t i = 0; i < p_elements; i++) {
1050 const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride];
1051 float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride];
1052 dst[0] = src[0];
1053 dst[1] = src[1];
1054 }
1055 src_offset += sizeof(float) * 2;
1056 }
1057 } else {
1058 if (p_old_format & OLD_ARRAY_COMPRESS_VERTEX) {
1059 for (uint32_t i = 0; i < p_elements; i++) {
1060 const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride];
1061 float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride];
1062 dst[0] = Math::half_to_float(src[0]);
1063 dst[1] = Math::half_to_float(src[1]);
1064 dst[2] = Math::half_to_float(src[2]);
1065 }
1066 src_offset += sizeof(uint16_t) * 4; //+pad
1067 } else {
1068 for (uint32_t i = 0; i < p_elements; i++) {
1069 const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride];
1070 float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride];
1071 dst[0] = src[0];
1072 dst[1] = src[1];
1073 dst[2] = src[2];
1074 }
1075 src_offset += sizeof(float) * 3;
1076 }
1077 }
1078 } break;
1079 case OLD_ARRAY_NORMAL: {
1080 if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
1081 if ((p_old_format & OLD_ARRAY_COMPRESS_NORMAL) && (p_old_format & OLD_ARRAY_FORMAT_TANGENT) && (p_old_format & OLD_ARRAY_COMPRESS_TANGENT)) {
1082 for (uint32_t i = 0; i < p_elements; i++) {
1083 const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1084 int16_t *dst = (int16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
1085
1086 dst[0] = (int16_t)CLAMP(src[0] / 127.0f * 32767, -32768, 32767);
1087 dst[1] = (int16_t)CLAMP(src[1] / 127.0f * 32767, -32768, 32767);
1088 }
1089 src_offset += sizeof(int8_t) * 2;
1090 } else {
1091 for (uint32_t i = 0; i < p_elements; i++) {
1092 const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1093 int16_t *dst = (int16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
1094
1095 dst[0] = src[0];
1096 dst[1] = src[1];
1097 }
1098 src_offset += sizeof(int16_t) * 2;
1099 }
1100 } else { // No Octahedral compression
1101 if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) {
1102 for (uint32_t i = 0; i < p_elements; i++) {
1103 const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1104 const Vector3 original_normal(src[0], src[1], src[2]);
1105 Vector2 res = original_normal.octahedron_encode();
1106
1107 uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
1108 dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535);
1109 dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535);
1110 }
1111 src_offset += sizeof(uint8_t) * 4; // 1 byte padding
1112 } else {
1113 for (uint32_t i = 0; i < p_elements; i++) {
1114 const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1115 const Vector3 original_normal(src[0], src[1], src[2]);
1116 Vector2 res = original_normal.octahedron_encode();
1117
1118 uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
1119 dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535);
1120 dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535);
1121 }
1122 src_offset += sizeof(float) * 3;
1123 }
1124 }
1125
1126 } break;
1127 case OLD_ARRAY_TANGENT: {
1128 if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
1129 if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { // int8 SNORM -> uint16 UNORM
1130 for (uint32_t i = 0; i < p_elements; i++) {
1131 const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1132 uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]];
1133
1134 dst[0] = (uint16_t)CLAMP((src[0] / 127.0f * .5f + .5f) * 65535, 0, 65535);
1135 dst[1] = (uint16_t)CLAMP((src[1] / 127.0f * .5f + .5f) * 65535, 0, 65535);
1136 }
1137 src_offset += sizeof(uint8_t) * 2;
1138 } else { // int16 SNORM -> uint16 UNORM
1139 for (uint32_t i = 0; i < p_elements; i++) {
1140 const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1141 uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]];
1142
1143 dst[0] = (uint16_t)CLAMP((src[0] / 32767.0f * .5f + .5f) * 65535, 0, 65535);
1144 dst[1] = (uint16_t)CLAMP((src[1] / 32767.0f * .5f + .5f) * 65535, 0, 65535);
1145 }
1146 src_offset += sizeof(uint16_t) * 2;
1147 }
1148 } else { // No Octahedral compression
1149 if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) {
1150 for (uint32_t i = 0; i < p_elements; i++) {
1151 const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1152 const Vector3 original_tangent(src[0], src[1], src[2]);
1153 Vector2 res = original_tangent.octahedron_tangent_encode(src[3]);
1154
1155 uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
1156 dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535);
1157 dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535);
1158 }
1159 src_offset += sizeof(uint8_t) * 4;
1160 } else {
1161 for (uint32_t i = 0; i < p_elements; i++) {
1162 const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1163 const Vector3 original_tangent(src[0], src[1], src[2]);
1164 Vector2 res = original_tangent.octahedron_tangent_encode(src[3]);
1165
1166 uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]];
1167 dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535);
1168 dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535);
1169 }
1170 src_offset += sizeof(float) * 4;
1171 }
1172 }
1173 } break;
1174 case OLD_ARRAY_COLOR: {
1175 if (p_old_format & OLD_ARRAY_COMPRESS_COLOR) {
1176 for (uint32_t i = 0; i < p_elements; i++) {
1177 const uint32_t *src = (const uint32_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1178 uint32_t *dst = (uint32_t *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_COLOR]];
1179
1180 *dst = *src;
1181 }
1182 src_offset += sizeof(uint32_t);
1183 } else {
1184 for (uint32_t i = 0; i < p_elements; i++) {
1185 const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1186 uint8_t *dst = (uint8_t *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_COLOR]];
1187
1188 dst[0] = uint8_t(CLAMP(src[0] * 255.0, 0.0, 255.0));
1189 dst[1] = uint8_t(CLAMP(src[1] * 255.0, 0.0, 255.0));
1190 dst[2] = uint8_t(CLAMP(src[2] * 255.0, 0.0, 255.0));
1191 dst[3] = uint8_t(CLAMP(src[3] * 255.0, 0.0, 255.0));
1192 }
1193 src_offset += sizeof(float) * 4;
1194 }
1195 } break;
1196 case OLD_ARRAY_TEX_UV: {
1197 if (p_old_format & OLD_ARRAY_COMPRESS_TEX_UV) {
1198 for (uint32_t i = 0; i < p_elements; i++) {
1199 const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1200 float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV]];
1201
1202 dst[0] = Math::half_to_float(src[0]);
1203 dst[1] = Math::half_to_float(src[1]);
1204 }
1205 src_offset += sizeof(uint16_t) * 2;
1206 } else {
1207 for (uint32_t i = 0; i < p_elements; i++) {
1208 const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1209 float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV]];
1210
1211 dst[0] = src[0];
1212 dst[1] = src[1];
1213 }
1214 src_offset += sizeof(float) * 2;
1215 }
1216
1217 } break;
1218 case OLD_ARRAY_TEX_UV2: {
1219 if (p_old_format & OLD_ARRAY_COMPRESS_TEX_UV2) {
1220 for (uint32_t i = 0; i < p_elements; i++) {
1221 const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1222 float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV2]];
1223
1224 dst[0] = Math::half_to_float(src[0]);
1225 dst[1] = Math::half_to_float(src[1]);
1226 }
1227 src_offset += sizeof(uint16_t) * 2;
1228 } else {
1229 for (uint32_t i = 0; i < p_elements; i++) {
1230 const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1231 float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV2]];
1232
1233 dst[0] = src[0];
1234 dst[1] = src[1];
1235 }
1236 src_offset += sizeof(float) * 2;
1237 }
1238 } break;
1239 case OLD_ARRAY_BONES: {
1240 if (p_old_format & OLD_ARRAY_FLAG_USE_16_BIT_BONES) {
1241 for (uint32_t i = 0; i < p_elements; i++) {
1242 const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1243 uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_BONES]];
1244
1245 dst[0] = src[0];
1246 dst[1] = src[1];
1247 dst[2] = src[2];
1248 dst[3] = src[3];
1249 }
1250 src_offset += sizeof(uint16_t) * 4;
1251 } else {
1252 for (uint32_t i = 0; i < p_elements; i++) {
1253 const uint8_t *src = (const uint8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1254 uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_BONES]];
1255
1256 dst[0] = src[0];
1257 dst[1] = src[1];
1258 dst[2] = src[2];
1259 dst[3] = src[3];
1260 }
1261 src_offset += sizeof(uint8_t) * 4;
1262 }
1263 } break;
1264 case OLD_ARRAY_WEIGHTS: {
1265 if (p_old_format & OLD_ARRAY_COMPRESS_WEIGHTS) {
1266 for (uint32_t i = 0; i < p_elements; i++) {
1267 const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1268 uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_WEIGHTS]];
1269
1270 dst[0] = src[0];
1271 dst[1] = src[1];
1272 dst[2] = src[2];
1273 dst[3] = src[3];
1274 }
1275 src_offset += sizeof(uint16_t) * 4;
1276 } else {
1277 for (uint32_t i = 0; i < p_elements; i++) {
1278 const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset];
1279 uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_WEIGHTS]];
1280
1281 dst[0] = uint16_t(CLAMP(src[0] * 65535.0, 0, 65535.0));
1282 dst[1] = uint16_t(CLAMP(src[1] * 65535.0, 0, 65535.0));
1283 dst[2] = uint16_t(CLAMP(src[2] * 65535.0, 0, 65535.0));
1284 dst[3] = uint16_t(CLAMP(src[3] * 65535.0, 0, 65535.0));
1285 }
1286 src_offset += sizeof(float) * 4;
1287 }
1288 } break;
1289 default: {
1290 }
1291 }
1292 }
1293}
1294
1295bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
1296 String sname = p_name;
1297
1298 if (sname.begins_with("surface_")) {
1299 int sl = sname.find("/");
1300 if (sl == -1) {
1301 return false;
1302 }
1303 int idx = sname.substr(8, sl - 8).to_int();
1304
1305 String what = sname.get_slicec('/', 1);
1306 if (what == "material") {
1307 surface_set_material(idx, p_value);
1308 } else if (what == "name") {
1309 surface_set_name(idx, p_value);
1310 }
1311 return true;
1312 }
1313
1314#ifndef DISABLE_DEPRECATED
1315 // Kept for compatibility from 3.x to 4.0.
1316 if (!sname.begins_with("surfaces")) {
1317 return false;
1318 }
1319
1320 WARN_DEPRECATED_MSG(vformat(
1321 "Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene. Path: \"%s\"",
1322 get_path()));
1323
1324 int idx = sname.get_slicec('/', 1).to_int();
1325 String what = sname.get_slicec('/', 2);
1326
1327 if (idx == surfaces.size()) {
1328 //create
1329 Dictionary d = p_value;
1330 ERR_FAIL_COND_V(!d.has("primitive"), false);
1331
1332 if (d.has("arrays")) {
1333 //oldest format (2.x)
1334 ERR_FAIL_COND_V(!d.has("morph_arrays"), false);
1335 Array morph_arrays = d["morph_arrays"];
1336 for (int i = 0; i < morph_arrays.size(); i++) {
1337 morph_arrays[i] = _convert_old_array(morph_arrays[i]);
1338 }
1339 add_surface_from_arrays(_old_primitives[int(d["primitive"])], _convert_old_array(d["arrays"]), morph_arrays);
1340
1341 } else if (d.has("array_data")) {
1342 //print_line("array data (old style");
1343 //older format (3.x)
1344 Vector<uint8_t> array_data = d["array_data"];
1345 Vector<uint8_t> array_index_data;
1346 if (d.has("array_index_data")) {
1347 array_index_data = d["array_index_data"];
1348 }
1349
1350 ERR_FAIL_COND_V(!d.has("format"), false);
1351 uint32_t old_format = d["format"];
1352
1353 uint32_t primitive = d["primitive"];
1354
1355 primitive = _old_primitives[primitive]; //compatibility
1356
1357 ERR_FAIL_COND_V(!d.has("vertex_count"), false);
1358 int vertex_count = d["vertex_count"];
1359
1360 uint32_t new_format = ARRAY_FORMAT_VERTEX;
1361
1362 if (old_format & OLD_ARRAY_FORMAT_NORMAL) {
1363 new_format |= ARRAY_FORMAT_NORMAL;
1364 }
1365 if (old_format & OLD_ARRAY_FORMAT_TANGENT) {
1366 new_format |= ARRAY_FORMAT_TANGENT;
1367 }
1368 if (old_format & OLD_ARRAY_FORMAT_COLOR) {
1369 new_format |= ARRAY_FORMAT_COLOR;
1370 }
1371 if (old_format & OLD_ARRAY_FORMAT_TEX_UV) {
1372 new_format |= ARRAY_FORMAT_TEX_UV;
1373 }
1374 if (old_format & OLD_ARRAY_FORMAT_TEX_UV2) {
1375 new_format |= ARRAY_FORMAT_TEX_UV2;
1376 }
1377 if (old_format & OLD_ARRAY_FORMAT_BONES) {
1378 new_format |= ARRAY_FORMAT_BONES;
1379 }
1380 if (old_format & OLD_ARRAY_FORMAT_WEIGHTS) {
1381 new_format |= ARRAY_FORMAT_WEIGHTS;
1382 }
1383 if (old_format & OLD_ARRAY_FORMAT_INDEX) {
1384 new_format |= ARRAY_FORMAT_INDEX;
1385 }
1386 if (old_format & OLD_ARRAY_FLAG_USE_2D_VERTICES) {
1387 new_format |= OLD_ARRAY_FLAG_USE_2D_VERTICES;
1388 }
1389
1390 Vector<uint8_t> vertex_array;
1391 Vector<uint8_t> attribute_array;
1392 Vector<uint8_t> skin_array;
1393
1394 _fix_array_compatibility(array_data, old_format, new_format, vertex_count, vertex_array, attribute_array, skin_array);
1395
1396 int index_count = 0;
1397 if (d.has("index_count")) {
1398 index_count = d["index_count"];
1399 }
1400
1401 Vector<uint8_t> blend_shapes_new;
1402
1403 if (d.has("blend_shape_data")) {
1404 Array blend_shape_data = d["blend_shape_data"];
1405 for (int i = 0; i < blend_shape_data.size(); i++) {
1406 Vector<uint8_t> blend_vertex_array;
1407 Vector<uint8_t> blend_attribute_array;
1408 Vector<uint8_t> blend_skin_array;
1409
1410 Vector<uint8_t> shape = blend_shape_data[i];
1411 _fix_array_compatibility(shape, old_format, new_format, vertex_count, blend_vertex_array, blend_attribute_array, blend_skin_array);
1412
1413 blend_shapes_new.append_array(blend_vertex_array);
1414 }
1415 }
1416
1417 //clear unused flags
1418 print_verbose("Mesh format pre-conversion: " + itos(old_format));
1419
1420 print_verbose("Mesh format post-conversion: " + itos(new_format));
1421
1422 ERR_FAIL_COND_V(!d.has("aabb"), false);
1423 AABB aabb_new = d["aabb"];
1424
1425 Vector<AABB> bone_aabb;
1426 if (d.has("skeleton_aabb")) {
1427 Array baabb = d["skeleton_aabb"];
1428 bone_aabb.resize(baabb.size());
1429
1430 for (int i = 0; i < baabb.size(); i++) {
1431 bone_aabb.write[i] = baabb[i];
1432 }
1433 }
1434
1435 add_surface(new_format, PrimitiveType(primitive), vertex_array, attribute_array, skin_array, vertex_count, array_index_data, index_count, aabb_new, blend_shapes_new, bone_aabb);
1436
1437 } else {
1438 ERR_FAIL_V(false);
1439 }
1440
1441 if (d.has("material")) {
1442 surface_set_material(idx, d["material"]);
1443 }
1444 if (d.has("name")) {
1445 surface_set_name(idx, d["name"]);
1446 }
1447
1448 return true;
1449 }
1450#endif // DISABLE_DEPRECATED
1451
1452 return false;
1453}
1454
1455void ArrayMesh::_set_blend_shape_names(const PackedStringArray &p_names) {
1456 ERR_FAIL_COND(surfaces.size() > 0);
1457
1458 blend_shapes.resize(p_names.size());
1459 for (int i = 0; i < p_names.size(); i++) {
1460 blend_shapes.write[i] = p_names[i];
1461 }
1462
1463 if (mesh.is_valid()) {
1464 RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size());
1465 }
1466}
1467
1468PackedStringArray ArrayMesh::_get_blend_shape_names() const {
1469 PackedStringArray sarr;
1470 sarr.resize(blend_shapes.size());
1471 for (int i = 0; i < blend_shapes.size(); i++) {
1472 sarr.write[i] = blend_shapes[i];
1473 }
1474 return sarr;
1475}
1476
1477Array ArrayMesh::_get_surfaces() const {
1478 if (mesh.is_null()) {
1479 return Array();
1480 }
1481
1482 Array ret;
1483 for (int i = 0; i < surfaces.size(); i++) {
1484 RenderingServer::SurfaceData surface = RS::get_singleton()->mesh_get_surface(mesh, i);
1485 Dictionary data;
1486 data["format"] = surface.format;
1487 data["primitive"] = surface.primitive;
1488 data["vertex_data"] = surface.vertex_data;
1489 data["vertex_count"] = surface.vertex_count;
1490 if (surface.skin_data.size()) {
1491 data["skin_data"] = surface.skin_data;
1492 }
1493 if (surface.attribute_data.size()) {
1494 data["attribute_data"] = surface.attribute_data;
1495 }
1496 data["aabb"] = surface.aabb;
1497 if (surface.index_count) {
1498 data["index_data"] = surface.index_data;
1499 data["index_count"] = surface.index_count;
1500 };
1501
1502 Array lods;
1503 for (int j = 0; j < surface.lods.size(); j++) {
1504 lods.push_back(surface.lods[j].edge_length);
1505 lods.push_back(surface.lods[j].index_data);
1506 }
1507
1508 if (lods.size()) {
1509 data["lods"] = lods;
1510 }
1511
1512 Array bone_aabbs;
1513 for (int j = 0; j < surface.bone_aabbs.size(); j++) {
1514 bone_aabbs.push_back(surface.bone_aabbs[j]);
1515 }
1516 if (bone_aabbs.size()) {
1517 data["bone_aabbs"] = bone_aabbs;
1518 }
1519
1520 if (surface.blend_shape_data.size()) {
1521 data["blend_shapes"] = surface.blend_shape_data;
1522 }
1523
1524 if (surfaces[i].material.is_valid()) {
1525 data["material"] = surfaces[i].material;
1526 }
1527
1528 if (!surfaces[i].name.is_empty()) {
1529 data["name"] = surfaces[i].name;
1530 }
1531
1532 if (surfaces[i].is_2d) {
1533 data["2d"] = true;
1534 }
1535
1536 ret.push_back(data);
1537 }
1538
1539 return ret;
1540}
1541
1542void ArrayMesh::_create_if_empty() const {
1543 if (!mesh.is_valid()) {
1544 mesh = RS::get_singleton()->mesh_create();
1545 RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode);
1546 RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size());
1547 }
1548}
1549
1550void ArrayMesh::_set_surfaces(const Array &p_surfaces) {
1551 Vector<RS::SurfaceData> surface_data;
1552 Vector<Ref<Material>> surface_materials;
1553 Vector<String> surface_names;
1554 Vector<bool> surface_2d;
1555
1556 for (int i = 0; i < p_surfaces.size(); i++) {
1557 RS::SurfaceData surface;
1558 Dictionary d = p_surfaces[i];
1559 ERR_FAIL_COND(!d.has("format"));
1560 ERR_FAIL_COND(!d.has("primitive"));
1561 ERR_FAIL_COND(!d.has("vertex_data"));
1562 ERR_FAIL_COND(!d.has("vertex_count"));
1563 ERR_FAIL_COND(!d.has("aabb"));
1564 surface.format = d["format"];
1565 surface.primitive = RS::PrimitiveType(int(d["primitive"]));
1566 surface.vertex_data = d["vertex_data"];
1567 surface.vertex_count = d["vertex_count"];
1568 if (d.has("attribute_data")) {
1569 surface.attribute_data = d["attribute_data"];
1570 }
1571 if (d.has("skin_data")) {
1572 surface.skin_data = d["skin_data"];
1573 }
1574 surface.aabb = d["aabb"];
1575
1576 if (d.has("index_data")) {
1577 ERR_FAIL_COND(!d.has("index_count"));
1578 surface.index_data = d["index_data"];
1579 surface.index_count = d["index_count"];
1580 }
1581
1582 if (d.has("lods")) {
1583 Array lods = d["lods"];
1584 ERR_FAIL_COND(lods.size() & 1); //must be even
1585 for (int j = 0; j < lods.size(); j += 2) {
1586 RS::SurfaceData::LOD lod;
1587 lod.edge_length = lods[j + 0];
1588 lod.index_data = lods[j + 1];
1589 surface.lods.push_back(lod);
1590 }
1591 }
1592
1593 if (d.has("bone_aabbs")) {
1594 Array bone_aabbs = d["bone_aabbs"];
1595 for (int j = 0; j < bone_aabbs.size(); j++) {
1596 surface.bone_aabbs.push_back(bone_aabbs[j]);
1597 }
1598 }
1599
1600 if (d.has("blend_shapes")) {
1601 surface.blend_shape_data = d["blend_shapes"];
1602 }
1603
1604 Ref<Material> material;
1605 if (d.has("material")) {
1606 material = d["material"];
1607 if (material.is_valid()) {
1608 surface.material = material->get_rid();
1609 }
1610 }
1611
1612 String surf_name;
1613 if (d.has("name")) {
1614 surf_name = d["name"];
1615 }
1616
1617 bool _2d = false;
1618 if (d.has("2d")) {
1619 _2d = d["2d"];
1620 }
1621
1622 surface_data.push_back(surface);
1623 surface_materials.push_back(material);
1624 surface_names.push_back(surf_name);
1625 surface_2d.push_back(_2d);
1626 }
1627
1628 if (mesh.is_valid()) {
1629 //if mesh exists, it needs to be updated
1630 RS::get_singleton()->mesh_clear(mesh);
1631 for (int i = 0; i < surface_data.size(); i++) {
1632 RS::get_singleton()->mesh_add_surface(mesh, surface_data[i]);
1633 }
1634 } else {
1635 // if mesh does not exist (first time this is loaded, most likely),
1636 // we can create it with a single call, which is a lot more efficient and thread friendly
1637 mesh = RS::get_singleton()->mesh_create_from_surfaces(surface_data, blend_shapes.size());
1638 RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode);
1639 }
1640
1641 surfaces.clear();
1642
1643 aabb = AABB();
1644 for (int i = 0; i < surface_data.size(); i++) {
1645 Surface s;
1646 s.aabb = surface_data[i].aabb;
1647 if (i == 0) {
1648 aabb = s.aabb;
1649 } else {
1650 aabb.merge_with(s.aabb);
1651 }
1652
1653 s.material = surface_materials[i];
1654 s.is_2d = surface_2d[i];
1655 s.name = surface_names[i];
1656
1657 s.format = surface_data[i].format;
1658 s.primitive = PrimitiveType(surface_data[i].primitive);
1659 s.array_length = surface_data[i].vertex_count;
1660 s.index_array_length = surface_data[i].index_count;
1661
1662 surfaces.push_back(s);
1663 }
1664}
1665
1666bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
1667 if (_is_generated()) {
1668 return false;
1669 }
1670
1671 String sname = p_name;
1672 if (sname.begins_with("surface_")) {
1673 int sl = sname.find("/");
1674 if (sl == -1) {
1675 return false;
1676 }
1677 int idx = sname.substr(8, sl - 8).to_int();
1678 String what = sname.get_slicec('/', 1);
1679 if (what == "material") {
1680 r_ret = surface_get_material(idx);
1681 } else if (what == "name") {
1682 r_ret = surface_get_name(idx);
1683 }
1684 return true;
1685 }
1686
1687 return true;
1688}
1689
1690void ArrayMesh::reset_state() {
1691 clear_surfaces();
1692 clear_blend_shapes();
1693
1694 aabb = AABB();
1695 blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
1696 custom_aabb = AABB();
1697}
1698
1699void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
1700 if (_is_generated()) {
1701 return;
1702 }
1703
1704 for (int i = 0; i < surfaces.size(); i++) {
1705 p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
1706 if (surfaces[i].is_2d) {
1707 p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial,ShaderMaterial", PROPERTY_USAGE_EDITOR));
1708 } else {
1709 p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_EDITOR));
1710 }
1711 }
1712}
1713
1714void ArrayMesh::_recompute_aabb() {
1715 // regenerate AABB
1716 aabb = AABB();
1717
1718 for (int i = 0; i < surfaces.size(); i++) {
1719 if (i == 0) {
1720 aabb = surfaces[i].aabb;
1721 } else {
1722 aabb.merge_with(surfaces[i].aabb);
1723 }
1724 }
1725}
1726
1727// TODO: Need to add binding to add_surface using future MeshSurfaceData object.
1728void ArrayMesh::add_surface(BitField<ArrayFormat> p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data, const Vector<AABB> &p_bone_aabbs, const Vector<RS::SurfaceData::LOD> &p_lods) {
1729 ERR_FAIL_COND(surfaces.size() == RS::MAX_MESH_SURFACES);
1730 _create_if_empty();
1731
1732 Surface s;
1733 s.aabb = p_aabb;
1734 s.is_2d = p_format & ARRAY_FLAG_USE_2D_VERTICES;
1735 s.primitive = p_primitive;
1736 s.array_length = p_vertex_count;
1737 s.index_array_length = p_index_count;
1738 s.format = p_format;
1739
1740 surfaces.push_back(s);
1741 _recompute_aabb();
1742
1743 RS::SurfaceData sd;
1744 sd.format = p_format;
1745 sd.primitive = RS::PrimitiveType(p_primitive);
1746 sd.aabb = p_aabb;
1747 sd.vertex_count = p_vertex_count;
1748 sd.vertex_data = p_array;
1749 sd.attribute_data = p_attribute_array;
1750 sd.skin_data = p_skin_array;
1751 sd.index_count = p_index_count;
1752 sd.index_data = p_index_array;
1753 sd.blend_shape_data = p_blend_shape_data;
1754 sd.bone_aabbs = p_bone_aabbs;
1755 sd.lods = p_lods;
1756
1757 RenderingServer::get_singleton()->mesh_add_surface(mesh, sd);
1758
1759 clear_cache();
1760 notify_property_list_changed();
1761 emit_changed();
1762}
1763
1764void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, BitField<ArrayFormat> p_flags) {
1765 ERR_FAIL_COND(p_blend_shapes.size() != blend_shapes.size());
1766 ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX);
1767
1768 RS::SurfaceData surface;
1769
1770 Error err = RS::get_singleton()->mesh_create_surface_data_from_arrays(&surface, (RenderingServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_lods, p_flags);
1771 ERR_FAIL_COND(err != OK);
1772
1773 /* Debug code.
1774 print_line("format: " + itos(surface.format));
1775 print_line("aabb: " + surface.aabb);
1776 print_line("array size: " + itos(surface.vertex_data.size()));
1777 print_line("vertex count: " + itos(surface.vertex_count));
1778 print_line("index size: " + itos(surface.index_data.size()));
1779 print_line("index count: " + itos(surface.index_count));
1780 print_line("primitive: " + itos(surface.primitive));
1781 */
1782
1783 add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.attribute_data, surface.skin_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shape_data, surface.bone_aabbs, surface.lods);
1784}
1785
1786Array ArrayMesh::surface_get_arrays(int p_surface) const {
1787 ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
1788 return RenderingServer::get_singleton()->mesh_surface_get_arrays(mesh, p_surface);
1789}
1790
1791TypedArray<Array> ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const {
1792 ERR_FAIL_INDEX_V(p_surface, surfaces.size(), TypedArray<Array>());
1793 return RenderingServer::get_singleton()->mesh_surface_get_blend_shape_arrays(mesh, p_surface);
1794}
1795
1796Dictionary ArrayMesh::surface_get_lods(int p_surface) const {
1797 ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Dictionary());
1798 return RenderingServer::get_singleton()->mesh_surface_get_lods(mesh, p_surface);
1799}
1800
1801int ArrayMesh::get_surface_count() const {
1802 return surfaces.size();
1803}
1804
1805void ArrayMesh::add_blend_shape(const StringName &p_name) {
1806 ERR_FAIL_COND_MSG(surfaces.size(), "Can't add a shape key count if surfaces are already created.");
1807
1808 StringName shape_name = p_name;
1809
1810 if (blend_shapes.has(shape_name)) {
1811 int count = 2;
1812 do {
1813 shape_name = String(p_name) + " " + itos(count);
1814 count++;
1815 } while (blend_shapes.has(shape_name));
1816 }
1817
1818 blend_shapes.push_back(shape_name);
1819
1820 if (mesh.is_valid()) {
1821 RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size());
1822 }
1823}
1824
1825int ArrayMesh::get_blend_shape_count() const {
1826 return blend_shapes.size();
1827}
1828
1829StringName ArrayMesh::get_blend_shape_name(int p_index) const {
1830 ERR_FAIL_INDEX_V(p_index, blend_shapes.size(), StringName());
1831 return blend_shapes[p_index];
1832}
1833
1834void ArrayMesh::set_blend_shape_name(int p_index, const StringName &p_name) {
1835 ERR_FAIL_INDEX(p_index, blend_shapes.size());
1836
1837 StringName shape_name = p_name;
1838 int found = blend_shapes.find(shape_name);
1839 if (found != -1 && found != p_index) {
1840 int count = 2;
1841 do {
1842 shape_name = String(p_name) + " " + itos(count);
1843 count++;
1844 } while (blend_shapes.find(shape_name) != -1);
1845 }
1846
1847 blend_shapes.write[p_index] = shape_name;
1848}
1849
1850void ArrayMesh::clear_blend_shapes() {
1851 ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created.");
1852
1853 blend_shapes.clear();
1854
1855 if (mesh.is_valid()) {
1856 RS::get_singleton()->mesh_set_blend_shape_count(mesh, 0);
1857 }
1858}
1859
1860void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) {
1861 blend_shape_mode = p_mode;
1862 if (mesh.is_valid()) {
1863 RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)p_mode);
1864 }
1865}
1866
1867ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const {
1868 return blend_shape_mode;
1869}
1870
1871int ArrayMesh::surface_get_array_len(int p_idx) const {
1872 ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
1873 return surfaces[p_idx].array_length;
1874}
1875
1876int ArrayMesh::surface_get_array_index_len(int p_idx) const {
1877 ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
1878 return surfaces[p_idx].index_array_length;
1879}
1880
1881BitField<Mesh::ArrayFormat> ArrayMesh::surface_get_format(int p_idx) const {
1882 ERR_FAIL_INDEX_V(p_idx, surfaces.size(), 0);
1883 return surfaces[p_idx].format;
1884}
1885
1886ArrayMesh::PrimitiveType ArrayMesh::surface_get_primitive_type(int p_idx) const {
1887 ERR_FAIL_INDEX_V(p_idx, surfaces.size(), PRIMITIVE_LINES);
1888 return surfaces[p_idx].primitive;
1889}
1890
1891void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
1892 ERR_FAIL_INDEX(p_idx, surfaces.size());
1893 if (surfaces[p_idx].material == p_material) {
1894 return;
1895 }
1896 surfaces.write[p_idx].material = p_material;
1897 RenderingServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid());
1898
1899 emit_changed();
1900}
1901
1902int ArrayMesh::surface_find_by_name(const String &p_name) const {
1903 for (int i = 0; i < surfaces.size(); i++) {
1904 if (surfaces[i].name == p_name) {
1905 return i;
1906 }
1907 }
1908 return -1;
1909}
1910
1911void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
1912 ERR_FAIL_INDEX(p_idx, surfaces.size());
1913
1914 surfaces.write[p_idx].name = p_name;
1915 emit_changed();
1916}
1917
1918String ArrayMesh::surface_get_name(int p_idx) const {
1919 ERR_FAIL_INDEX_V(p_idx, surfaces.size(), String());
1920 return surfaces[p_idx].name;
1921}
1922
1923void ArrayMesh::surface_update_vertex_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
1924 ERR_FAIL_INDEX(p_surface, surfaces.size());
1925 RS::get_singleton()->mesh_surface_update_vertex_region(mesh, p_surface, p_offset, p_data);
1926 emit_changed();
1927}
1928
1929void ArrayMesh::surface_update_attribute_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
1930 ERR_FAIL_INDEX(p_surface, surfaces.size());
1931 RS::get_singleton()->mesh_surface_update_attribute_region(mesh, p_surface, p_offset, p_data);
1932 emit_changed();
1933}
1934
1935void ArrayMesh::surface_update_skin_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
1936 ERR_FAIL_INDEX(p_surface, surfaces.size());
1937 RS::get_singleton()->mesh_surface_update_skin_region(mesh, p_surface, p_offset, p_data);
1938 emit_changed();
1939}
1940
1941void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) {
1942 ERR_FAIL_INDEX(p_idx, surfaces.size());
1943 surfaces.write[p_idx].aabb = p_aabb;
1944 // set custom aabb too?
1945 emit_changed();
1946}
1947
1948Ref<Material> ArrayMesh::surface_get_material(int p_idx) const {
1949 ERR_FAIL_INDEX_V(p_idx, surfaces.size(), Ref<Material>());
1950 return surfaces[p_idx].material;
1951}
1952
1953RID ArrayMesh::get_rid() const {
1954 _create_if_empty();
1955 return mesh;
1956}
1957
1958AABB ArrayMesh::get_aabb() const {
1959 return aabb;
1960}
1961
1962void ArrayMesh::clear_surfaces() {
1963 if (!mesh.is_valid()) {
1964 return;
1965 }
1966 RS::get_singleton()->mesh_clear(mesh);
1967 surfaces.clear();
1968 aabb = AABB();
1969}
1970
1971void ArrayMesh::set_custom_aabb(const AABB &p_custom) {
1972 _create_if_empty();
1973 custom_aabb = p_custom;
1974 RS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
1975 emit_changed();
1976}
1977
1978AABB ArrayMesh::get_custom_aabb() const {
1979 return custom_aabb;
1980}
1981
1982void ArrayMesh::regen_normal_maps() {
1983 if (surfaces.size() == 0) {
1984 return;
1985 }
1986 Vector<Ref<SurfaceTool>> surfs;
1987 for (int i = 0; i < get_surface_count(); i++) {
1988 Ref<SurfaceTool> st = memnew(SurfaceTool);
1989 st->create_from(Ref<ArrayMesh>(this), i);
1990 surfs.push_back(st);
1991 }
1992
1993 clear_surfaces();
1994
1995 for (int i = 0; i < surfs.size(); i++) {
1996 surfs.write[i]->generate_tangents();
1997 surfs.write[i]->commit(Ref<ArrayMesh>(this));
1998 }
1999}
2000
2001//dirty hack
2002bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, const uint8_t *p_cache_data, bool *r_use_cache, uint8_t **r_mesh_cache, int *r_mesh_cache_size, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = nullptr;
2003
2004struct ArrayMeshLightmapSurface {
2005 Ref<Material> material;
2006 LocalVector<SurfaceTool::Vertex> vertices;
2007 Mesh::PrimitiveType primitive = Mesh::PrimitiveType::PRIMITIVE_MAX;
2008 uint32_t format = 0;
2009};
2010
2011Error ArrayMesh::lightmap_unwrap(const Transform3D &p_base_transform, float p_texel_size) {
2012 Vector<uint8_t> null_cache;
2013 return lightmap_unwrap_cached(p_base_transform, p_texel_size, null_cache, null_cache, false);
2014}
2015
2016Error ArrayMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache, bool p_generate_cache) {
2017 ERR_FAIL_NULL_V(array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
2018 ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes.");
2019 ERR_FAIL_COND_V_MSG(p_texel_size <= 0.0f, ERR_PARAMETER_RANGE_ERROR, "Texel size must be greater than 0.");
2020
2021 LocalVector<float> vertices;
2022 LocalVector<float> normals;
2023 LocalVector<int> indices;
2024 LocalVector<float> uv;
2025 LocalVector<Pair<int, int>> uv_indices;
2026
2027 Vector<ArrayMeshLightmapSurface> lightmap_surfaces;
2028
2029 // Keep only the scale
2030 Basis basis = p_base_transform.get_basis();
2031 Vector3 scale = Vector3(basis.get_column(0).length(), basis.get_column(1).length(), basis.get_column(2).length());
2032
2033 Transform3D transform;
2034 transform.scale(scale);
2035
2036 Basis normal_basis = transform.basis.inverse().transposed();
2037
2038 for (int i = 0; i < get_surface_count(); i++) {
2039 ArrayMeshLightmapSurface s;
2040 s.primitive = surface_get_primitive_type(i);
2041
2042 ERR_FAIL_COND_V_MSG(s.primitive != Mesh::PRIMITIVE_TRIANGLES, ERR_UNAVAILABLE, "Only triangles are supported for lightmap unwrap.");
2043 s.format = surface_get_format(i);
2044 ERR_FAIL_COND_V_MSG(!(s.format & ARRAY_FORMAT_NORMAL), ERR_UNAVAILABLE, "Normals are required for lightmap unwrap.");
2045
2046 Array arrays = surface_get_arrays(i);
2047 s.material = surface_get_material(i);
2048 SurfaceTool::create_vertex_array_from_triangle_arrays(arrays, s.vertices, &s.format);
2049
2050 PackedVector3Array rvertices = arrays[Mesh::ARRAY_VERTEX];
2051 int vc = rvertices.size();
2052
2053 PackedVector3Array rnormals = arrays[Mesh::ARRAY_NORMAL];
2054
2055 int vertex_ofs = vertices.size() / 3;
2056
2057 vertices.resize((vertex_ofs + vc) * 3);
2058 normals.resize((vertex_ofs + vc) * 3);
2059 uv_indices.resize(vertex_ofs + vc);
2060
2061 for (int j = 0; j < vc; j++) {
2062 Vector3 v = transform.xform(rvertices[j]);
2063 Vector3 n = normal_basis.xform(rnormals[j]).normalized();
2064
2065 vertices[(j + vertex_ofs) * 3 + 0] = v.x;
2066 vertices[(j + vertex_ofs) * 3 + 1] = v.y;
2067 vertices[(j + vertex_ofs) * 3 + 2] = v.z;
2068 normals[(j + vertex_ofs) * 3 + 0] = n.x;
2069 normals[(j + vertex_ofs) * 3 + 1] = n.y;
2070 normals[(j + vertex_ofs) * 3 + 2] = n.z;
2071 uv_indices[j + vertex_ofs] = Pair<int, int>(i, j);
2072 }
2073
2074 PackedInt32Array rindices = arrays[Mesh::ARRAY_INDEX];
2075 int ic = rindices.size();
2076
2077 float eps = 1.19209290e-7F; // Taken from xatlas.h
2078 if (ic == 0) {
2079 for (int j = 0; j < vc / 3; j++) {
2080 Vector3 p0 = transform.xform(rvertices[j * 3 + 0]);
2081 Vector3 p1 = transform.xform(rvertices[j * 3 + 1]);
2082 Vector3 p2 = transform.xform(rvertices[j * 3 + 2]);
2083
2084 if ((p0 - p1).length_squared() < eps || (p1 - p2).length_squared() < eps || (p2 - p0).length_squared() < eps) {
2085 continue;
2086 }
2087
2088 indices.push_back(vertex_ofs + j * 3 + 0);
2089 indices.push_back(vertex_ofs + j * 3 + 1);
2090 indices.push_back(vertex_ofs + j * 3 + 2);
2091 }
2092
2093 } else {
2094 for (int j = 0; j < ic / 3; j++) {
2095 Vector3 p0 = transform.xform(rvertices[rindices[j * 3 + 0]]);
2096 Vector3 p1 = transform.xform(rvertices[rindices[j * 3 + 1]]);
2097 Vector3 p2 = transform.xform(rvertices[rindices[j * 3 + 2]]);
2098
2099 if ((p0 - p1).length_squared() < eps || (p1 - p2).length_squared() < eps || (p2 - p0).length_squared() < eps) {
2100 continue;
2101 }
2102
2103 indices.push_back(vertex_ofs + rindices[j * 3 + 0]);
2104 indices.push_back(vertex_ofs + rindices[j * 3 + 1]);
2105 indices.push_back(vertex_ofs + rindices[j * 3 + 2]);
2106 }
2107 }
2108
2109 lightmap_surfaces.push_back(s);
2110 }
2111
2112 //unwrap
2113
2114 bool use_cache = p_generate_cache; // Used to request cache generation and to know if cache was used
2115 uint8_t *gen_cache;
2116 int gen_cache_size;
2117 float *gen_uvs;
2118 int *gen_vertices;
2119 int *gen_indices;
2120 int gen_vertex_count;
2121 int gen_index_count;
2122 int size_x;
2123 int size_y;
2124
2125 bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), indices.size(), p_src_cache.ptr(), &use_cache, &gen_cache, &gen_cache_size, &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y);
2126
2127 if (!ok) {
2128 return ERR_CANT_CREATE;
2129 }
2130
2131 clear_surfaces();
2132
2133 //create surfacetools for each surface..
2134 LocalVector<Ref<SurfaceTool>> surfaces_tools;
2135
2136 for (int i = 0; i < lightmap_surfaces.size(); i++) {
2137 Ref<SurfaceTool> st;
2138 st.instantiate();
2139 st->begin(Mesh::PRIMITIVE_TRIANGLES);
2140 st->set_material(lightmap_surfaces[i].material);
2141 surfaces_tools.push_back(st); //stay there
2142 }
2143
2144 print_verbose("Mesh: Gen indices: " + itos(gen_index_count));
2145
2146 //go through all indices
2147 for (int i = 0; i < gen_index_count; i += 3) {
2148 ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], (int)uv_indices.size(), ERR_BUG);
2149 ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], (int)uv_indices.size(), ERR_BUG);
2150 ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], (int)uv_indices.size(), ERR_BUG);
2151
2152 ERR_FAIL_COND_V(uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 1]]].first || uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
2153
2154 int surface = uv_indices[gen_vertices[gen_indices[i + 0]]].first;
2155
2156 for (int j = 0; j < 3; j++) {
2157 SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second];
2158
2159 if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) {
2160 surfaces_tools[surface]->set_color(v.color);
2161 }
2162 if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
2163 surfaces_tools[surface]->set_uv(v.uv);
2164 }
2165 if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
2166 surfaces_tools[surface]->set_normal(v.normal);
2167 }
2168 if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
2169 Plane t;
2170 t.normal = v.tangent;
2171 t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
2172 surfaces_tools[surface]->set_tangent(t);
2173 }
2174 if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) {
2175 surfaces_tools[surface]->set_bones(v.bones);
2176 }
2177 if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
2178 surfaces_tools[surface]->set_weights(v.weights);
2179 }
2180
2181 Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
2182 surfaces_tools[surface]->set_uv2(uv2);
2183
2184 surfaces_tools[surface]->add_vertex(v.vertex);
2185 }
2186 }
2187
2188 //generate surfaces
2189 for (unsigned int i = 0; i < surfaces_tools.size(); i++) {
2190 surfaces_tools[i]->index();
2191 surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), lightmap_surfaces[i].format);
2192 }
2193
2194 set_lightmap_size_hint(Size2(size_x, size_y));
2195
2196 if (gen_cache_size > 0) {
2197 r_dst_cache.resize(gen_cache_size);
2198 memcpy(r_dst_cache.ptrw(), gen_cache, gen_cache_size);
2199 memfree(gen_cache);
2200 }
2201
2202 if (!use_cache) {
2203 // Cache was not used, free the buffers
2204 memfree(gen_vertices);
2205 memfree(gen_indices);
2206 memfree(gen_uvs);
2207 }
2208
2209 return OK;
2210}
2211
2212void ArrayMesh::set_shadow_mesh(const Ref<ArrayMesh> &p_mesh) {
2213 shadow_mesh = p_mesh;
2214 if (shadow_mesh.is_valid()) {
2215 RS::get_singleton()->mesh_set_shadow_mesh(mesh, shadow_mesh->get_rid());
2216 } else {
2217 RS::get_singleton()->mesh_set_shadow_mesh(mesh, RID());
2218 }
2219}
2220
2221Ref<ArrayMesh> ArrayMesh::get_shadow_mesh() const {
2222 return shadow_mesh;
2223}
2224
2225void ArrayMesh::_bind_methods() {
2226 ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
2227 ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count);
2228 ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &ArrayMesh::get_blend_shape_name);
2229 ClassDB::bind_method(D_METHOD("set_blend_shape_name", "index", "name"), &ArrayMesh::set_blend_shape_name);
2230 ClassDB::bind_method(D_METHOD("clear_blend_shapes"), &ArrayMesh::clear_blend_shapes);
2231 ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode);
2232 ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
2233
2234 ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0));
2235 ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces);
2236 ClassDB::bind_method(D_METHOD("surface_update_vertex_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_vertex_region);
2237 ClassDB::bind_method(D_METHOD("surface_update_attribute_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_attribute_region);
2238 ClassDB::bind_method(D_METHOD("surface_update_skin_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_skin_region);
2239 ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len);
2240 ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len);
2241 ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format);
2242 ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &ArrayMesh::surface_get_primitive_type);
2243 ClassDB::bind_method(D_METHOD("surface_find_by_name", "name"), &ArrayMesh::surface_find_by_name);
2244 ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name);
2245 ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name);
2246 ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape);
2247 ClassDB::bind_method(D_METHOD("create_convex_shape", "clean", "simplify"), &ArrayMesh::create_convex_shape, DEFVAL(true), DEFVAL(false));
2248 ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline);
2249 ClassDB::bind_method(D_METHOD("regen_normal_maps"), &ArrayMesh::regen_normal_maps);
2250 ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normal_maps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
2251 ClassDB::bind_method(D_METHOD("lightmap_unwrap", "transform", "texel_size"), &ArrayMesh::lightmap_unwrap);
2252 ClassDB::set_method_flags(get_class_static(), _scs_create("lightmap_unwrap"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
2253 ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &ArrayMesh::generate_triangle_mesh);
2254
2255 ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb);
2256 ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb);
2257
2258 ClassDB::bind_method(D_METHOD("set_shadow_mesh", "mesh"), &ArrayMesh::set_shadow_mesh);
2259 ClassDB::bind_method(D_METHOD("get_shadow_mesh"), &ArrayMesh::get_shadow_mesh);
2260
2261 ClassDB::bind_method(D_METHOD("_set_blend_shape_names", "blend_shape_names"), &ArrayMesh::_set_blend_shape_names);
2262 ClassDB::bind_method(D_METHOD("_get_blend_shape_names"), &ArrayMesh::_get_blend_shape_names);
2263
2264 ClassDB::bind_method(D_METHOD("_set_surfaces", "surfaces"), &ArrayMesh::_set_surfaces);
2265 ClassDB::bind_method(D_METHOD("_get_surfaces"), &ArrayMesh::_get_surfaces);
2266
2267 ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "_blend_shape_names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_blend_shape_names", "_get_blend_shape_names");
2268 ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_surfaces", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_surfaces", "_get_surfaces");
2269 ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode");
2270 ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, "suffix:m"), "set_custom_aabb", "get_custom_aabb");
2271 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shadow_mesh", PROPERTY_HINT_RESOURCE_TYPE, "ArrayMesh"), "set_shadow_mesh", "get_shadow_mesh");
2272}
2273
2274void ArrayMesh::reload_from_file() {
2275 RenderingServer::get_singleton()->mesh_clear(mesh);
2276 surfaces.clear();
2277 clear_blend_shapes();
2278 clear_cache();
2279
2280 Resource::reload_from_file();
2281
2282 notify_property_list_changed();
2283}
2284
2285ArrayMesh::ArrayMesh() {
2286 //mesh is now created on demand
2287 //mesh = RenderingServer::get_singleton()->mesh_create();
2288}
2289
2290ArrayMesh::~ArrayMesh() {
2291 if (mesh.is_valid()) {
2292 ERR_FAIL_NULL(RenderingServer::get_singleton());
2293 RenderingServer::get_singleton()->free(mesh);
2294 }
2295}
2296///////////////
2297
2298void PlaceholderMesh::_bind_methods() {
2299 ClassDB::bind_method(D_METHOD("set_aabb", "aabb"), &PlaceholderMesh::set_aabb);
2300 ADD_PROPERTY(PropertyInfo(Variant::AABB, "aabb", PROPERTY_HINT_NONE, "suffix:m"), "set_aabb", "get_aabb");
2301}
2302
2303PlaceholderMesh::PlaceholderMesh() {
2304 rid = RS::get_singleton()->mesh_create();
2305}
2306
2307PlaceholderMesh::~PlaceholderMesh() {
2308 ERR_FAIL_NULL(RenderingServer::get_singleton());
2309 RS::get_singleton()->free(rid);
2310}
2311