| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  mesh.cpp                                                             */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-01-03 21:27:34 +01:00
										 |  |  | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "mesh.h"
 | 
					
						
							| 
									
										
										
										
											2017-12-09 19:36:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | #include "core/math/convex_hull.h"
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/templates/pair.h"
 | 
					
						
							| 
									
										
										
										
											2022-08-19 19:15:46 -05:00
										 |  |  | #include "scene/resources/surface_tool.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | #include "scene/resources/concave_polygon_shape_3d.h"
 | 
					
						
							|  |  |  | #include "scene/resources/convex_polygon_shape_3d.h"
 | 
					
						
							| 
									
										
										
										
											2017-12-09 19:36:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 17:14:06 -07:00
										 |  |  | Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr; | 
					
						
							| 
									
										
										
										
											2019-04-10 17:46:04 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 08:17:38 +01:00
										 |  |  | int Mesh::get_surface_count() const { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_get_surface_count, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Mesh::surface_get_array_len(int p_idx) const { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_get_array_len, p_idx, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Mesh::surface_get_array_index_len(int p_idx) const { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_get_array_index_len, p_idx, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Array Mesh::surface_get_arrays(int p_surface) const { | 
					
						
							|  |  |  | 	Array ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_get_arrays, p_surface, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return Array(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 20:35:08 +02:00
										 |  |  | TypedArray<Array> Mesh::surface_get_blend_shape_arrays(int p_surface) const { | 
					
						
							|  |  |  | 	TypedArray<Array> ret; | 
					
						
							| 
									
										
										
										
											2022-03-10 08:17:38 +01:00
										 |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_get_blend_shape_arrays, p_surface, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 20:35:08 +02:00
										 |  |  | 	return TypedArray<Array>(); | 
					
						
							| 
									
										
										
										
											2022-03-10 08:17:38 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Dictionary Mesh::surface_get_lods(int p_surface) const { | 
					
						
							|  |  |  | 	Dictionary ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_get_lods, p_surface, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Dictionary(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint32_t Mesh::surface_get_format(int p_idx) const { | 
					
						
							|  |  |  | 	uint32_t ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_get_format, p_idx, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const { | 
					
						
							|  |  |  | 	uint32_t ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_get_primitive_type, p_idx, ret)) { | 
					
						
							|  |  |  | 		return (Mesh::PrimitiveType)ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return PRIMITIVE_MAX; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) { | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_set_material, p_idx, p_material)) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<Material> Mesh::surface_get_material(int p_idx) const { | 
					
						
							|  |  |  | 	Ref<Material> ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_surface_get_material, p_idx, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Ref<Material>(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Mesh::get_blend_shape_count() const { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_count, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | StringName Mesh::get_blend_shape_name(int p_index) const { | 
					
						
							|  |  |  | 	StringName ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_get_blend_shape_name, p_index, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return StringName(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Mesh::set_blend_shape_name(int p_index, const StringName &p_name) { | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_set_blend_shape_name, p_index, p_name)) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AABB Mesh::get_aabb() const { | 
					
						
							|  |  |  | 	AABB ret; | 
					
						
							|  |  |  | 	if (GDVIRTUAL_REQUIRED_CALL(_get_aabb, ret)) { | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return AABB(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (triangle_mesh.is_valid()) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return triangle_mesh; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-31 13:47:02 +02:00
										 |  |  | 	int faces_size = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	for (int i = 0; i < get_surface_count(); i++) { | 
					
						
							| 
									
										
										
										
											2022-05-31 13:47:02 +02:00
										 |  |  | 		switch (surface_get_primitive_type(i)) { | 
					
						
							|  |  |  | 			case PRIMITIVE_TRIANGLES: { | 
					
						
							|  |  |  | 				int len = (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? surface_get_array_index_len(i) : surface_get_array_len(i); | 
					
						
							|  |  |  | 				// Don't error if zero, it's valid (we'll just skip it later).
 | 
					
						
							|  |  |  | 				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)); | 
					
						
							|  |  |  | 				faces_size += len; | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case PRIMITIVE_TRIANGLE_STRIP: { | 
					
						
							|  |  |  | 				int len = (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? surface_get_array_index_len(i) : surface_get_array_len(i); | 
					
						
							|  |  |  | 				// Don't error if zero, it's valid (we'll just skip it later).
 | 
					
						
							|  |  |  | 				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)); | 
					
						
							|  |  |  | 				faces_size += (len == 0) ? 0 : (len - 2) * 3; | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			default: { | 
					
						
							|  |  |  | 			} break; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-31 13:47:02 +02:00
										 |  |  | 	if (faces_size == 0) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return triangle_mesh; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-14 01:22:15 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	Vector<Vector3> faces; | 
					
						
							| 
									
										
										
										
											2022-05-31 13:47:02 +02:00
										 |  |  | 	faces.resize(faces_size); | 
					
						
							| 
									
										
										
										
											2022-06-22 21:48:23 +02:00
										 |  |  | 	Vector<int32_t> surface_indices; | 
					
						
							|  |  |  | 	surface_indices.resize(faces_size / 3); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	Vector3 *facesw = faces.ptrw(); | 
					
						
							| 
									
										
										
										
											2022-06-22 21:48:23 +02:00
										 |  |  | 	int32_t *surface_indicesw = surface_indices.ptrw(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	int widx = 0; | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	for (int i = 0; i < get_surface_count(); i++) { | 
					
						
							| 
									
										
										
										
											2022-05-31 13:47:02 +02:00
										 |  |  | 		Mesh::PrimitiveType primitive = surface_get_primitive_type(i); | 
					
						
							|  |  |  | 		if (primitive != PRIMITIVE_TRIANGLES && primitive != PRIMITIVE_TRIANGLE_STRIP) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		int len = (surface_get_format(i) & ARRAY_FORMAT_INDEX) ? surface_get_array_index_len(i) : surface_get_array_len(i); | 
					
						
							| 
									
										
										
										
											2022-06-24 11:22:26 -07:00
										 |  |  | 		if ((primitive == PRIMITIVE_TRIANGLES && (len == 0 || (len % 3) != 0)) || | 
					
						
							|  |  |  | 				(primitive == PRIMITIVE_TRIANGLE_STRIP && len < 3) || | 
					
						
							|  |  |  | 				(surface_get_format(i) & ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY)) { | 
					
						
							| 
									
										
										
										
											2022-05-31 13:47:02 +02:00
										 |  |  | 			// Error was already shown, just skip (including zero).
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		Array a = surface_get_arrays(i); | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 		ERR_FAIL_COND_V(a.is_empty(), Ref<TriangleMesh>()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		int vc = surface_get_array_len(i); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		Vector<Vector3> vertices = a[ARRAY_VERTEX]; | 
					
						
							| 
									
										
										
										
											2022-06-24 11:22:26 -07:00
										 |  |  | 		ERR_FAIL_COND_V(vertices.is_empty(), Ref<TriangleMesh>()); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		const Vector3 *vr = vertices.ptr(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 21:48:23 +02:00
										 |  |  | 		int32_t from_index = widx / 3; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		if (surface_get_format(i) & ARRAY_FORMAT_INDEX) { | 
					
						
							|  |  |  | 			int ic = surface_get_array_index_len(i); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			Vector<int> indices = a[ARRAY_INDEX]; | 
					
						
							|  |  |  | 			const int *ir = indices.ptr(); | 
					
						
							| 
									
										
										
										
											2016-11-09 23:55:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-31 13:47:02 +02:00
										 |  |  | 			if (primitive == PRIMITIVE_TRIANGLES) { | 
					
						
							|  |  |  | 				for (int j = 0; j < ic; j++) { | 
					
						
							|  |  |  | 					int index = ir[j]; | 
					
						
							|  |  |  | 					facesw[widx++] = vr[index]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { // PRIMITIVE_TRIANGLE_STRIP
 | 
					
						
							|  |  |  | 				for (int j = 2; j < ic; j++) { | 
					
						
							|  |  |  | 					facesw[widx++] = vr[ir[j - 2]]; | 
					
						
							|  |  |  | 					facesw[widx++] = vr[ir[j - 1]]; | 
					
						
							|  |  |  | 					facesw[widx++] = vr[ir[j]]; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-11-09 23:55:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2022-05-31 13:47:02 +02:00
										 |  |  | 			if (primitive == PRIMITIVE_TRIANGLES) { | 
					
						
							|  |  |  | 				for (int j = 0; j < vc; j++) { | 
					
						
							|  |  |  | 					facesw[widx++] = vr[j]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { // PRIMITIVE_TRIANGLE_STRIP
 | 
					
						
							|  |  |  | 				for (int j = 2; j < vc; j++) { | 
					
						
							|  |  |  | 					facesw[widx++] = vr[j - 2]; | 
					
						
							|  |  |  | 					facesw[widx++] = vr[j - 1]; | 
					
						
							|  |  |  | 					facesw[widx++] = vr[j]; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-06-22 21:48:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		int32_t to_index = widx / 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (int j = from_index; j < to_index; j++) { | 
					
						
							|  |  |  | 			surface_indicesw[j] = i; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-09 23:55:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); | 
					
						
							|  |  |  | 	triangle_mesh->create(faces); | 
					
						
							| 
									
										
										
										
											2016-11-09 23:55:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	return triangle_mesh; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-11-09 23:55:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-23 13:32:55 +01:00
										 |  |  | Ref<TriangleMesh> Mesh::generate_surface_triangle_mesh(int p_surface) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_surface, get_surface_count(), Ref<TriangleMesh>()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (surface_triangle_meshes.size() != get_surface_count()) { | 
					
						
							|  |  |  | 		surface_triangle_meshes.resize(get_surface_count()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (surface_triangle_meshes[p_surface].is_valid()) { | 
					
						
							|  |  |  | 		return surface_triangle_meshes[p_surface]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int facecount = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (surface_get_primitive_type(p_surface) != PRIMITIVE_TRIANGLES) { | 
					
						
							|  |  |  | 		return Ref<TriangleMesh>(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { | 
					
						
							|  |  |  | 		facecount += surface_get_array_index_len(p_surface); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		facecount += surface_get_array_len(p_surface); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Vector<Vector3> faces; | 
					
						
							|  |  |  | 	faces.resize(facecount); | 
					
						
							|  |  |  | 	Vector3 *facesw = faces.ptrw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Array a = surface_get_arrays(p_surface); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(a.is_empty(), Ref<TriangleMesh>()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int vc = surface_get_array_len(p_surface); | 
					
						
							|  |  |  | 	Vector<Vector3> vertices = a[ARRAY_VERTEX]; | 
					
						
							|  |  |  | 	const Vector3 *vr = vertices.ptr(); | 
					
						
							|  |  |  | 	int widx = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { | 
					
						
							|  |  |  | 		int ic = surface_get_array_index_len(p_surface); | 
					
						
							|  |  |  | 		Vector<int> indices = a[ARRAY_INDEX]; | 
					
						
							|  |  |  | 		const int *ir = indices.ptr(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (int j = 0; j < ic; j++) { | 
					
						
							|  |  |  | 			int index = ir[j]; | 
					
						
							|  |  |  | 			facesw[widx++] = vr[index]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		for (int j = 0; j < vc; j++) { | 
					
						
							|  |  |  | 			facesw[widx++] = vr[j]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	Ref<TriangleMesh> tr_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); | 
					
						
							|  |  |  | 	tr_mesh->create(faces); | 
					
						
							|  |  |  | 	surface_triangle_meshes.set(p_surface, tr_mesh); | 
					
						
							| 
									
										
										
										
											2022-04-23 13:32:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	return tr_mesh; | 
					
						
							| 
									
										
										
										
											2022-04-23 13:32:55 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) { | 
					
						
							| 
									
										
										
										
											2018-09-09 19:39:34 +02:00
										 |  |  | 	if (debug_lines.size() > 0) { | 
					
						
							|  |  |  | 		r_lines = debug_lines; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 	Ref<TriangleMesh> tm = generate_triangle_mesh(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (tm.is_null()) { | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	Vector<int> triangle_indices; | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 	tm->get_indices(&triangle_indices); | 
					
						
							|  |  |  | 	const int triangles_num = tm->get_triangles().size(); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	Vector<Vector3> vertices = tm->get_vertices(); | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-09 19:39:34 +02:00
										 |  |  | 	debug_lines.resize(tm->get_triangles().size() * 6); // 3 lines x 2 points each line
 | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	const int *ind_r = triangle_indices.ptr(); | 
					
						
							|  |  |  | 	const Vector3 *ver_r = vertices.ptr(); | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 	for (int j = 0, x = 0, i = 0; i < triangles_num; j += 6, x += 3, ++i) { | 
					
						
							|  |  |  | 		// Triangle line 1
 | 
					
						
							| 
									
										
										
										
											2018-09-09 19:39:34 +02:00
										 |  |  | 		debug_lines.write[j + 0] = ver_r[ind_r[x + 0]]; | 
					
						
							|  |  |  | 		debug_lines.write[j + 1] = ver_r[ind_r[x + 1]]; | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Triangle line 2
 | 
					
						
							| 
									
										
										
										
											2018-09-09 19:39:34 +02:00
										 |  |  | 		debug_lines.write[j + 2] = ver_r[ind_r[x + 1]]; | 
					
						
							|  |  |  | 		debug_lines.write[j + 3] = ver_r[ind_r[x + 2]]; | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Triangle line 3
 | 
					
						
							| 
									
										
										
										
											2018-09-09 19:39:34 +02:00
										 |  |  | 		debug_lines.write[j + 4] = ver_r[ind_r[x + 2]]; | 
					
						
							|  |  |  | 		debug_lines.write[j + 5] = ver_r[ind_r[x + 0]]; | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-09-09 19:39:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	r_lines = debug_lines; | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) { | 
					
						
							|  |  |  | 	Ref<TriangleMesh> tm = generate_triangle_mesh(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (tm.is_null()) { | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	Vector<Vector3> vertices = tm->get_vertices(); | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int vertices_size = vertices.size(); | 
					
						
							|  |  |  | 	r_points.resize(vertices_size); | 
					
						
							|  |  |  | 	for (int i = 0; i < vertices_size; ++i) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		r_points.write[i] = vertices[i]; | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | Vector<Face3> Mesh::get_faces() const { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	Ref<TriangleMesh> tm = generate_triangle_mesh(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (tm.is_valid()) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return tm->get_faces(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	return Vector<Face3>(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-11-09 23:55:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-23 13:32:55 +01:00
										 |  |  | Vector<Face3> Mesh::get_surface_faces(int p_surface) const { | 
					
						
							|  |  |  | 	Ref<TriangleMesh> tm = generate_surface_triangle_mesh(p_surface); | 
					
						
							|  |  |  | 	if (tm.is_valid()) { | 
					
						
							|  |  |  | 		return tm->get_faces(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return Vector<Face3>(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const { | 
					
						
							|  |  |  | 	if (p_simplify) { | 
					
						
							| 
									
										
										
											
												Improve collision generation usability in the new 3D scene import workflow.
With this PR it's possible to add a collision during the Mesh import, directly in editor.
To generate the shape is possible to chose between the following options:
- Decompose Convex: The Mesh is decomposed in one or many Convex Shapes (Using the VHACD library).
- Simple Convex: Is generated a convex shape that enclose the entire mesh.
- Trimesh: Generate a trimesh shape using the Mesh faces.
- Box: Add a primitive box shape, where you can tweak the `size`, `position`, `rotation`.
- Sphere: Add a primitive sphere shape, where you can tweak the `radius`, `position`, `rotation`.
- Cylinder: Add a primitive cylinder shape, where you can tweak the `height`, `radius`, `position`, `rotation`.
- Capsule: Add a primitive capsule shape, where you can tweak the `height`, `radius`, `position`, `rotation`.
It's also possible to chose the generated body, so you can create:
- Rigid Body
- Static Body
- Area
											
										 
											2021-08-22 18:19:13 +02:00
										 |  |  | 		ConvexDecompositionSettings settings; | 
					
						
							|  |  |  | 		settings.max_convex_hulls = 1; | 
					
						
							|  |  |  | 		Vector<Ref<Shape3D>> decomposed = convex_decompose(settings); | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | 		if (decomposed.size() == 1) { | 
					
						
							|  |  |  | 			return decomposed[0]; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			ERR_PRINT("Convex shape simplification failed, falling back to simpler process."); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-09 23:55:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | 	Vector<Vector3> vertices; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	for (int i = 0; i < get_surface_count(); i++) { | 
					
						
							|  |  |  | 		Array a = surface_get_arrays(i); | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 		ERR_FAIL_COND_V(a.is_empty(), Ref<ConvexPolygonShape3D>()); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		Vector<Vector3> v = a[ARRAY_VERTEX]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		vertices.append_array(v); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D); | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (p_clean) { | 
					
						
							|  |  |  | 		Geometry3D::MeshData md; | 
					
						
							|  |  |  | 		Error err = ConvexHullComputer::convex_hull(vertices, md); | 
					
						
							|  |  |  | 		if (err == OK) { | 
					
						
							|  |  |  | 			shape->set_points(md.vertices); | 
					
						
							|  |  |  | 			return shape; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			ERR_PRINT("Convex shape cleaning failed, falling back to simpler process."); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	shape->set_points(vertices); | 
					
						
							|  |  |  | 	return shape; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | Ref<Shape3D> Mesh::create_trimesh_shape() const { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	Vector<Face3> faces = get_faces(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (faces.size() == 0) { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 		return Ref<Shape3D>(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-06 23:36:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	Vector<Vector3> face_points; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	face_points.resize(faces.size() * 3); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 00:33:39 +01:00
										 |  |  | 	for (int i = 0; i < face_points.size(); i += 3) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		Face3 f = faces.get(i / 3); | 
					
						
							| 
									
										
										
										
											2020-03-11 00:33:39 +01:00
										 |  |  | 		face_points.set(i, f.vertex[0]); | 
					
						
							|  |  |  | 		face_points.set(i + 1, f.vertex[1]); | 
					
						
							|  |  |  | 		face_points.set(i + 2, f.vertex[2]); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	Ref<ConcavePolygonShape3D> shape = memnew(ConcavePolygonShape3D); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	shape->set_faces(face_points); | 
					
						
							|  |  |  | 	return shape; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | Ref<Mesh> Mesh::create_outline(float p_margin) const { | 
					
						
							|  |  |  | 	Array arrays; | 
					
						
							|  |  |  | 	int index_accum = 0; | 
					
						
							|  |  |  | 	for (int i = 0; i < get_surface_count(); i++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		Array a = surface_get_arrays(i); | 
					
						
							| 
									
										
										
										
											2020-12-15 12:04:21 +00:00
										 |  |  | 		ERR_FAIL_COND_V(a.is_empty(), Ref<ArrayMesh>()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		if (i == 0) { | 
					
						
							|  |  |  | 			arrays = a; | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			Vector<Vector3> v = a[ARRAY_VERTEX]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			index_accum += v.size(); | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2018-05-13 23:26:45 -03:00
										 |  |  | 			int vcount = 0; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			for (int j = 0; j < arrays.size(); j++) { | 
					
						
							|  |  |  | 				if (arrays[j].get_type() == Variant::NIL || a[j].get_type() == Variant::NIL) { | 
					
						
							|  |  |  | 					//mismatch, do not use
 | 
					
						
							|  |  |  | 					arrays[j] = Variant(); | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-11-09 23:55:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 				switch (j) { | 
					
						
							|  |  |  | 					case ARRAY_VERTEX: | 
					
						
							|  |  |  | 					case ARRAY_NORMAL: { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 						Vector<Vector3> dst = arrays[j]; | 
					
						
							|  |  |  | 						Vector<Vector3> src = a[j]; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						if (j == ARRAY_VERTEX) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 							vcount = src.size(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 						if (dst.size() == 0 || src.size() == 0) { | 
					
						
							|  |  |  | 							arrays[j] = Variant(); | 
					
						
							|  |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						dst.append_array(src); | 
					
						
							|  |  |  | 						arrays[j] = dst; | 
					
						
							|  |  |  | 					} break; | 
					
						
							|  |  |  | 					case ARRAY_TANGENT: | 
					
						
							|  |  |  | 					case ARRAY_BONES: | 
					
						
							|  |  |  | 					case ARRAY_WEIGHTS: { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 						Vector<real_t> dst = arrays[j]; | 
					
						
							|  |  |  | 						Vector<real_t> src = a[j]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 						if (dst.size() == 0 || src.size() == 0) { | 
					
						
							|  |  |  | 							arrays[j] = Variant(); | 
					
						
							|  |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						dst.append_array(src); | 
					
						
							|  |  |  | 						arrays[j] = dst; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 					} break; | 
					
						
							|  |  |  | 					case ARRAY_COLOR: { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 						Vector<Color> dst = arrays[j]; | 
					
						
							|  |  |  | 						Vector<Color> src = a[j]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 						if (dst.size() == 0 || src.size() == 0) { | 
					
						
							|  |  |  | 							arrays[j] = Variant(); | 
					
						
							|  |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						dst.append_array(src); | 
					
						
							|  |  |  | 						arrays[j] = dst; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 					} break; | 
					
						
							|  |  |  | 					case ARRAY_TEX_UV: | 
					
						
							|  |  |  | 					case ARRAY_TEX_UV2: { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 						Vector<Vector2> dst = arrays[j]; | 
					
						
							|  |  |  | 						Vector<Vector2> src = a[j]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 						if (dst.size() == 0 || src.size() == 0) { | 
					
						
							|  |  |  | 							arrays[j] = Variant(); | 
					
						
							|  |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						dst.append_array(src); | 
					
						
							|  |  |  | 						arrays[j] = dst; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 					} break; | 
					
						
							|  |  |  | 					case ARRAY_INDEX: { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 						Vector<int> dst = arrays[j]; | 
					
						
							|  |  |  | 						Vector<int> src = a[j]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 						if (dst.size() == 0 || src.size() == 0) { | 
					
						
							|  |  |  | 							arrays[j] = Variant(); | 
					
						
							|  |  |  | 							continue; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						{ | 
					
						
							|  |  |  | 							int ss = src.size(); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 							int *w = src.ptrw(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 							for (int k = 0; k < ss; k++) { | 
					
						
							|  |  |  | 								w[k] += index_accum; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						dst.append_array(src); | 
					
						
							|  |  |  | 						arrays[j] = dst; | 
					
						
							|  |  |  | 						index_accum += vcount; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 					} break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-01 22:06:47 +07:00
										 |  |  | 	ERR_FAIL_COND_V(arrays.size() != ARRAY_MAX, Ref<ArrayMesh>()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		int *ir = nullptr; | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		Vector<int> indices = arrays[ARRAY_INDEX]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		bool has_indices = false; | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		Vector<Vector3> vertices = arrays[ARRAY_VERTEX]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		int vc = vertices.size(); | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(!vc, Ref<ArrayMesh>()); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		Vector3 *r = vertices.ptrw(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		if (indices.size()) { | 
					
						
							| 
									
										
										
										
											2019-12-11 08:57:57 +08:00
										 |  |  | 			ERR_FAIL_COND_V(indices.size() % 3 != 0, Ref<ArrayMesh>()); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			vc = indices.size(); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			ir = indices.ptrw(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			has_indices = true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 		HashMap<Vector3, Vector3> normal_accum; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		//fill normals with triangle normals
 | 
					
						
							|  |  |  | 		for (int i = 0; i < vc; i += 3) { | 
					
						
							|  |  |  | 			Vector3 t[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (has_indices) { | 
					
						
							|  |  |  | 				t[0] = r[ir[i + 0]]; | 
					
						
							|  |  |  | 				t[1] = r[ir[i + 1]]; | 
					
						
							|  |  |  | 				t[2] = r[ir[i + 2]]; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				t[0] = r[i + 0]; | 
					
						
							|  |  |  | 				t[1] = r[i + 1]; | 
					
						
							|  |  |  | 				t[2] = r[i + 2]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Vector3 n = Plane(t[0], t[1], t[2]).normal; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (int j = 0; j < 3; j++) { | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 				HashMap<Vector3, Vector3>::Iterator E = normal_accum.find(t[j]); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 				if (!E) { | 
					
						
							|  |  |  | 					normal_accum[t[j]] = n; | 
					
						
							|  |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 					float d = n.dot(E->value); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					if (d < 1.0) { | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 						E->value += n * (1.0 - d); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 					//E->get()+=n;
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		//normalize
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 14:13:42 -06:00
										 |  |  | 		for (KeyValue<Vector3, Vector3> &E : normal_accum) { | 
					
						
							|  |  |  | 			E.value.normalize(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		//displace normals
 | 
					
						
							|  |  |  | 		int vc2 = vertices.size(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		for (int i = 0; i < vc2; i++) { | 
					
						
							|  |  |  | 			Vector3 t = r[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 			HashMap<Vector3, Vector3>::Iterator E = normal_accum.find(t); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			ERR_CONTINUE(!E); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 			t += E->value * p_margin; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			r[i] = t; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		arrays[ARRAY_VERTEX] = vertices; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		if (!has_indices) { | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			Vector<int> new_indices; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			new_indices.resize(vertices.size()); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			int *iw = new_indices.ptrw(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			for (int j = 0; j < vc2; j += 3) { | 
					
						
							|  |  |  | 				iw[j] = j; | 
					
						
							|  |  |  | 				iw[j + 1] = j + 2; | 
					
						
							|  |  |  | 				iw[j + 2] = j + 1; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			arrays[ARRAY_INDEX] = new_indices; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			for (int j = 0; j < vc; j += 3) { | 
					
						
							|  |  |  | 				SWAP(ir[j + 1], ir[j + 2]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			arrays[ARRAY_INDEX] = indices; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	Ref<ArrayMesh> newmesh = memnew(ArrayMesh); | 
					
						
							|  |  |  | 	newmesh->add_surface_from_arrays(PRIMITIVE_TRIANGLES, arrays); | 
					
						
							|  |  |  | 	return newmesh; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 09:34:23 -03:00
										 |  |  | void Mesh::set_lightmap_size_hint(const Size2i &p_size) { | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 	lightmap_size_hint = p_size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 09:34:23 -03:00
										 |  |  | Size2i Mesh::get_lightmap_size_hint() const { | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 	return lightmap_size_hint; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-13 17:15:55 -05:00
										 |  |  | void Mesh::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint); | 
					
						
							| 
									
										
										
										
											2019-12-07 21:23:05 -05:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_aabb"), &Mesh::get_aabb); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 09:34:23 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint"); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-27 21:33:32 +10:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &Mesh::surface_get_arrays); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &Mesh::surface_get_blend_shape_arrays); | 
					
						
							| 
									
										
										
										
											2019-01-31 18:04:36 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material"), &Mesh::surface_set_material); | 
					
						
							| 
									
										
										
										
											2018-08-27 21:33:32 +10:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &Mesh::surface_get_material); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 	BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(PRIMITIVE_LINES); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP); | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 	BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP); | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_VERTEX); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_NORMAL); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_TANGENT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_COLOR); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_TEX_UV); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM0); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM1); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM2); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM3); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_BONES); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_INDEX); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_MAX); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_UNORM); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_SNORM); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_HALF); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_HALF); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_R_FLOAT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_FLOAT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGB_FLOAT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_FLOAT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_CUSTOM_MAX); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_TANGENT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2); | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3); | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK); | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE); | 
					
						
							| 
									
										
										
										
											2021-09-08 21:29:14 -07:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BITS); | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3_SHIFT); | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_MASK); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_COMPRESS_FLAGS_BASE); | 
					
						
							| 
									
										
										
										
											2017-09-12 22:09:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_8_BONE_WEIGHTS); | 
					
						
							| 
									
										
										
										
											2020-12-12 09:06:59 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); | 
					
						
							| 
									
										
										
										
											2022-03-10 08:17:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_get_surface_count) | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_get_array_len, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_get_array_index_len, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_get_arrays, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_get_blend_shape_arrays, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_get_lods, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_get_format, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_get_primitive_type, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_set_material, "index", "material") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_surface_get_material, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_get_blend_shape_count) | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_get_blend_shape_name, "index") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_set_blend_shape_name, "index", "name") | 
					
						
							|  |  |  | 	GDVIRTUAL_BIND(_get_aabb) | 
					
						
							| 
									
										
										
										
											2017-07-13 17:15:55 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-09 19:39:34 +02:00
										 |  |  | void Mesh::clear_cache() const { | 
					
						
							|  |  |  | 	triangle_mesh.unref(); | 
					
						
							|  |  |  | 	debug_lines.clear(); | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Improve collision generation usability in the new 3D scene import workflow.
With this PR it's possible to add a collision during the Mesh import, directly in editor.
To generate the shape is possible to chose between the following options:
- Decompose Convex: The Mesh is decomposed in one or many Convex Shapes (Using the VHACD library).
- Simple Convex: Is generated a convex shape that enclose the entire mesh.
- Trimesh: Generate a trimesh shape using the Mesh faces.
- Box: Add a primitive box shape, where you can tweak the `size`, `position`, `rotation`.
- Sphere: Add a primitive sphere shape, where you can tweak the `radius`, `position`, `rotation`.
- Cylinder: Add a primitive cylinder shape, where you can tweak the `height`, `radius`, `position`, `rotation`.
- Capsule: Add a primitive capsule shape, where you can tweak the `height`, `radius`, `position`, `rotation`.
It's also possible to chose the generated body, so you can create:
- Rigid Body
- Static Body
- Area
											
										 
											2021-08-22 18:19:13 +02:00
										 |  |  | Vector<Ref<Shape3D>> Mesh::convex_decompose(const ConvexDecompositionSettings &p_settings) const { | 
					
						
							| 
									
										
										
										
											2021-09-14 17:14:06 -07:00
										 |  |  | 	ERR_FAIL_COND_V(!convex_decomposition_function, Vector<Ref<Shape3D>>()); | 
					
						
							| 
									
										
										
										
											2019-04-10 17:46:04 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 17:14:06 -07:00
										 |  |  | 	Ref<TriangleMesh> tm = generate_triangle_mesh(); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!tm.is_valid(), Vector<Ref<Shape3D>>()); | 
					
						
							| 
									
										
										
										
											2019-04-10 17:46:04 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 17:14:06 -07:00
										 |  |  | 	const Vector<TriangleMesh::Triangle> &triangles = tm->get_triangles(); | 
					
						
							|  |  |  | 	int triangle_count = triangles.size(); | 
					
						
							| 
									
										
										
										
											2019-04-10 17:46:04 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 17:14:06 -07:00
										 |  |  | 	Vector<uint32_t> indices; | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		indices.resize(triangle_count * 3); | 
					
						
							|  |  |  | 		uint32_t *w = indices.ptrw(); | 
					
						
							|  |  |  | 		for (int i = 0; i < triangle_count; i++) { | 
					
						
							|  |  |  | 			for (int j = 0; j < 3; j++) { | 
					
						
							|  |  |  | 				w[i * 3 + j] = triangles[i].indices[j]; | 
					
						
							| 
									
										
										
										
											2019-04-10 17:46:04 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-09-14 17:14:06 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const Vector<Vector3> &vertices = tm->get_vertices(); | 
					
						
							|  |  |  | 	int vertex_count = vertices.size(); | 
					
						
							| 
									
										
										
										
											2019-04-10 17:46:04 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-14 17:14:06 -07:00
										 |  |  | 	Vector<Vector<Vector3>> decomposed = convex_decomposition_function((real_t *)vertices.ptr(), vertex_count, indices.ptr(), triangle_count, p_settings, nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Vector<Ref<Shape3D>> ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < decomposed.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 		Ref<ConvexPolygonShape3D> shape; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:03:09 -06:00
										 |  |  | 		shape.instantiate(); | 
					
						
							| 
									
										
										
										
											2021-09-14 17:14:06 -07:00
										 |  |  | 		shape->set_points(decomposed[i]); | 
					
						
							| 
									
										
										
										
											2019-04-10 17:46:04 -03:00
										 |  |  | 		ret.push_back(shape); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-27 12:43:49 -03:00
										 |  |  | int Mesh::get_builtin_bind_pose_count() const { | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-10-17 01:08:21 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | Transform3D Mesh::get_builtin_bind_pose(int p_index) const { | 
					
						
							|  |  |  | 	return Transform3D(); | 
					
						
							| 
									
										
										
										
											2021-04-27 12:43:49 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | Mesh::Mesh() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-12-04 15:54:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | enum OldArrayType { | 
					
						
							|  |  |  | 	OLD_ARRAY_VERTEX, | 
					
						
							|  |  |  | 	OLD_ARRAY_NORMAL, | 
					
						
							|  |  |  | 	OLD_ARRAY_TANGENT, | 
					
						
							|  |  |  | 	OLD_ARRAY_COLOR, | 
					
						
							|  |  |  | 	OLD_ARRAY_TEX_UV, | 
					
						
							|  |  |  | 	OLD_ARRAY_TEX_UV2, | 
					
						
							|  |  |  | 	OLD_ARRAY_BONES, | 
					
						
							|  |  |  | 	OLD_ARRAY_WEIGHTS, | 
					
						
							|  |  |  | 	OLD_ARRAY_INDEX, | 
					
						
							|  |  |  | 	OLD_ARRAY_MAX, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum OldArrayFormat { | 
					
						
							|  |  |  | 	/* OLD_ARRAY FORMAT FLAGS */ | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_VERTEX = 1 << OLD_ARRAY_VERTEX, // mandatory
 | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_NORMAL = 1 << OLD_ARRAY_NORMAL, | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_TANGENT = 1 << OLD_ARRAY_TANGENT, | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_COLOR = 1 << OLD_ARRAY_COLOR, | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_TEX_UV = 1 << OLD_ARRAY_TEX_UV, | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_TEX_UV2 = 1 << OLD_ARRAY_TEX_UV2, | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_BONES = 1 << OLD_ARRAY_BONES, | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_WEIGHTS = 1 << OLD_ARRAY_WEIGHTS, | 
					
						
							|  |  |  | 	OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1), | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_VERTEX = 1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE), // mandatory
 | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE), | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE), | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE), | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE), | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE), | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_BONES = 1 << (OLD_ARRAY_BONES + OLD_ARRAY_COMPRESS_BASE), | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_WEIGHTS = 1 << (OLD_ARRAY_WEIGHTS + OLD_ARRAY_COMPRESS_BASE), | 
					
						
							|  |  |  | 	OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1, | 
					
						
							|  |  |  | 	OLD_ARRAY_FLAG_USE_16_BIT_BONES = OLD_ARRAY_COMPRESS_INDEX << 2, | 
					
						
							|  |  |  | 	OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3, | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 	OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION = OLD_ARRAY_COMPRESS_INDEX << 4, | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-10 00:54:24 -04:00
										 |  |  | #ifndef DISABLE_DEPRECATED
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | static Array _convert_old_array(const Array &p_old) { | 
					
						
							|  |  |  | 	Array new_array; | 
					
						
							|  |  |  | 	new_array.resize(Mesh::ARRAY_MAX); | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_VERTEX] = p_old[OLD_ARRAY_VERTEX]; | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_NORMAL] = p_old[OLD_ARRAY_NORMAL]; | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_TANGENT] = p_old[OLD_ARRAY_TANGENT]; | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_COLOR] = p_old[OLD_ARRAY_COLOR]; | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_TEX_UV] = p_old[OLD_ARRAY_TEX_UV]; | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_TEX_UV2] = p_old[OLD_ARRAY_TEX_UV2]; | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_BONES] = p_old[OLD_ARRAY_BONES]; | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_WEIGHTS] = p_old[OLD_ARRAY_WEIGHTS]; | 
					
						
							|  |  |  | 	new_array[Mesh::ARRAY_INDEX] = p_old[OLD_ARRAY_INDEX]; | 
					
						
							|  |  |  | 	return new_array; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | static Mesh::PrimitiveType _old_primitives[7] = { | 
					
						
							|  |  |  | 	Mesh::PRIMITIVE_POINTS, | 
					
						
							|  |  |  | 	Mesh::PRIMITIVE_LINES, | 
					
						
							|  |  |  | 	Mesh::PRIMITIVE_LINE_STRIP, | 
					
						
							|  |  |  | 	Mesh::PRIMITIVE_LINES, | 
					
						
							|  |  |  | 	Mesh::PRIMITIVE_TRIANGLES, | 
					
						
							|  |  |  | 	Mesh::PRIMITIVE_TRIANGLE_STRIP, | 
					
						
							|  |  |  | 	Mesh::PRIMITIVE_TRIANGLE_STRIP | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-08-10 00:54:24 -04:00
										 |  |  | #endif // DISABLE_DEPRECATED
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void _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) { | 
					
						
							|  |  |  | 	uint32_t dst_vertex_stride; | 
					
						
							|  |  |  | 	uint32_t dst_attribute_stride; | 
					
						
							|  |  |  | 	uint32_t dst_skin_stride; | 
					
						
							|  |  |  | 	uint32_t dst_offsets[Mesh::ARRAY_MAX]; | 
					
						
							|  |  |  | 	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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vertex_data.resize(dst_vertex_stride * p_elements); | 
					
						
							|  |  |  | 	attribute_data.resize(dst_attribute_stride * p_elements); | 
					
						
							|  |  |  | 	skin_data.resize(dst_skin_stride * p_elements); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uint8_t *dst_vertex_ptr = vertex_data.ptrw(); | 
					
						
							|  |  |  | 	uint8_t *dst_attribute_ptr = attribute_data.ptrw(); | 
					
						
							|  |  |  | 	uint8_t *dst_skin_ptr = skin_data.ptrw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const uint8_t *src_vertex_ptr = p_src.ptr(); | 
					
						
							|  |  |  | 	uint32_t src_vertex_stride = p_src.size() / p_elements; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uint32_t src_offset = 0; | 
					
						
							|  |  |  | 	for (uint32_t j = 0; j < OLD_ARRAY_INDEX; j++) { | 
					
						
							|  |  |  | 		if (!(p_old_format & (1 << j))) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		switch (j) { | 
					
						
							|  |  |  | 			case OLD_ARRAY_VERTEX: { | 
					
						
							|  |  |  | 				if (p_old_format & OLD_ARRAY_FLAG_USE_2D_VERTICES) { | 
					
						
							|  |  |  | 					if (p_old_format & OLD_ARRAY_COMPRESS_VERTEX) { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride]; | 
					
						
							|  |  |  | 							float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride]; | 
					
						
							|  |  |  | 							dst[0] = Math::half_to_float(src[0]); | 
					
						
							|  |  |  | 							dst[1] = Math::half_to_float(src[1]); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						src_offset += sizeof(uint16_t) * 2; | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride]; | 
					
						
							|  |  |  | 							float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride]; | 
					
						
							|  |  |  | 							dst[0] = src[0]; | 
					
						
							|  |  |  | 							dst[1] = src[1]; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						src_offset += sizeof(float) * 2; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					if (p_old_format & OLD_ARRAY_COMPRESS_VERTEX) { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride]; | 
					
						
							|  |  |  | 							float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride]; | 
					
						
							|  |  |  | 							dst[0] = Math::half_to_float(src[0]); | 
					
						
							|  |  |  | 							dst[1] = Math::half_to_float(src[1]); | 
					
						
							|  |  |  | 							dst[2] = Math::half_to_float(src[2]); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						src_offset += sizeof(uint16_t) * 4; //+pad
 | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride]; | 
					
						
							|  |  |  | 							float *dst = (float *)&dst_vertex_ptr[i * dst_vertex_stride]; | 
					
						
							|  |  |  | 							dst[0] = src[0]; | 
					
						
							|  |  |  | 							dst[1] = src[1]; | 
					
						
							|  |  |  | 							dst[2] = src[2]; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						src_offset += sizeof(float) * 3; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case OLD_ARRAY_NORMAL: { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 				if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { | 
					
						
							|  |  |  | 					if ((p_old_format & OLD_ARRAY_COMPRESS_NORMAL) && (p_old_format & OLD_ARRAY_FORMAT_TANGENT) && (p_old_format & OLD_ARRAY_COMPRESS_TANGENT)) { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							int16_t *dst = (int16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							dst[0] = (int16_t)CLAMP(src[0] / 127.0f * 32767, -32768, 32767); | 
					
						
							|  |  |  | 							dst[1] = (int16_t)CLAMP(src[1] / 127.0f * 32767, -32768, 32767); | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-11-10 22:55:01 +00:00
										 |  |  | 						src_offset += sizeof(int8_t) * 2; | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							int16_t *dst = (int16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							dst[0] = src[0]; | 
					
						
							|  |  |  | 							dst[1] = src[1]; | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						src_offset += sizeof(int16_t) * 2; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} else { // No Octahedral compression
 | 
					
						
							|  |  |  | 					if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							const Vector3 original_normal(src[0], src[1], src[2]); | 
					
						
							|  |  |  | 							Vector2 res = original_normal.octahedron_encode(); | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; | 
					
						
							|  |  |  | 							dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); | 
					
						
							|  |  |  | 							dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-11-10 22:55:01 +00:00
										 |  |  | 						src_offset += sizeof(uint8_t) * 4; // 1 byte padding
 | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							const Vector3 original_normal(src[0], src[1], src[2]); | 
					
						
							|  |  |  | 							Vector2 res = original_normal.octahedron_encode(); | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; | 
					
						
							|  |  |  | 							dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); | 
					
						
							|  |  |  | 							dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-11-10 22:55:01 +00:00
										 |  |  | 						src_offset += sizeof(float) * 3; | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case OLD_ARRAY_TANGENT: { | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 				if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 					if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { // int8 SNORM -> uint16 UNORM
 | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							dst[0] = (uint16_t)CLAMP((src[0] / 127.0f * .5f + .5f) * 65535, 0, 65535); | 
					
						
							|  |  |  | 							dst[1] = (uint16_t)CLAMP((src[1] / 127.0f * .5f + .5f) * 65535, 0, 65535); | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-11-10 22:55:01 +00:00
										 |  |  | 						src_offset += sizeof(uint8_t) * 2; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 					} else { // int16 SNORM -> uint16 UNORM
 | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							dst[0] = (uint16_t)CLAMP((src[0] / 32767.0f * .5f + .5f) * 65535, 0, 65535); | 
					
						
							|  |  |  | 							dst[1] = (uint16_t)CLAMP((src[1] / 32767.0f * .5f + .5f) * 65535, 0, 65535); | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 						src_offset += sizeof(uint16_t) * 2; | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 				} else { // No Octahedral compression
 | 
					
						
							|  |  |  | 					if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							const Vector3 original_tangent(src[0], src[1], src[2]); | 
					
						
							|  |  |  | 							Vector2 res = original_tangent.octahedron_tangent_encode(src[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; | 
					
						
							|  |  |  | 							dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); | 
					
						
							|  |  |  | 							dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-11-10 22:55:01 +00:00
										 |  |  | 						src_offset += sizeof(uint8_t) * 4; | 
					
						
							| 
									
										
										
										
											2022-01-08 04:03:57 -08:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 							const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							| 
									
										
										
										
											2022-02-22 18:10:09 -05:00
										 |  |  | 							const Vector3 original_tangent(src[0], src[1], src[2]); | 
					
						
							|  |  |  | 							Vector2 res = original_tangent.octahedron_tangent_encode(src[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; | 
					
						
							|  |  |  | 							dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); | 
					
						
							|  |  |  | 							dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-11-10 22:55:01 +00:00
										 |  |  | 						src_offset += sizeof(float) * 4; | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case OLD_ARRAY_COLOR: { | 
					
						
							|  |  |  | 				if (p_old_format & OLD_ARRAY_COMPRESS_COLOR) { | 
					
						
							|  |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const uint32_t *src = (const uint32_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						uint32_t *dst = (uint32_t *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_COLOR]]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 						*dst = *src; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					src_offset += sizeof(uint32_t); | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						uint8_t *dst = (uint8_t *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_COLOR]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						dst[0] = uint8_t(CLAMP(src[0] * 255.0, 0.0, 255.0)); | 
					
						
							|  |  |  | 						dst[1] = uint8_t(CLAMP(src[1] * 255.0, 0.0, 255.0)); | 
					
						
							|  |  |  | 						dst[2] = uint8_t(CLAMP(src[2] * 255.0, 0.0, 255.0)); | 
					
						
							|  |  |  | 						dst[3] = uint8_t(CLAMP(src[3] * 255.0, 0.0, 255.0)); | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					src_offset += sizeof(float) * 4; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case OLD_ARRAY_TEX_UV: { | 
					
						
							|  |  |  | 				if (p_old_format & OLD_ARRAY_COMPRESS_TEX_UV) { | 
					
						
							|  |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						dst[0] = Math::half_to_float(src[0]); | 
					
						
							|  |  |  | 						dst[1] = Math::half_to_float(src[1]); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					src_offset += sizeof(uint16_t) * 2; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV]]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 						dst[0] = src[0]; | 
					
						
							|  |  |  | 						dst[1] = src[1]; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					src_offset += sizeof(float) * 2; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case OLD_ARRAY_TEX_UV2: { | 
					
						
							|  |  |  | 				if (p_old_format & OLD_ARRAY_COMPRESS_TEX_UV2) { | 
					
						
							|  |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV2]]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 						dst[0] = Math::half_to_float(src[0]); | 
					
						
							|  |  |  | 						dst[1] = Math::half_to_float(src[1]); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					src_offset += sizeof(uint16_t) * 2; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						float *dst = (float *)&dst_attribute_ptr[i * dst_attribute_stride + dst_offsets[Mesh::ARRAY_TEX_UV2]]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 						dst[0] = src[0]; | 
					
						
							|  |  |  | 						dst[1] = src[1]; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					src_offset += sizeof(float) * 2; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case OLD_ARRAY_BONES: { | 
					
						
							|  |  |  | 				if (p_old_format & OLD_ARRAY_FLAG_USE_16_BIT_BONES) { | 
					
						
							|  |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_BONES]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						dst[0] = src[0]; | 
					
						
							|  |  |  | 						dst[1] = src[1]; | 
					
						
							|  |  |  | 						dst[2] = src[2]; | 
					
						
							|  |  |  | 						dst[3] = src[3]; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					src_offset += sizeof(uint16_t) * 4; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const uint8_t *src = (const uint8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_BONES]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						dst[0] = src[0]; | 
					
						
							|  |  |  | 						dst[1] = src[1]; | 
					
						
							|  |  |  | 						dst[2] = src[2]; | 
					
						
							|  |  |  | 						dst[3] = src[3]; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					src_offset += sizeof(uint8_t) * 4; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case OLD_ARRAY_WEIGHTS: { | 
					
						
							|  |  |  | 				if (p_old_format & OLD_ARRAY_COMPRESS_WEIGHTS) { | 
					
						
							|  |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const uint16_t *src = (const uint16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_WEIGHTS]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						dst[0] = src[0]; | 
					
						
							|  |  |  | 						dst[1] = src[1]; | 
					
						
							|  |  |  | 						dst[2] = src[2]; | 
					
						
							|  |  |  | 						dst[3] = src[3]; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					src_offset += sizeof(uint16_t) * 4; | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					for (uint32_t i = 0; i < p_elements; i++) { | 
					
						
							|  |  |  | 						const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; | 
					
						
							|  |  |  | 						uint16_t *dst = (uint16_t *)&dst_skin_ptr[i * dst_skin_stride + dst_offsets[Mesh::ARRAY_WEIGHTS]]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						dst[0] = uint16_t(CLAMP(src[0] * 65535.0, 0, 65535.0)); | 
					
						
							|  |  |  | 						dst[1] = uint16_t(CLAMP(src[1] * 65535.0, 0, 65535.0)); | 
					
						
							|  |  |  | 						dst[2] = uint16_t(CLAMP(src[2] * 65535.0, 0, 65535.0)); | 
					
						
							|  |  |  | 						dst[3] = uint16_t(CLAMP(src[3] * 65535.0, 0, 65535.0)); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					src_offset += sizeof(float) * 4; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			default: { | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-12-04 15:54:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { | 
					
						
							|  |  |  | 	String sname = p_name; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	if (sname.begins_with("surface_")) { | 
					
						
							|  |  |  | 		int sl = sname.find("/"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (sl == -1) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		int idx = sname.substr(8, sl - 8).to_int() - 1; | 
					
						
							|  |  |  | 		String what = sname.get_slicec('/', 1); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (what == "material") { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			surface_set_material(idx, p_value); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else if (what == "name") { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			surface_set_name(idx, p_value); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | #ifndef DISABLE_DEPRECATED
 | 
					
						
							| 
									
										
										
										
											2020-02-13 11:37:37 +01:00
										 |  |  | 	// Kept for compatibility from 3.x to 4.0.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!sname.begins_with("surfaces")) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-18 03:43:57 +00:00
										 |  |  | 	WARN_DEPRECATED_MSG(vformat( | 
					
						
							|  |  |  | 			"Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene. Path: \"%s\"", | 
					
						
							|  |  |  | 			get_path())); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	int idx = sname.get_slicec('/', 1).to_int(); | 
					
						
							|  |  |  | 	String what = sname.get_slicec('/', 2); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	if (idx == surfaces.size()) { | 
					
						
							|  |  |  | 		//create
 | 
					
						
							|  |  |  | 		Dictionary d = p_value; | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(!d.has("primitive"), false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		if (d.has("arrays")) { | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 			//oldest format (2.x)
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			ERR_FAIL_COND_V(!d.has("morph_arrays"), false); | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			Array morph_arrays = d["morph_arrays"]; | 
					
						
							|  |  |  | 			for (int i = 0; i < morph_arrays.size(); i++) { | 
					
						
							|  |  |  | 				morph_arrays[i] = _convert_old_array(morph_arrays[i]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			add_surface_from_arrays(_old_primitives[int(d["primitive"])], _convert_old_array(d["arrays"]), morph_arrays); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		} else if (d.has("array_data")) { | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 			//print_line("array data (old style");
 | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 			//older format (3.x)
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			Vector<uint8_t> array_data = d["array_data"]; | 
					
						
							|  |  |  | 			Vector<uint8_t> array_index_data; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (d.has("array_index_data")) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 				array_index_data = d["array_index_data"]; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			ERR_FAIL_COND_V(!d.has("format"), false); | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			uint32_t old_format = d["format"]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			uint32_t primitive = d["primitive"]; | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			primitive = _old_primitives[primitive]; //compatibility
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			ERR_FAIL_COND_V(!d.has("vertex_count"), false); | 
					
						
							|  |  |  | 			int vertex_count = d["vertex_count"]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 			uint32_t new_format = ARRAY_FORMAT_VERTEX; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FORMAT_NORMAL) { | 
					
						
							|  |  |  | 				new_format |= ARRAY_FORMAT_NORMAL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FORMAT_TANGENT) { | 
					
						
							|  |  |  | 				new_format |= ARRAY_FORMAT_TANGENT; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FORMAT_COLOR) { | 
					
						
							|  |  |  | 				new_format |= ARRAY_FORMAT_COLOR; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FORMAT_TEX_UV) { | 
					
						
							|  |  |  | 				new_format |= ARRAY_FORMAT_TEX_UV; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FORMAT_TEX_UV2) { | 
					
						
							|  |  |  | 				new_format |= ARRAY_FORMAT_TEX_UV2; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FORMAT_BONES) { | 
					
						
							|  |  |  | 				new_format |= ARRAY_FORMAT_BONES; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FORMAT_WEIGHTS) { | 
					
						
							|  |  |  | 				new_format |= ARRAY_FORMAT_WEIGHTS; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FORMAT_INDEX) { | 
					
						
							|  |  |  | 				new_format |= ARRAY_FORMAT_INDEX; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (old_format & OLD_ARRAY_FLAG_USE_2D_VERTICES) { | 
					
						
							|  |  |  | 				new_format |= OLD_ARRAY_FLAG_USE_2D_VERTICES; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Vector<uint8_t> vertex_array; | 
					
						
							|  |  |  | 			Vector<uint8_t> attribute_array; | 
					
						
							|  |  |  | 			Vector<uint8_t> skin_array; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			_fix_array_compatibility(array_data, old_format, new_format, vertex_count, vertex_array, attribute_array, skin_array); | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			int index_count = 0; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (d.has("index_count")) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 				index_count = d["index_count"]; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			Vector<uint8_t> blend_shapes_new; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			if (d.has("blend_shape_data")) { | 
					
						
							|  |  |  | 				Array blend_shape_data = d["blend_shape_data"]; | 
					
						
							|  |  |  | 				for (int i = 0; i < blend_shape_data.size(); i++) { | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					Vector<uint8_t> blend_vertex_array; | 
					
						
							|  |  |  | 					Vector<uint8_t> blend_attribute_array; | 
					
						
							|  |  |  | 					Vector<uint8_t> blend_skin_array; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 					Vector<uint8_t> shape = blend_shape_data[i]; | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 					_fix_array_compatibility(shape, old_format, new_format, vertex_count, blend_vertex_array, blend_attribute_array, blend_skin_array); | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 					blend_shapes_new.append_array(blend_vertex_array); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 			//clear unused flags
 | 
					
						
							| 
									
										
										
										
											2021-12-05 23:21:27 +01:00
										 |  |  | 			print_verbose("Mesh format pre-conversion: " + itos(old_format)); | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-05 23:21:27 +01:00
										 |  |  | 			print_verbose("Mesh format post-conversion: " + itos(new_format)); | 
					
						
							| 
									
										
										
										
											2019-09-14 00:37:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			ERR_FAIL_COND_V(!d.has("aabb"), false); | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			AABB aabb_new = d["aabb"]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | 			Vector<AABB> bone_aabb; | 
					
						
							| 
									
										
										
										
											2017-11-11 21:48:00 -06:00
										 |  |  | 			if (d.has("skeleton_aabb")) { | 
					
						
							|  |  |  | 				Array baabb = d["skeleton_aabb"]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 				bone_aabb.resize(baabb.size()); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 				for (int i = 0; i < baabb.size(); i++) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 					bone_aabb.write[i] = baabb[i]; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			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); | 
					
						
							| 
									
										
										
										
											2021-07-02 12:33:24 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			ERR_FAIL_V(false); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		if (d.has("material")) { | 
					
						
							|  |  |  | 			surface_set_material(idx, d["material"]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (d.has("name")) { | 
					
						
							|  |  |  | 			surface_set_name(idx, d["name"]); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-02-13 11:37:37 +01:00
										 |  |  | #endif // DISABLE_DEPRECATED
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2014-05-04 22:50:23 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | void ArrayMesh::_set_blend_shape_names(const PackedStringArray &p_names) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(surfaces.size() > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	blend_shapes.resize(p_names.size()); | 
					
						
							|  |  |  | 	for (int i = 0; i < p_names.size(); i++) { | 
					
						
							|  |  |  | 		blend_shapes.write[i] = p_names[i]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mesh.is_valid()) { | 
					
						
							|  |  |  | 		RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PackedStringArray ArrayMesh::_get_blend_shape_names() const { | 
					
						
							|  |  |  | 	PackedStringArray sarr; | 
					
						
							|  |  |  | 	sarr.resize(blend_shapes.size()); | 
					
						
							|  |  |  | 	for (int i = 0; i < blend_shapes.size(); i++) { | 
					
						
							|  |  |  | 		sarr.write[i] = blend_shapes[i]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return sarr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | Array ArrayMesh::_get_surfaces() const { | 
					
						
							|  |  |  | 	if (mesh.is_null()) { | 
					
						
							|  |  |  | 		return Array(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Array ret; | 
					
						
							|  |  |  | 	for (int i = 0; i < surfaces.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		RenderingServer::SurfaceData surface = RS::get_singleton()->mesh_get_surface(mesh, i); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		Dictionary data; | 
					
						
							|  |  |  | 		data["format"] = surface.format; | 
					
						
							|  |  |  | 		data["primitive"] = surface.primitive; | 
					
						
							|  |  |  | 		data["vertex_data"] = surface.vertex_data; | 
					
						
							|  |  |  | 		data["vertex_count"] = surface.vertex_count; | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 		if (surface.skin_data.size()) { | 
					
						
							|  |  |  | 			data["skin_data"] = surface.skin_data; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (surface.attribute_data.size()) { | 
					
						
							|  |  |  | 			data["attribute_data"] = surface.attribute_data; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		data["aabb"] = surface.aabb; | 
					
						
							|  |  |  | 		if (surface.index_count) { | 
					
						
							|  |  |  | 			data["index_data"] = surface.index_data; | 
					
						
							|  |  |  | 			data["index_count"] = surface.index_count; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Array lods; | 
					
						
							|  |  |  | 		for (int j = 0; j < surface.lods.size(); j++) { | 
					
						
							|  |  |  | 			lods.push_back(surface.lods[j].edge_length); | 
					
						
							|  |  |  | 			lods.push_back(surface.lods[j].index_data); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (lods.size()) { | 
					
						
							|  |  |  | 			data["lods"] = lods; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Array bone_aabbs; | 
					
						
							|  |  |  | 		for (int j = 0; j < surface.bone_aabbs.size(); j++) { | 
					
						
							|  |  |  | 			bone_aabbs.push_back(surface.bone_aabbs[j]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (bone_aabbs.size()) { | 
					
						
							|  |  |  | 			data["bone_aabbs"] = bone_aabbs; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 		if (surface.blend_shape_data.size()) { | 
					
						
							|  |  |  | 			data["blend_shapes"] = surface.blend_shape_data; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (surfaces[i].material.is_valid()) { | 
					
						
							|  |  |  | 			data["material"] = surfaces[i].material; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 03:42:46 -06:00
										 |  |  | 		if (!surfaces[i].name.is_empty()) { | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 			data["name"] = surfaces[i].name; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (surfaces[i].is_2d) { | 
					
						
							|  |  |  | 			data["2d"] = true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ret.push_back(data); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-03 17:39:08 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ArrayMesh::_create_if_empty() const { | 
					
						
							|  |  |  | 	if (!mesh.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		mesh = RS::get_singleton()->mesh_create(); | 
					
						
							|  |  |  | 		RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode); | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 		RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ArrayMesh::_set_surfaces(const Array &p_surfaces) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	Vector<RS::SurfaceData> surface_data; | 
					
						
							| 
									
										
										
										
											2020-03-17 07:33:00 +01:00
										 |  |  | 	Vector<Ref<Material>> surface_materials; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	Vector<String> surface_names; | 
					
						
							|  |  |  | 	Vector<bool> surface_2d; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < p_surfaces.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		RS::SurfaceData surface; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		Dictionary d = p_surfaces[i]; | 
					
						
							|  |  |  | 		ERR_FAIL_COND(!d.has("format")); | 
					
						
							|  |  |  | 		ERR_FAIL_COND(!d.has("primitive")); | 
					
						
							|  |  |  | 		ERR_FAIL_COND(!d.has("vertex_data")); | 
					
						
							|  |  |  | 		ERR_FAIL_COND(!d.has("vertex_count")); | 
					
						
							|  |  |  | 		ERR_FAIL_COND(!d.has("aabb")); | 
					
						
							|  |  |  | 		surface.format = d["format"]; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		surface.primitive = RS::PrimitiveType(int(d["primitive"])); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		surface.vertex_data = d["vertex_data"]; | 
					
						
							|  |  |  | 		surface.vertex_count = d["vertex_count"]; | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 		if (d.has("attribute_data")) { | 
					
						
							|  |  |  | 			surface.attribute_data = d["attribute_data"]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (d.has("skin_data")) { | 
					
						
							|  |  |  | 			surface.skin_data = d["skin_data"]; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		surface.aabb = d["aabb"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (d.has("index_data")) { | 
					
						
							|  |  |  | 			ERR_FAIL_COND(!d.has("index_count")); | 
					
						
							|  |  |  | 			surface.index_data = d["index_data"]; | 
					
						
							|  |  |  | 			surface.index_count = d["index_count"]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (d.has("lods")) { | 
					
						
							|  |  |  | 			Array lods = d["lods"]; | 
					
						
							|  |  |  | 			ERR_FAIL_COND(lods.size() & 1); //must be even
 | 
					
						
							|  |  |  | 			for (int j = 0; j < lods.size(); j += 2) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 				RS::SurfaceData::LOD lod; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 				lod.edge_length = lods[j + 0]; | 
					
						
							|  |  |  | 				lod.index_data = lods[j + 1]; | 
					
						
							|  |  |  | 				surface.lods.push_back(lod); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (d.has("bone_aabbs")) { | 
					
						
							|  |  |  | 			Array bone_aabbs = d["bone_aabbs"]; | 
					
						
							|  |  |  | 			for (int j = 0; j < bone_aabbs.size(); j++) { | 
					
						
							|  |  |  | 				surface.bone_aabbs.push_back(bone_aabbs[j]); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 		if (d.has("blend_shapes")) { | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 			surface.blend_shape_data = d["blend_shapes"]; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Ref<Material> material; | 
					
						
							|  |  |  | 		if (d.has("material")) { | 
					
						
							|  |  |  | 			material = d["material"]; | 
					
						
							|  |  |  | 			if (material.is_valid()) { | 
					
						
							|  |  |  | 				surface.material = material->get_rid(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 		String surf_name; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		if (d.has("name")) { | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			surf_name = d["name"]; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bool _2d = false; | 
					
						
							|  |  |  | 		if (d.has("2d")) { | 
					
						
							|  |  |  | 			_2d = d["2d"]; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		surface_data.push_back(surface); | 
					
						
							|  |  |  | 		surface_materials.push_back(material); | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 		surface_names.push_back(surf_name); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		surface_2d.push_back(_2d); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mesh.is_valid()) { | 
					
						
							|  |  |  | 		//if mesh exists, it needs to be updated
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		RS::get_singleton()->mesh_clear(mesh); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		for (int i = 0; i < surface_data.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 			RS::get_singleton()->mesh_add_surface(mesh, surface_data[i]); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		// if mesh does not exist (first time this is loaded, most likely),
 | 
					
						
							|  |  |  | 		// we can create it with a single call, which is a lot more efficient and thread friendly
 | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 		mesh = RS::get_singleton()->mesh_create_from_surfaces(surface_data, blend_shapes.size()); | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	surfaces.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	aabb = AABB(); | 
					
						
							|  |  |  | 	for (int i = 0; i < surface_data.size(); i++) { | 
					
						
							|  |  |  | 		Surface s; | 
					
						
							|  |  |  | 		s.aabb = surface_data[i].aabb; | 
					
						
							|  |  |  | 		if (i == 0) { | 
					
						
							|  |  |  | 			aabb = s.aabb; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			aabb.merge_with(s.aabb); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		s.material = surface_materials[i]; | 
					
						
							|  |  |  | 		s.is_2d = surface_2d[i]; | 
					
						
							|  |  |  | 		s.name = surface_names[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		s.format = surface_data[i].format; | 
					
						
							|  |  |  | 		s.primitive = PrimitiveType(surface_data[i].primitive); | 
					
						
							|  |  |  | 		s.array_length = surface_data[i].vertex_count; | 
					
						
							|  |  |  | 		s.index_array_length = surface_data[i].index_count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		surfaces.push_back(s); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (_is_generated()) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	String sname = p_name; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	if (sname.begins_with("surface_")) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		int sl = sname.find("/"); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (sl == -1) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		int idx = sname.substr(8, sl - 8).to_int() - 1; | 
					
						
							|  |  |  | 		String what = sname.get_slicec('/', 1); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (what == "material") { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			r_ret = surface_get_material(idx); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else if (what == "name") { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			r_ret = surface_get_name(idx); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-11 14:18:45 -03:00
										 |  |  | void ArrayMesh::reset_state() { | 
					
						
							|  |  |  | 	clear_surfaces(); | 
					
						
							|  |  |  | 	clear_blend_shapes(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	aabb = AABB(); | 
					
						
							|  |  |  | 	blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE; | 
					
						
							|  |  |  | 	custom_aabb = AABB(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (_is_generated()) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	for (int i = 0; i < surfaces.size(); i++) { | 
					
						
							|  |  |  | 		p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); | 
					
						
							| 
									
										
										
										
											2017-06-22 09:17:06 -03:00
										 |  |  | 		if (surfaces[i].is_2d) { | 
					
						
							| 
									
										
										
										
											2021-07-04 17:49:36 +02:00
										 |  |  | 			p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial,ShaderMaterial", PROPERTY_USAGE_EDITOR)); | 
					
						
							| 
									
										
										
										
											2017-06-22 09:17:06 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2021-07-04 17:49:36 +02:00
										 |  |  | 			p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_EDITOR)); | 
					
						
							| 
									
										
										
										
											2017-06-22 09:17:06 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | void ArrayMesh::_recompute_aabb() { | 
					
						
							|  |  |  | 	// regenerate AABB
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | 	aabb = AABB(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	for (int i = 0; i < surfaces.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (i == 0) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			aabb = surfaces[i].aabb; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			aabb.merge_with(surfaces[i].aabb); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-10-10 13:04:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // TODO: Need to add binding to add_surface using future MeshSurfaceData object.
 | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | void ArrayMesh::add_surface(uint32_t 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) { | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	_create_if_empty(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	Surface s; | 
					
						
							|  |  |  | 	s.aabb = p_aabb; | 
					
						
							| 
									
										
										
										
											2017-06-22 09:17:06 -03:00
										 |  |  | 	s.is_2d = p_format & ARRAY_FLAG_USE_2D_VERTICES; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	s.primitive = p_primitive; | 
					
						
							|  |  |  | 	s.array_length = p_vertex_count; | 
					
						
							|  |  |  | 	s.index_array_length = p_index_count; | 
					
						
							|  |  |  | 	s.format = p_format; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	surfaces.push_back(s); | 
					
						
							| 
									
										
										
										
											2017-06-09 00:23:50 -03:00
										 |  |  | 	_recompute_aabb(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	RS::SurfaceData sd; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	sd.format = p_format; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	sd.primitive = RS::PrimitiveType(p_primitive); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	sd.aabb = p_aabb; | 
					
						
							|  |  |  | 	sd.vertex_count = p_vertex_count; | 
					
						
							|  |  |  | 	sd.vertex_data = p_array; | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	sd.attribute_data = p_attribute_array; | 
					
						
							|  |  |  | 	sd.skin_data = p_skin_array; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	sd.index_count = p_index_count; | 
					
						
							|  |  |  | 	sd.index_data = p_index_array; | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	sd.blend_shape_data = p_blend_shape_data; | 
					
						
							|  |  |  | 	sd.bone_aabbs = p_bone_aabbs; | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	sd.lods = p_lods; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	RenderingServer::get_singleton()->mesh_add_surface(mesh, sd); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	clear_cache(); | 
					
						
							| 
									
										
										
										
											2021-02-10 17:18:45 -03:00
										 |  |  | 	notify_property_list_changed(); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	emit_changed(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-02 17:38:40 +03:00
										 |  |  | void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) { | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	RS::SurfaceData surface; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	ERR_FAIL_COND(err != OK); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-04 15:54:48 +01:00
										 |  |  | 	/* Debug code.
 | 
					
						
							|  |  |  | 	print_line("format: " + itos(surface.format)); | 
					
						
							| 
									
										
										
										
											2019-10-03 17:39:08 -03:00
										 |  |  | 	print_line("aabb: " + surface.aabb); | 
					
						
							|  |  |  | 	print_line("array size: " + itos(surface.vertex_data.size())); | 
					
						
							|  |  |  | 	print_line("vertex count: " + itos(surface.vertex_count)); | 
					
						
							|  |  |  | 	print_line("index size: " + itos(surface.index_data.size())); | 
					
						
							|  |  |  | 	print_line("index count: " + itos(surface.index_count)); | 
					
						
							|  |  |  | 	print_line("primitive: " + itos(surface.primitive)); | 
					
						
							| 
									
										
										
										
											2020-12-04 15:54:48 +01:00
										 |  |  | 	*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | Array ArrayMesh::surface_get_arrays(int p_surface) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array()); | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	return RenderingServer::get_singleton()->mesh_surface_get_arrays(mesh, p_surface); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 20:35:08 +02:00
										 |  |  | TypedArray<Array> ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_surface, surfaces.size(), TypedArray<Array>()); | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	return RenderingServer::get_singleton()->mesh_surface_get_blend_shape_arrays(mesh, p_surface); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | Dictionary ArrayMesh::surface_get_lods(int p_surface) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Dictionary()); | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	return RenderingServer::get_singleton()->mesh_surface_get_lods(mesh, p_surface); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-14 01:01:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | int ArrayMesh::get_surface_count() const { | 
					
						
							|  |  |  | 	return surfaces.size(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-14 01:01:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | void ArrayMesh::add_blend_shape(const StringName &p_name) { | 
					
						
							| 
									
										
										
										
											2019-08-08 22:11:48 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(surfaces.size(), "Can't add a shape key count if surfaces are already created."); | 
					
						
							| 
									
										
										
										
											2014-10-14 01:01:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	StringName shape_name = p_name; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	if (blend_shapes.has(shape_name)) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		int count = 2; | 
					
						
							|  |  |  | 		do { | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			shape_name = String(p_name) + " " + itos(count); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 			count++; | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 		} while (blend_shapes.has(shape_name)); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	blend_shapes.push_back(shape_name); | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (mesh.is_valid()) { | 
					
						
							|  |  |  | 		RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | int ArrayMesh::get_blend_shape_count() const { | 
					
						
							|  |  |  | 	return blend_shapes.size(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | StringName ArrayMesh::get_blend_shape_name(int p_index) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_index, blend_shapes.size(), StringName()); | 
					
						
							|  |  |  | 	return blend_shapes[p_index]; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 07:53:18 -07:00
										 |  |  | void ArrayMesh::set_blend_shape_name(int p_index, const StringName &p_name) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX(p_index, blend_shapes.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	StringName shape_name = p_name; | 
					
						
							|  |  |  | 	int found = blend_shapes.find(shape_name); | 
					
						
							| 
									
										
										
										
											2020-10-15 07:53:18 -07:00
										 |  |  | 	if (found != -1 && found != p_index) { | 
					
						
							|  |  |  | 		int count = 2; | 
					
						
							|  |  |  | 		do { | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 			shape_name = String(p_name) + " " + itos(count); | 
					
						
							| 
									
										
										
										
											2020-10-15 07:53:18 -07:00
										 |  |  | 			count++; | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 		} while (blend_shapes.find(shape_name) != -1); | 
					
						
							| 
									
										
										
										
											2020-10-15 07:53:18 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	blend_shapes.write[p_index] = shape_name; | 
					
						
							| 
									
										
										
										
											2020-10-15 07:53:18 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | void ArrayMesh::clear_blend_shapes() { | 
					
						
							| 
									
										
										
										
											2019-08-08 22:11:48 +02:00
										 |  |  | 	ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	blend_shapes.clear(); | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (mesh.is_valid()) { | 
					
						
							|  |  |  | 		RS::get_singleton()->mesh_set_blend_shape_count(mesh, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) { | 
					
						
							|  |  |  | 	blend_shape_mode = p_mode; | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 	if (mesh.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)p_mode); | 
					
						
							| 
									
										
										
										
											2019-09-23 16:01:05 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const { | 
					
						
							|  |  |  | 	return blend_shape_mode; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | int ArrayMesh::surface_get_array_len(int p_idx) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	return surfaces[p_idx].array_length; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | int ArrayMesh::surface_get_array_index_len(int p_idx) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	return surfaces[p_idx].index_array_length; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | uint32_t ArrayMesh::surface_get_format(int p_idx) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, surfaces.size(), 0); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	return surfaces[p_idx].format; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | ArrayMesh::PrimitiveType ArrayMesh::surface_get_primitive_type(int p_idx) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, surfaces.size(), PRIMITIVE_LINES); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	return surfaces[p_idx].primitive; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX(p_idx, surfaces.size()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (surfaces[p_idx].material == p_material) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	surfaces.write[p_idx].material = p_material; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	RenderingServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid()); | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	emit_changed(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-28 10:34:31 +10:00
										 |  |  | int ArrayMesh::surface_find_by_name(const String &p_name) const { | 
					
						
							|  |  |  | 	for (int i = 0; i < surfaces.size(); i++) { | 
					
						
							|  |  |  | 		if (surfaces[i].name == p_name) { | 
					
						
							|  |  |  | 			return i; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | void ArrayMesh::surface_set_name(int p_idx, const String &p_name) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX(p_idx, surfaces.size()); | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	surfaces.write[p_idx].name = p_name; | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	emit_changed(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | String ArrayMesh::surface_get_name(int p_idx) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, surfaces.size(), String()); | 
					
						
							|  |  |  | 	return surfaces[p_idx].name; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-29 22:55:11 -03:00
										 |  |  | void ArrayMesh::surface_update_vertex_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) { | 
					
						
							| 
									
										
										
										
											2017-11-14 17:25:42 -03:00
										 |  |  | 	ERR_FAIL_INDEX(p_surface, surfaces.size()); | 
					
						
							| 
									
										
										
										
											2021-06-29 22:55:11 -03:00
										 |  |  | 	RS::get_singleton()->mesh_surface_update_vertex_region(mesh, p_surface, p_offset, p_data); | 
					
						
							|  |  |  | 	emit_changed(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ArrayMesh::surface_update_attribute_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX(p_surface, surfaces.size()); | 
					
						
							|  |  |  | 	RS::get_singleton()->mesh_surface_update_attribute_region(mesh, p_surface, p_offset, p_data); | 
					
						
							|  |  |  | 	emit_changed(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ArrayMesh::surface_update_skin_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX(p_surface, surfaces.size()); | 
					
						
							|  |  |  | 	RS::get_singleton()->mesh_surface_update_skin_region(mesh, p_surface, p_offset, p_data); | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	emit_changed(); | 
					
						
							| 
									
										
										
										
											2017-11-14 17:25:42 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	ERR_FAIL_INDEX(p_idx, surfaces.size()); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	surfaces.write[p_idx].aabb = p_aabb; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	// set custom aabb too?
 | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	emit_changed(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | Ref<Material> ArrayMesh::surface_get_material(int p_idx) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_idx, surfaces.size(), Ref<Material>()); | 
					
						
							|  |  |  | 	return surfaces[p_idx].material; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | RID ArrayMesh::get_rid() const { | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	_create_if_empty(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	return mesh; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | AABB ArrayMesh::get_aabb() const { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	return aabb; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | void ArrayMesh::clear_surfaces() { | 
					
						
							|  |  |  | 	if (!mesh.is_valid()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	RS::get_singleton()->mesh_clear(mesh); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	surfaces.clear(); | 
					
						
							|  |  |  | 	aabb = AABB(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | void ArrayMesh::set_custom_aabb(const AABB &p_custom) { | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	_create_if_empty(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	custom_aabb = p_custom; | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	RS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb); | 
					
						
							| 
									
										
										
										
											2018-04-27 21:52:15 -03:00
										 |  |  | 	emit_changed(); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | AABB ArrayMesh::get_custom_aabb() const { | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	return custom_aabb; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-23 09:34:26 +00:00
										 |  |  | void ArrayMesh::regen_normal_maps() { | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	if (surfaces.size() == 0) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-03-17 07:33:00 +01:00
										 |  |  | 	Vector<Ref<SurfaceTool>> surfs; | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	for (int i = 0; i < get_surface_count(); i++) { | 
					
						
							|  |  |  | 		Ref<SurfaceTool> st = memnew(SurfaceTool); | 
					
						
							|  |  |  | 		st->create_from(Ref<ArrayMesh>(this), i); | 
					
						
							|  |  |  | 		surfs.push_back(st); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	clear_surfaces(); | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	for (int i = 0; i < surfs.size(); i++) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		surfs.write[i]->generate_tangents(); | 
					
						
							|  |  |  | 		surfs.write[i]->commit(Ref<ArrayMesh>(this)); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | //dirty hack
 | 
					
						
							| 
									
										
										
										
											2021-10-12 14:30:55 +07:00
										 |  |  | bool (*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; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct ArrayMeshLightmapSurface { | 
					
						
							|  |  |  | 	Ref<Material> material; | 
					
						
							| 
									
										
										
										
											2020-12-12 09:06:59 -03:00
										 |  |  | 	LocalVector<SurfaceTool::Vertex> vertices; | 
					
						
							| 
									
										
										
										
											2021-02-09 18:24:36 +01:00
										 |  |  | 	Mesh::PrimitiveType primitive = Mesh::PrimitiveType::PRIMITIVE_MAX; | 
					
						
							|  |  |  | 	uint32_t format = 0; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 01:08:21 -04:00
										 |  |  | Error ArrayMesh::lightmap_unwrap(const Transform3D &p_base_transform, float p_texel_size) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	Vector<uint8_t> null_cache; | 
					
						
							|  |  |  | 	return lightmap_unwrap_cached(p_base_transform, p_texel_size, null_cache, null_cache, false); | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 01:08:21 -04:00
										 |  |  | Error 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-12-09 14:11:26 -03:00
										 |  |  | 	ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED); | 
					
						
							| 
									
										
										
										
											2019-08-08 22:11:48 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes."); | 
					
						
							| 
									
										
										
										
											2022-02-24 13:00:51 +01:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(p_texel_size <= 0.0f, ERR_PARAMETER_RANGE_ERROR, "Texel size must be greater than 0."); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	LocalVector<float> vertices; | 
					
						
							|  |  |  | 	LocalVector<float> normals; | 
					
						
							|  |  |  | 	LocalVector<int> indices; | 
					
						
							|  |  |  | 	LocalVector<float> uv; | 
					
						
							|  |  |  | 	LocalVector<Pair<int, int>> uv_indices; | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Vector<ArrayMeshLightmapSurface> lightmap_surfaces; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Keep only the scale
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	Basis basis = p_base_transform.get_basis(); | 
					
						
							| 
									
										
										
										
											2022-05-03 07:50:35 -05:00
										 |  |  | 	Vector3 scale = Vector3(basis.get_column(0).length(), basis.get_column(1).length(), basis.get_column(2).length()); | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 01:08:21 -04:00
										 |  |  | 	Transform3D transform; | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	transform.scale(scale); | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Basis normal_basis = transform.basis.inverse().transposed(); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < get_surface_count(); i++) { | 
					
						
							|  |  |  | 		ArrayMeshLightmapSurface s; | 
					
						
							|  |  |  | 		s.primitive = surface_get_primitive_type(i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-08 22:11:48 +02:00
										 |  |  | 		ERR_FAIL_COND_V_MSG(s.primitive != Mesh::PRIMITIVE_TRIANGLES, ERR_UNAVAILABLE, "Only triangles are supported for lightmap unwrap."); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		s.format = surface_get_format(i); | 
					
						
							| 
									
										
										
										
											2019-08-08 22:11:48 +02:00
										 |  |  | 		ERR_FAIL_COND_V_MSG(!(s.format & ARRAY_FORMAT_NORMAL), ERR_UNAVAILABLE, "Normals are required for lightmap unwrap."); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Array arrays = surface_get_arrays(i); | 
					
						
							|  |  |  | 		s.material = surface_get_material(i); | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 		SurfaceTool::create_vertex_array_from_triangle_arrays(arrays, s.vertices, &s.format); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 		PackedVector3Array rvertices = arrays[Mesh::ARRAY_VERTEX]; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		int vc = rvertices.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 		PackedVector3Array rnormals = arrays[Mesh::ARRAY_NORMAL]; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		int vertex_ofs = vertices.size() / 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		vertices.resize((vertex_ofs + vc) * 3); | 
					
						
							|  |  |  | 		normals.resize((vertex_ofs + vc) * 3); | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 		uv_indices.resize(vertex_ofs + vc); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for (int j = 0; j < vc; j++) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 			Vector3 v = transform.xform(rvertices[j]); | 
					
						
							|  |  |  | 			Vector3 n = normal_basis.xform(rnormals[j]).normalized(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			vertices[(j + vertex_ofs) * 3 + 0] = v.x; | 
					
						
							|  |  |  | 			vertices[(j + vertex_ofs) * 3 + 1] = v.y; | 
					
						
							|  |  |  | 			vertices[(j + vertex_ofs) * 3 + 2] = v.z; | 
					
						
							|  |  |  | 			normals[(j + vertex_ofs) * 3 + 0] = n.x; | 
					
						
							|  |  |  | 			normals[(j + vertex_ofs) * 3 + 1] = n.y; | 
					
						
							|  |  |  | 			normals[(j + vertex_ofs) * 3 + 2] = n.z; | 
					
						
							|  |  |  | 			uv_indices[j + vertex_ofs] = Pair<int, int>(i, j); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 		PackedInt32Array rindices = arrays[Mesh::ARRAY_INDEX]; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		int ic = rindices.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 		float eps = 1.19209290e-7F; // Taken from xatlas.h
 | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		if (ic == 0) { | 
					
						
							|  |  |  | 			for (int j = 0; j < vc / 3; j++) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 				Vector3 p0 = transform.xform(rvertices[j * 3 + 0]); | 
					
						
							|  |  |  | 				Vector3 p1 = transform.xform(rvertices[j * 3 + 1]); | 
					
						
							|  |  |  | 				Vector3 p2 = transform.xform(rvertices[j * 3 + 2]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ((p0 - p1).length_squared() < eps || (p1 - p2).length_squared() < eps || (p2 - p0).length_squared() < eps) { | 
					
						
							| 
									
										
										
										
											2017-12-14 08:59:46 -03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-12-14 08:59:46 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				indices.push_back(vertex_ofs + j * 3 + 0); | 
					
						
							|  |  |  | 				indices.push_back(vertex_ofs + j * 3 + 1); | 
					
						
							|  |  |  | 				indices.push_back(vertex_ofs + j * 3 + 2); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			for (int j = 0; j < ic / 3; j++) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 				Vector3 p0 = transform.xform(rvertices[rindices[j * 3 + 0]]); | 
					
						
							|  |  |  | 				Vector3 p1 = transform.xform(rvertices[rindices[j * 3 + 1]]); | 
					
						
							|  |  |  | 				Vector3 p2 = transform.xform(rvertices[rindices[j * 3 + 2]]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if ((p0 - p1).length_squared() < eps || (p1 - p2).length_squared() < eps || (p2 - p0).length_squared() < eps) { | 
					
						
							| 
									
										
										
										
											2017-12-14 08:59:46 -03:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				indices.push_back(vertex_ofs + rindices[j * 3 + 0]); | 
					
						
							|  |  |  | 				indices.push_back(vertex_ofs + rindices[j * 3 + 1]); | 
					
						
							|  |  |  | 				indices.push_back(vertex_ofs + rindices[j * 3 + 2]); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 		lightmap_surfaces.push_back(s); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//unwrap
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	bool use_cache = p_generate_cache; // Used to request cache generation and to know if cache was used
 | 
					
						
							|  |  |  | 	uint8_t *gen_cache; | 
					
						
							|  |  |  | 	int gen_cache_size; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 	float *gen_uvs; | 
					
						
							|  |  |  | 	int *gen_vertices; | 
					
						
							|  |  |  | 	int *gen_indices; | 
					
						
							|  |  |  | 	int gen_vertex_count; | 
					
						
							|  |  |  | 	int gen_index_count; | 
					
						
							|  |  |  | 	int size_x; | 
					
						
							|  |  |  | 	int size_y; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!ok) { | 
					
						
							|  |  |  | 		return ERR_CANT_CREATE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	clear_surfaces(); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	//create surfacetools for each surface..
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	LocalVector<Ref<SurfaceTool>> surfaces_tools; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 	for (int i = 0; i < lightmap_surfaces.size(); i++) { | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		Ref<SurfaceTool> st; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:03:09 -06:00
										 |  |  | 		st.instantiate(); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		st->begin(Mesh::PRIMITIVE_TRIANGLES); | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 		st->set_material(lightmap_surfaces[i].material); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		surfaces_tools.push_back(st); //stay there
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-24 09:35:07 +02:00
										 |  |  | 	print_verbose("Mesh: Gen indices: " + itos(gen_index_count)); | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 	//go through all indices
 | 
					
						
							|  |  |  | 	for (int i = 0; i < gen_index_count; i += 3) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], (int)uv_indices.size(), ERR_BUG); | 
					
						
							|  |  |  | 		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], (int)uv_indices.size(), ERR_BUG); | 
					
						
							|  |  |  | 		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], (int)uv_indices.size(), ERR_BUG); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 		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); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 		int surface = uv_indices[gen_vertices[gen_indices[i + 0]]].first; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for (int j = 0; j < 3; j++) { | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 			SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second]; | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 			if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 				surfaces_tools[surface]->set_color(v.color); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 			if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 				surfaces_tools[surface]->set_uv(v.uv); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 			if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 				surfaces_tools[surface]->set_normal(v.normal); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 			if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) { | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 				Plane t; | 
					
						
							|  |  |  | 				t.normal = v.tangent; | 
					
						
							| 
									
										
										
										
											2020-05-10 16:47:11 +02:00
										 |  |  | 				t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1; | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 				surfaces_tools[surface]->set_tangent(t); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 			if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 				surfaces_tools[surface]->set_bones(v.bones); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 			if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 				surfaces_tools[surface]->set_weights(v.weights); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]); | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 			surfaces_tools[surface]->set_uv2(uv2); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 			surfaces_tools[surface]->add_vertex(v.vertex); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//generate surfaces
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	for (unsigned int i = 0; i < surfaces_tools.size(); i++) { | 
					
						
							|  |  |  | 		surfaces_tools[i]->index(); | 
					
						
							|  |  |  | 		surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), lightmap_surfaces[i].format); | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	set_lightmap_size_hint(Size2(size_x, size_y)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-25 23:36:39 +02:00
										 |  |  | 	if (gen_cache_size > 0) { | 
					
						
							|  |  |  | 		r_dst_cache.resize(gen_cache_size); | 
					
						
							|  |  |  | 		memcpy(r_dst_cache.ptrw(), gen_cache, gen_cache_size); | 
					
						
							|  |  |  | 		memfree(gen_cache); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!use_cache) { | 
					
						
							|  |  |  | 		// Cache was not used, free the buffers
 | 
					
						
							|  |  |  | 		memfree(gen_vertices); | 
					
						
							|  |  |  | 		memfree(gen_indices); | 
					
						
							|  |  |  | 		memfree(gen_uvs); | 
					
						
							| 
									
										
										
										
											2020-04-22 15:34:00 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 14:11:26 -03:00
										 |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 12:20:11 -03:00
										 |  |  | void ArrayMesh::set_shadow_mesh(const Ref<ArrayMesh> &p_mesh) { | 
					
						
							|  |  |  | 	shadow_mesh = p_mesh; | 
					
						
							|  |  |  | 	if (shadow_mesh.is_valid()) { | 
					
						
							|  |  |  | 		RS::get_singleton()->mesh_set_shadow_mesh(mesh, shadow_mesh->get_rid()); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		RS::get_singleton()->mesh_set_shadow_mesh(mesh, RID()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<ArrayMesh> ArrayMesh::get_shadow_mesh() const { | 
					
						
							|  |  |  | 	return shadow_mesh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | void ArrayMesh::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &ArrayMesh::get_blend_shape_name); | 
					
						
							| 
									
										
										
										
											2020-10-15 07:53:18 -07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_blend_shape_name", "index", "name"), &ArrayMesh::set_blend_shape_name); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("clear_blend_shapes"), &ArrayMesh::clear_blend_shapes); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-01 22:40:47 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0)); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces); | 
					
						
							| 
									
										
										
										
											2021-06-29 22:55:11 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("surface_update_vertex_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_vertex_region); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("surface_update_attribute_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_attribute_region); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("surface_update_skin_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_skin_region); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &ArrayMesh::surface_get_primitive_type); | 
					
						
							| 
									
										
										
										
											2018-07-28 10:34:31 +10:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("surface_find_by_name", "name"), &ArrayMesh::surface_find_by_name); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name); | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape); | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("create_convex_shape", "clean", "simplify"), &ArrayMesh::create_convex_shape, DEFVAL(true), DEFVAL(false)); | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline); | 
					
						
							| 
									
										
										
										
											2020-12-23 09:34:26 +00:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("regen_normal_maps"), &ArrayMesh::regen_normal_maps); | 
					
						
							|  |  |  | 	ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normal_maps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); | 
					
						
							| 
									
										
										
										
											2018-08-20 20:58:53 +07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("lightmap_unwrap", "transform", "texel_size"), &ArrayMesh::lightmap_unwrap); | 
					
						
							| 
									
										
										
										
											2018-01-17 03:39:06 +00:00
										 |  |  | 	ClassDB::set_method_flags(get_class_static(), _scs_create("lightmap_unwrap"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_faces"), &ArrayMesh::get_faces); | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("generate_triangle_mesh"), &ArrayMesh::generate_triangle_mesh); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 12:20:11 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_shadow_mesh", "mesh"), &ArrayMesh::set_shadow_mesh); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_shadow_mesh"), &ArrayMesh::get_shadow_mesh); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_set_blend_shape_names", "blend_shape_names"), &ArrayMesh::_set_blend_shape_names); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_get_blend_shape_names"), &ArrayMesh::_get_blend_shape_names); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_set_surfaces", "surfaces"), &ArrayMesh::_set_surfaces); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_get_surfaces"), &ArrayMesh::_get_surfaces); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-03 23:06:17 +01:00
										 |  |  | 	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"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_surfaces", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_surfaces", "_get_surfaces"); | 
					
						
							| 
									
										
										
										
											2019-10-03 17:39:08 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode"); | 
					
						
							| 
									
										
										
										
											2022-05-20 00:24:41 -05:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, "suffix:m"), "set_custom_aabb", "get_custom_aabb"); | 
					
						
							| 
									
										
										
										
											2021-01-25 12:20:11 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shadow_mesh", PROPERTY_HINT_RESOURCE_TYPE, "ArrayMesh"), "set_shadow_mesh", "get_shadow_mesh"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-11 21:48:00 -06:00
										 |  |  | void ArrayMesh::reload_from_file() { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	RenderingServer::get_singleton()->mesh_clear(mesh); | 
					
						
							| 
									
										
										
										
											2017-11-17 16:47:11 -06:00
										 |  |  | 	surfaces.clear(); | 
					
						
							|  |  |  | 	clear_blend_shapes(); | 
					
						
							| 
									
										
										
										
											2018-09-09 20:52:43 +02:00
										 |  |  | 	clear_cache(); | 
					
						
							| 
									
										
										
										
											2017-11-17 16:47:11 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-11 21:48:00 -06:00
										 |  |  | 	Resource::reload_from_file(); | 
					
						
							| 
									
										
										
										
											2017-11-17 16:47:11 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-10 17:18:45 -03:00
										 |  |  | 	notify_property_list_changed(); | 
					
						
							| 
									
										
										
										
											2017-11-11 21:48:00 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | ArrayMesh::ArrayMesh() { | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	//mesh is now created on demand
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	//mesh = RenderingServer::get_singleton()->mesh_create();
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 18:18:55 -03:00
										 |  |  | ArrayMesh::~ArrayMesh() { | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	if (mesh.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		RenderingServer::get_singleton()->free(mesh); | 
					
						
							| 
									
										
										
										
											2019-08-18 19:40:52 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-04-28 11:46:45 +02:00
										 |  |  | ///////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PlaceholderMesh::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_aabb", "aabb"), &PlaceholderMesh::set_aabb); | 
					
						
							| 
									
										
										
										
											2022-05-20 00:24:41 -05:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::AABB, "aabb", PROPERTY_HINT_NONE, "suffix:m"), "set_aabb", "get_aabb"); | 
					
						
							| 
									
										
										
										
											2022-04-28 11:46:45 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PlaceholderMesh::PlaceholderMesh() { | 
					
						
							|  |  |  | 	rid = RS::get_singleton()->mesh_create(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PlaceholderMesh::~PlaceholderMesh() { | 
					
						
							|  |  |  | 	RS::get_singleton()->free(rid); | 
					
						
							|  |  |  | } |