| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | /*  mesh_instance_3d.cpp                                                  */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | #include "mesh_instance_3d.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-26 07:15:31 +01:00
										 |  |  | #include "scene/3d/physics/collision_shape_3d.h"
 | 
					
						
							|  |  |  | #include "scene/3d/physics/static_body_3d.h"
 | 
					
						
							|  |  |  | #include "scene/3d/skeleton_3d.h"
 | 
					
						
							| 
									
										
										
										
											2021-08-13 11:42:45 -05:00
										 |  |  | #include "scene/resources/3d/concave_polygon_shape_3d.h"
 | 
					
						
							|  |  |  | #include "scene/resources/3d/convex_polygon_shape_3d.h"
 | 
					
						
							| 
									
										
										
										
											2017-11-21 01:36:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	//this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else.
 | 
					
						
							|  |  |  | 	//add to it that it's probably found on first call to _set anyway.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!get_instance().is_valid()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 	HashMap<StringName, int>::Iterator E = blend_shape_properties.find(p_name); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 	if (E) { | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 		set_blend_shape_value(E->value, p_value); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-15 20:47:38 +10:00
										 |  |  | 	if (p_name.operator String().begins_with("surface_material_override/")) { | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 		int idx = p_name.operator String().get_slicec('/', 1).to_int(); | 
					
						
							| 
									
										
										
										
											2022-12-02 23:20:39 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-22 20:25:17 -07:00
										 |  |  | 		if (idx >= surface_override_materials.size() || idx < 0) { | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 16:26:46 -08:00
										 |  |  | 		set_surface_override_material(idx, p_value); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!get_instance().is_valid()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 	HashMap<StringName, int>::ConstIterator E = blend_shape_properties.find(p_name); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 	if (E) { | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 		r_ret = get_blend_shape_value(E->value); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-15 20:47:38 +10:00
										 |  |  | 	if (p_name.operator String().begins_with("surface_material_override/")) { | 
					
						
							| 
									
										
										
										
											2022-12-16 16:26:46 -08:00
										 |  |  | 		int idx = p_name.operator String().get_slicec('/', 1).to_int(); | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 		if (idx >= surface_override_materials.size() || idx < 0) { | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 		r_ret = surface_override_materials[idx]; | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	List<String> ls; | 
					
						
							| 
									
										
										
										
											2021-10-15 19:04:35 -03:00
										 |  |  | 	for (const KeyValue<StringName, int> &E : blend_shape_properties) { | 
					
						
							| 
									
										
										
										
											2021-08-09 14:13:42 -06:00
										 |  |  | 		ls.push_back(E.key); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 18:03:38 +01:00
										 |  |  | 	ls.sort(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 15:46:25 +02:00
										 |  |  | 	for (const String &E : ls) { | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 		p_list->push_back(PropertyInfo(Variant::FLOAT, E, PROPERTY_HINT_RANGE, "-1,1,0.00001")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (mesh.is_valid()) { | 
					
						
							| 
									
										
										
										
											2022-12-16 16:26:46 -08:00
										 |  |  | 		for (int i = 0; i < mesh->get_surface_count(); i++) { | 
					
						
							| 
									
										
										
										
											2023-10-20 02:39:06 +02:00
										 |  |  | 			p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("%s/%d", PNAME("surface_material_override"), i), PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT)); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (mesh == p_mesh) { | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (mesh.is_valid()) { | 
					
						
							| 
									
										
										
										
											2023-07-03 21:29:37 +02:00
										 |  |  | 		mesh->disconnect_changed(callable_mp(this, &MeshInstance3D::_mesh_changed)); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	mesh = p_mesh; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mesh.is_valid()) { | 
					
						
							| 
									
										
										
										
											2023-03-04 10:45:43 +01:00
										 |  |  | 		// If mesh is a PrimitiveMesh, calling get_rid on it can trigger a changed callback
 | 
					
						
							|  |  |  | 		// so do this before connecting _mesh_changed.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		set_base(mesh->get_rid()); | 
					
						
							| 
									
										
										
										
											2023-07-03 21:29:37 +02:00
										 |  |  | 		mesh->connect_changed(callable_mp(this, &MeshInstance3D::_mesh_changed)); | 
					
						
							| 
									
										
										
										
											2022-08-30 12:42:10 +07:00
										 |  |  | 		_mesh_changed(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2021-10-15 19:04:35 -03:00
										 |  |  | 		blend_shape_tracks.clear(); | 
					
						
							|  |  |  | 		blend_shape_properties.clear(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		set_base(RID()); | 
					
						
							| 
									
										
										
										
											2021-10-15 19:04:35 -03:00
										 |  |  | 		update_gizmos(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-10 17:18:45 -03:00
										 |  |  | 	notify_property_list_changed(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | Ref<Mesh> MeshInstance3D::get_mesh() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return mesh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 19:04:35 -03:00
										 |  |  | int MeshInstance3D::get_blend_shape_count() const { | 
					
						
							|  |  |  | 	if (mesh.is_null()) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return mesh->get_blend_shape_count(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | int MeshInstance3D::find_blend_shape_by_name(const StringName &p_name) { | 
					
						
							|  |  |  | 	if (mesh.is_null()) { | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (int i = 0; i < mesh->get_blend_shape_count(); i++) { | 
					
						
							|  |  |  | 		if (mesh->get_blend_shape_name(i) == p_name) { | 
					
						
							|  |  |  | 			return i; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | float MeshInstance3D::get_blend_shape_value(int p_blend_shape) const { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(mesh.is_null(), 0.0); | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_blend_shape, (int)blend_shape_tracks.size(), 0); | 
					
						
							|  |  |  | 	return blend_shape_tracks[p_blend_shape]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void MeshInstance3D::set_blend_shape_value(int p_blend_shape, float p_value) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(mesh.is_null()); | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX(p_blend_shape, (int)blend_shape_tracks.size()); | 
					
						
							|  |  |  | 	blend_shape_tracks[p_blend_shape] = p_value; | 
					
						
							|  |  |  | 	RenderingServer::get_singleton()->instance_set_blend_shape_weight(get_instance(), p_blend_shape, p_value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::_resolve_skeleton_path() { | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 	Ref<SkinReference> new_skin_reference; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!skeleton_path.is_empty()) { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 		Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(get_node(skeleton_path)); | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 		if (skeleton) { | 
					
						
							| 
									
										
										
										
											2019-12-16 13:00:30 -03:00
										 |  |  | 			if (skin_internal.is_null()) { | 
					
						
							| 
									
										
										
										
											2021-10-13 09:37:40 -03:00
										 |  |  | 				new_skin_reference = skeleton->register_skin(skeleton->create_skin_from_rest_transforms()); | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 				//a skin was created for us
 | 
					
						
							| 
									
										
										
										
											2019-12-16 13:00:30 -03:00
										 |  |  | 				skin_internal = new_skin_reference->get_skin(); | 
					
						
							| 
									
										
										
										
											2021-02-10 17:18:45 -03:00
										 |  |  | 				notify_property_list_changed(); | 
					
						
							| 
									
										
										
										
											2021-10-13 09:37:40 -03:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				new_skin_reference = skeleton->register_skin(skin_internal); | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	skin_ref = new_skin_reference; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (skin_ref.is_valid()) { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		RenderingServer::get_singleton()->instance_attach_skeleton(get_instance(), skin_ref->get_skeleton()); | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 		RenderingServer::get_singleton()->instance_attach_skeleton(get_instance(), RID()); | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::set_skin(const Ref<Skin> &p_skin) { | 
					
						
							| 
									
										
										
										
											2019-12-16 13:00:30 -03:00
										 |  |  | 	skin_internal = p_skin; | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 	skin = p_skin; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!is_inside_tree()) { | 
					
						
							| 
									
										
										
										
											2014-05-13 13:24:26 +08:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 	_resolve_skeleton_path(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-13 13:24:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | Ref<Skin> MeshInstance3D::get_skin() const { | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 	return skin; | 
					
						
							| 
									
										
										
										
											2014-05-13 13:24:26 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-30 12:36:17 -07:00
										 |  |  | Ref<SkinReference> MeshInstance3D::get_skin_reference() const { | 
					
						
							|  |  |  | 	return skin_ref; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::set_skeleton_path(const NodePath &p_skeleton) { | 
					
						
							| 
									
										
										
										
											2014-05-13 13:24:26 +08:00
										 |  |  | 	skeleton_path = p_skeleton; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!is_inside_tree()) { | 
					
						
							| 
									
										
										
										
											2014-05-13 13:24:26 +08:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-13 13:24:26 +08:00
										 |  |  | 	_resolve_skeleton_path(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | NodePath MeshInstance3D::get_skeleton_path() { | 
					
						
							| 
									
										
										
										
											2014-05-13 13:24:26 +08:00
										 |  |  | 	return skeleton_path; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | AABB MeshInstance3D::get_aabb() const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!mesh.is_null()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return mesh->get_aabb(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | 	return AABB(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | Node *MeshInstance3D::create_trimesh_collision_node() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (mesh.is_null()) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-25 11:43:06 -06:00
										 |  |  | 	Ref<ConcavePolygonShape3D> shape = mesh->create_trimesh_shape(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (shape.is_null()) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	StaticBody3D *static_body = memnew(StaticBody3D); | 
					
						
							|  |  |  | 	CollisionShape3D *cshape = memnew(CollisionShape3D); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	cshape->set_shape(shape); | 
					
						
							| 
									
										
										
										
											2021-10-21 16:46:07 +02:00
										 |  |  | 	static_body->add_child(cshape, true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return static_body; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::create_trimesh_collision() { | 
					
						
							|  |  |  | 	StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_trimesh_collision_node()); | 
					
						
							| 
									
										
										
										
											2023-06-06 14:59:54 +02:00
										 |  |  | 	ERR_FAIL_NULL(static_body); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	static_body->set_name(String(get_name()) + "_col"); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 16:46:07 +02:00
										 |  |  | 	add_child(static_body, true); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	if (get_owner()) { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 		CollisionShape3D *cshape = Object::cast_to<CollisionShape3D>(static_body->get_child(0)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		static_body->set_owner(get_owner()); | 
					
						
							| 
									
										
										
										
											2014-10-12 02:13:22 -03:00
										 |  |  | 		cshape->set_owner(get_owner()); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | Node *MeshInstance3D::create_convex_collision_node(bool p_clean, bool p_simplify) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (mesh.is_null()) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-25 11:43:06 -06:00
										 |  |  | 	Ref<ConvexPolygonShape3D> shape = mesh->create_convex_shape(p_clean, p_simplify); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (shape.is_null()) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	StaticBody3D *static_body = memnew(StaticBody3D); | 
					
						
							|  |  |  | 	CollisionShape3D *cshape = memnew(CollisionShape3D); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	cshape->set_shape(shape); | 
					
						
							| 
									
										
										
										
											2021-10-21 16:46:07 +02:00
										 |  |  | 	static_body->add_child(cshape, true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return static_body; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | void MeshInstance3D::create_convex_collision(bool p_clean, bool p_simplify) { | 
					
						
							|  |  |  | 	StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_convex_collision_node(p_clean, p_simplify)); | 
					
						
							| 
									
										
										
										
											2023-06-06 14:59:54 +02:00
										 |  |  | 	ERR_FAIL_NULL(static_body); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	static_body->set_name(String(get_name()) + "_col"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 16:46:07 +02:00
										 |  |  | 	add_child(static_body, true); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	if (get_owner()) { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 		CollisionShape3D *cshape = Object::cast_to<CollisionShape3D>(static_body->get_child(0)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		static_body->set_owner(get_owner()); | 
					
						
							| 
									
										
										
										
											2014-10-12 02:13:22 -03:00
										 |  |  | 		cshape->set_owner(get_owner()); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-26 16:10:26 +01:00
										 |  |  | Node *MeshInstance3D::create_multiple_convex_collisions_node(const Ref<MeshConvexDecompositionSettings> &p_settings) { | 
					
						
							| 
									
										
										
										
											2020-04-30 09:41:22 +03:00
										 |  |  | 	if (mesh.is_null()) { | 
					
						
							|  |  |  | 		return nullptr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-26 16:10:26 +01:00
										 |  |  | 	Ref<MeshConvexDecompositionSettings> settings; | 
					
						
							|  |  |  | 	if (p_settings.is_valid()) { | 
					
						
							|  |  |  | 		settings = p_settings; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		settings.instantiate(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												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>> shapes = mesh->convex_decompose(settings); | 
					
						
							| 
									
										
										
										
											2020-04-30 09:41:22 +03:00
										 |  |  | 	if (!shapes.size()) { | 
					
						
							|  |  |  | 		return nullptr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	StaticBody3D *static_body = memnew(StaticBody3D); | 
					
						
							|  |  |  | 	for (int i = 0; i < shapes.size(); i++) { | 
					
						
							|  |  |  | 		CollisionShape3D *cshape = memnew(CollisionShape3D); | 
					
						
							|  |  |  | 		cshape->set_shape(shapes[i]); | 
					
						
							| 
									
										
										
										
											2021-10-21 16:46:07 +02:00
										 |  |  | 		static_body->add_child(cshape, true); | 
					
						
							| 
									
										
										
										
											2020-04-30 09:41:22 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return static_body; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-26 16:10:26 +01:00
										 |  |  | void MeshInstance3D::create_multiple_convex_collisions(const Ref<MeshConvexDecompositionSettings> &p_settings) { | 
					
						
							|  |  |  | 	StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_multiple_convex_collisions_node(p_settings)); | 
					
						
							| 
									
										
										
										
											2023-06-06 14:59:54 +02:00
										 |  |  | 	ERR_FAIL_NULL(static_body); | 
					
						
							| 
									
										
										
										
											2020-04-30 09:41:22 +03:00
										 |  |  | 	static_body->set_name(String(get_name()) + "_col"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 16:46:07 +02:00
										 |  |  | 	add_child(static_body, true); | 
					
						
							| 
									
										
										
										
											2020-04-30 09:41:22 +03:00
										 |  |  | 	if (get_owner()) { | 
					
						
							|  |  |  | 		static_body->set_owner(get_owner()); | 
					
						
							|  |  |  | 		int count = static_body->get_child_count(); | 
					
						
							|  |  |  | 		for (int i = 0; i < count; i++) { | 
					
						
							|  |  |  | 			CollisionShape3D *cshape = Object::cast_to<CollisionShape3D>(static_body->get_child(i)); | 
					
						
							|  |  |  | 			cshape->set_owner(get_owner()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 	switch (p_what) { | 
					
						
							|  |  |  | 		case NOTIFICATION_ENTER_TREE: { | 
					
						
							|  |  |  | 			_resolve_skeleton_path(); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2022-12-04 23:04:48 +02:00
										 |  |  | 		case NOTIFICATION_TRANSLATION_CHANGED: { | 
					
						
							|  |  |  | 			if (mesh.is_valid()) { | 
					
						
							|  |  |  | 				mesh->notification(NOTIFICATION_TRANSLATION_CHANGED); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2014-05-13 13:24:26 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | int MeshInstance3D::get_surface_override_material_count() const { | 
					
						
							|  |  |  | 	return surface_override_materials.size(); | 
					
						
							| 
									
										
										
										
											2018-10-23 15:25:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | void MeshInstance3D::set_surface_override_material(int p_surface, const Ref<Material> &p_material) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX(p_surface, surface_override_materials.size()); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 	surface_override_materials.write[p_surface] = p_material; | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 	if (surface_override_materials[p_surface].is_valid()) { | 
					
						
							|  |  |  | 		RS::get_singleton()->instance_set_surface_override_material(get_instance(), p_surface, surface_override_materials[p_surface]->get_rid()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 		RS::get_singleton()->instance_set_surface_override_material(get_instance(), p_surface, RID()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | Ref<Material> MeshInstance3D::get_surface_override_material(int p_surface) const { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_surface, surface_override_materials.size(), Ref<Material>()); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 	return surface_override_materials[p_surface]; | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-30 17:18:09 -08:00
										 |  |  | Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	Ref<Material> mat_override = get_material_override(); | 
					
						
							|  |  |  | 	if (mat_override.is_valid()) { | 
					
						
							|  |  |  | 		return mat_override; | 
					
						
							| 
									
										
										
										
											2020-04-22 14:35:25 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-30 17:18:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 	Ref<Material> surface_material = get_surface_override_material(p_surface); | 
					
						
							| 
									
										
										
										
											2020-04-22 14:35:25 +02:00
										 |  |  | 	if (surface_material.is_valid()) { | 
					
						
							|  |  |  | 		return surface_material; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-30 17:18:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	Ref<Mesh> m = get_mesh(); | 
					
						
							|  |  |  | 	if (m.is_valid()) { | 
					
						
							|  |  |  | 		return m->surface_get_material(p_surface); | 
					
						
							| 
									
										
										
										
											2020-01-30 17:18:09 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-04-22 14:35:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return Ref<Material>(); | 
					
						
							| 
									
										
										
										
											2020-01-30 17:18:09 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::_mesh_changed() { | 
					
						
							| 
									
										
										
										
											2021-02-18 16:51:39 +05:30
										 |  |  | 	ERR_FAIL_COND(mesh.is_null()); | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 	surface_override_materials.resize(mesh->get_surface_count()); | 
					
						
							| 
									
										
										
										
											2021-10-15 19:04:35 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	uint32_t initialize_bs_from = blend_shape_tracks.size(); | 
					
						
							|  |  |  | 	blend_shape_tracks.resize(mesh->get_blend_shape_count()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (uint32_t i = 0; i < blend_shape_tracks.size(); i++) { | 
					
						
							|  |  |  | 		blend_shape_properties["blend_shapes/" + String(mesh->get_blend_shape_name(i))] = i; | 
					
						
							|  |  |  | 		if (i < initialize_bs_from) { | 
					
						
							|  |  |  | 			set_blend_shape_value(i, blend_shape_tracks[i]); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			set_blend_shape_value(i, 0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 12:42:10 +07:00
										 |  |  | 	int surface_count = mesh->get_surface_count(); | 
					
						
							|  |  |  | 	for (int surface_index = 0; surface_index < surface_count; ++surface_index) { | 
					
						
							|  |  |  | 		if (surface_override_materials[surface_index].is_valid()) { | 
					
						
							|  |  |  | 			RS::get_singleton()->instance_set_surface_override_material(get_instance(), surface_index, surface_override_materials[surface_index]->get_rid()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-23 16:49:50 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2016-05-27 14:18:40 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-19 02:01:19 +02:00
										 |  |  | MeshInstance3D *MeshInstance3D::create_debug_tangents_node() { | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 	Vector<Vector3> lines; | 
					
						
							|  |  |  | 	Vector<Color> colors; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	Ref<Mesh> m = get_mesh(); | 
					
						
							|  |  |  | 	if (!m.is_valid()) { | 
					
						
							| 
									
										
										
										
											2022-06-19 02:01:19 +02:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 12:53:28 +03:00
										 |  |  | 	for (int i = 0; i < m->get_surface_count(); i++) { | 
					
						
							|  |  |  | 		Array arrays = m->surface_get_arrays(i); | 
					
						
							| 
									
										
										
										
											2021-09-29 16:59:46 +08:00
										 |  |  | 		ERR_CONTINUE(arrays.size() != Mesh::ARRAY_MAX); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 		Vector<Vector3> verts = arrays[Mesh::ARRAY_VERTEX]; | 
					
						
							|  |  |  | 		Vector<Vector3> norms = arrays[Mesh::ARRAY_NORMAL]; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (norms.size() == 0) { | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 		Vector<float> tangents = arrays[Mesh::ARRAY_TANGENT]; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (tangents.size() == 0) { | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for (int j = 0; j < verts.size(); j++) { | 
					
						
							|  |  |  | 			Vector3 v = verts[j]; | 
					
						
							|  |  |  | 			Vector3 n = norms[j]; | 
					
						
							|  |  |  | 			Vector3 t = Vector3(tangents[j * 4 + 0], tangents[j * 4 + 1], tangents[j * 4 + 2]); | 
					
						
							|  |  |  | 			Vector3 b = (n.cross(t)).normalized() * tangents[j * 4 + 3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			lines.push_back(v); //normal
 | 
					
						
							|  |  |  | 			colors.push_back(Color(0, 0, 1)); //color
 | 
					
						
							|  |  |  | 			lines.push_back(v + n * 0.04); //normal
 | 
					
						
							|  |  |  | 			colors.push_back(Color(0, 0, 1)); //color
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			lines.push_back(v); //tangent
 | 
					
						
							|  |  |  | 			colors.push_back(Color(1, 0, 0)); //color
 | 
					
						
							|  |  |  | 			lines.push_back(v + t * 0.04); //tangent
 | 
					
						
							|  |  |  | 			colors.push_back(Color(1, 0, 0)); //color
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			lines.push_back(v); //binormal
 | 
					
						
							|  |  |  | 			colors.push_back(Color(0, 1, 0)); //color
 | 
					
						
							|  |  |  | 			lines.push_back(v + b * 0.04); //binormal
 | 
					
						
							|  |  |  | 			colors.push_back(Color(0, 1, 0)); //color
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lines.size()) { | 
					
						
							| 
									
										
										
										
											2019-09-15 01:01:52 -03:00
										 |  |  | 		Ref<StandardMaterial3D> sm; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:03:09 -06:00
										 |  |  | 		sm.instantiate(); | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-15 01:01:52 -03:00
										 |  |  | 		sm->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); | 
					
						
							|  |  |  | 		sm->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); | 
					
						
							|  |  |  | 		sm->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); | 
					
						
							| 
									
										
										
										
											2023-09-27 00:45:57 +02:00
										 |  |  | 		sm->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Ref<ArrayMesh> am; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:03:09 -06:00
										 |  |  | 		am.instantiate(); | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 		Array a; | 
					
						
							|  |  |  | 		a.resize(Mesh::ARRAY_MAX); | 
					
						
							|  |  |  | 		a[Mesh::ARRAY_VERTEX] = lines; | 
					
						
							|  |  |  | 		a[Mesh::ARRAY_COLOR] = colors; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		am->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a); | 
					
						
							|  |  |  | 		am->surface_set_material(0, sm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 		MeshInstance3D *mi = memnew(MeshInstance3D); | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 		mi->set_mesh(am); | 
					
						
							|  |  |  | 		mi->set_name("DebugTangents"); | 
					
						
							| 
									
										
										
										
											2022-06-19 02:01:19 +02:00
										 |  |  | 		return mi; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-04 23:52:23 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-19 02:01:19 +02:00
										 |  |  | 	return nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MeshInstance3D::create_debug_tangents() { | 
					
						
							|  |  |  | 	MeshInstance3D *mi = create_debug_tangents_node(); | 
					
						
							|  |  |  | 	if (!mi) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	add_child(mi, true); | 
					
						
							|  |  |  | 	if (is_inside_tree() && this == get_tree()->get_edited_scene_root()) { | 
					
						
							|  |  |  | 		mi->set_owner(this); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		mi->set_owner(get_owner()); | 
					
						
							| 
									
										
										
										
											2017-07-03 10:44:45 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-08 01:09:46 +02:00
										 |  |  | bool MeshInstance3D::_property_can_revert(const StringName &p_name) const { | 
					
						
							|  |  |  | 	HashMap<StringName, int>::ConstIterator E = blend_shape_properties.find(p_name); | 
					
						
							|  |  |  | 	if (E) { | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MeshInstance3D::_property_get_revert(const StringName &p_name, Variant &r_property) const { | 
					
						
							|  |  |  | 	HashMap<StringName, int>::ConstIterator E = blend_shape_properties.find(p_name); | 
					
						
							|  |  |  | 	if (E) { | 
					
						
							|  |  |  | 		r_property = 0.0f; | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-06 02:08:20 +02:00
										 |  |  | Ref<ArrayMesh> MeshInstance3D::bake_mesh_from_current_blend_shape_mix(Ref<ArrayMesh> p_existing) { | 
					
						
							|  |  |  | 	Ref<ArrayMesh> source_mesh = get_mesh(); | 
					
						
							| 
									
										
										
										
											2024-07-26 11:52:26 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(source_mesh.is_null(), Ref<ArrayMesh>(), "The source mesh must be a valid ArrayMesh."); | 
					
						
							| 
									
										
										
										
											2023-05-06 02:08:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Ref<ArrayMesh> bake_mesh; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p_existing.is_valid()) { | 
					
						
							| 
									
										
										
										
											2024-07-26 11:52:26 +02:00
										 |  |  | 		ERR_FAIL_COND_V_MSG(p_existing.is_null(), Ref<ArrayMesh>(), "The existing mesh must be a valid ArrayMesh."); | 
					
						
							| 
									
										
										
										
											2023-05-06 02:08:20 +02:00
										 |  |  | 		ERR_FAIL_COND_V_MSG(source_mesh == p_existing, Ref<ArrayMesh>(), "The source mesh can not be the same mesh as the existing mesh."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bake_mesh = p_existing; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		bake_mesh.instantiate(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Mesh::BlendShapeMode blend_shape_mode = source_mesh->get_blend_shape_mode(); | 
					
						
							|  |  |  | 	int mesh_surface_count = source_mesh->get_surface_count(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bake_mesh->clear_surfaces(); | 
					
						
							|  |  |  | 	bake_mesh->set_blend_shape_mode(blend_shape_mode); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int surface_index = 0; surface_index < mesh_surface_count; surface_index++) { | 
					
						
							|  |  |  | 		uint32_t surface_format = source_mesh->surface_get_format(surface_index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ERR_CONTINUE(0 == (surface_format & Mesh::ARRAY_FORMAT_VERTEX)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const Array &source_mesh_arrays = source_mesh->surface_get_arrays(surface_index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(source_mesh_arrays.size() != RS::ARRAY_MAX, Ref<ArrayMesh>()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const Vector<Vector3> &source_mesh_vertex_array = source_mesh_arrays[Mesh::ARRAY_VERTEX]; | 
					
						
							|  |  |  | 		const Vector<Vector3> &source_mesh_normal_array = source_mesh_arrays[Mesh::ARRAY_NORMAL]; | 
					
						
							|  |  |  | 		const Vector<float> &source_mesh_tangent_array = source_mesh_arrays[Mesh::ARRAY_TANGENT]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Array new_mesh_arrays; | 
					
						
							|  |  |  | 		new_mesh_arrays.resize(Mesh::ARRAY_MAX); | 
					
						
							|  |  |  | 		for (int i = 0; i < source_mesh_arrays.size(); i++) { | 
					
						
							|  |  |  | 			if (i == Mesh::ARRAY_VERTEX || i == Mesh::ARRAY_NORMAL || i == Mesh::ARRAY_TANGENT) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			new_mesh_arrays[i] = source_mesh_arrays[i]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bool use_normal_array = source_mesh_normal_array.size() == source_mesh_vertex_array.size(); | 
					
						
							|  |  |  | 		bool use_tangent_array = source_mesh_tangent_array.size() / 4 == source_mesh_vertex_array.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Vector<Vector3> lerped_vertex_array = source_mesh_vertex_array; | 
					
						
							|  |  |  | 		Vector<Vector3> lerped_normal_array = source_mesh_normal_array; | 
					
						
							|  |  |  | 		Vector<float> lerped_tangent_array = source_mesh_tangent_array; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const Vector3 *source_vertices_ptr = source_mesh_vertex_array.ptr(); | 
					
						
							|  |  |  | 		const Vector3 *source_normals_ptr = source_mesh_normal_array.ptr(); | 
					
						
							|  |  |  | 		const float *source_tangents_ptr = source_mesh_tangent_array.ptr(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Vector3 *lerped_vertices_ptrw = lerped_vertex_array.ptrw(); | 
					
						
							|  |  |  | 		Vector3 *lerped_normals_ptrw = lerped_normal_array.ptrw(); | 
					
						
							|  |  |  | 		float *lerped_tangents_ptrw = lerped_tangent_array.ptrw(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const Array &blendshapes_mesh_arrays = source_mesh->surface_get_blend_shape_arrays(surface_index); | 
					
						
							|  |  |  | 		int blend_shape_count = source_mesh->get_blend_shape_count(); | 
					
						
							|  |  |  | 		ERR_FAIL_COND_V(blendshapes_mesh_arrays.size() != blend_shape_count, Ref<ArrayMesh>()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (int blendshape_index = 0; blendshape_index < blend_shape_count; blendshape_index++) { | 
					
						
							|  |  |  | 			float blend_weight = get_blend_shape_value(blendshape_index); | 
					
						
							|  |  |  | 			if (abs(blend_weight) <= 0.0001) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const Array &blendshape_mesh_arrays = blendshapes_mesh_arrays[blendshape_index]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const Vector<Vector3> &blendshape_vertex_array = blendshape_mesh_arrays[Mesh::ARRAY_VERTEX]; | 
					
						
							|  |  |  | 			const Vector<Vector3> &blendshape_normal_array = blendshape_mesh_arrays[Mesh::ARRAY_NORMAL]; | 
					
						
							|  |  |  | 			const Vector<float> &blendshape_tangent_array = blendshape_mesh_arrays[Mesh::ARRAY_TANGENT]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ERR_FAIL_COND_V(source_mesh_vertex_array.size() != blendshape_vertex_array.size(), Ref<ArrayMesh>()); | 
					
						
							|  |  |  | 			ERR_FAIL_COND_V(source_mesh_normal_array.size() != blendshape_normal_array.size(), Ref<ArrayMesh>()); | 
					
						
							|  |  |  | 			ERR_FAIL_COND_V(source_mesh_tangent_array.size() != blendshape_tangent_array.size(), Ref<ArrayMesh>()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const Vector3 *blendshape_vertices_ptr = blendshape_vertex_array.ptr(); | 
					
						
							|  |  |  | 			const Vector3 *blendshape_normals_ptr = blendshape_normal_array.ptr(); | 
					
						
							|  |  |  | 			const float *blendshape_tangents_ptr = blendshape_tangent_array.ptr(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (blend_shape_mode == Mesh::BLEND_SHAPE_MODE_NORMALIZED) { | 
					
						
							|  |  |  | 				for (int i = 0; i < source_mesh_vertex_array.size(); i++) { | 
					
						
							|  |  |  | 					const Vector3 &source_vertex = source_vertices_ptr[i]; | 
					
						
							|  |  |  | 					const Vector3 &blendshape_vertex = blendshape_vertices_ptr[i]; | 
					
						
							|  |  |  | 					Vector3 lerped_vertex = source_vertex.lerp(blendshape_vertex, blend_weight) - source_vertex; | 
					
						
							|  |  |  | 					lerped_vertices_ptrw[i] += lerped_vertex; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (use_normal_array) { | 
					
						
							|  |  |  | 						const Vector3 &source_normal = source_normals_ptr[i]; | 
					
						
							|  |  |  | 						const Vector3 &blendshape_normal = blendshape_normals_ptr[i]; | 
					
						
							|  |  |  | 						Vector3 lerped_normal = source_normal.lerp(blendshape_normal, blend_weight) - source_normal; | 
					
						
							|  |  |  | 						lerped_normals_ptrw[i] += lerped_normal; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (use_tangent_array) { | 
					
						
							|  |  |  | 						int tangent_index = i * 4; | 
					
						
							|  |  |  | 						const Vector4 source_tangent = Vector4( | 
					
						
							|  |  |  | 								source_tangents_ptr[tangent_index], | 
					
						
							|  |  |  | 								source_tangents_ptr[tangent_index + 1], | 
					
						
							|  |  |  | 								source_tangents_ptr[tangent_index + 2], | 
					
						
							|  |  |  | 								source_tangents_ptr[tangent_index + 3]); | 
					
						
							|  |  |  | 						const Vector4 blendshape_tangent = Vector4( | 
					
						
							|  |  |  | 								blendshape_tangents_ptr[tangent_index], | 
					
						
							|  |  |  | 								blendshape_tangents_ptr[tangent_index + 1], | 
					
						
							|  |  |  | 								blendshape_tangents_ptr[tangent_index + 2], | 
					
						
							|  |  |  | 								blendshape_tangents_ptr[tangent_index + 3]); | 
					
						
							|  |  |  | 						Vector4 lerped_tangent = source_tangent.lerp(blendshape_tangent, blend_weight); | 
					
						
							|  |  |  | 						lerped_tangents_ptrw[tangent_index] += lerped_tangent.x; | 
					
						
							|  |  |  | 						lerped_tangents_ptrw[tangent_index + 1] += lerped_tangent.y; | 
					
						
							|  |  |  | 						lerped_tangents_ptrw[tangent_index + 2] += lerped_tangent.z; | 
					
						
							|  |  |  | 						lerped_tangents_ptrw[tangent_index + 3] += lerped_tangent.w; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if (blend_shape_mode == Mesh::BLEND_SHAPE_MODE_RELATIVE) { | 
					
						
							|  |  |  | 				for (int i = 0; i < source_mesh_vertex_array.size(); i++) { | 
					
						
							|  |  |  | 					const Vector3 &blendshape_vertex = blendshape_vertices_ptr[i]; | 
					
						
							|  |  |  | 					lerped_vertices_ptrw[i] += blendshape_vertex * blend_weight; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (use_normal_array) { | 
					
						
							|  |  |  | 						const Vector3 &blendshape_normal = blendshape_normals_ptr[i]; | 
					
						
							|  |  |  | 						lerped_normals_ptrw[i] += blendshape_normal * blend_weight; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (use_tangent_array) { | 
					
						
							|  |  |  | 						int tangent_index = i * 4; | 
					
						
							|  |  |  | 						const Vector4 blendshape_tangent = Vector4( | 
					
						
							|  |  |  | 								blendshape_tangents_ptr[tangent_index], | 
					
						
							|  |  |  | 								blendshape_tangents_ptr[tangent_index + 1], | 
					
						
							|  |  |  | 								blendshape_tangents_ptr[tangent_index + 2], | 
					
						
							|  |  |  | 								blendshape_tangents_ptr[tangent_index + 3]); | 
					
						
							|  |  |  | 						Vector4 lerped_tangent = blendshape_tangent * blend_weight; | 
					
						
							|  |  |  | 						lerped_tangents_ptrw[tangent_index] += lerped_tangent.x; | 
					
						
							|  |  |  | 						lerped_tangents_ptrw[tangent_index + 1] += lerped_tangent.y; | 
					
						
							|  |  |  | 						lerped_tangents_ptrw[tangent_index + 2] += lerped_tangent.z; | 
					
						
							|  |  |  | 						lerped_tangents_ptrw[tangent_index + 3] += lerped_tangent.w; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		new_mesh_arrays[Mesh::ARRAY_VERTEX] = lerped_vertex_array; | 
					
						
							|  |  |  | 		if (use_normal_array) { | 
					
						
							|  |  |  | 			new_mesh_arrays[Mesh::ARRAY_NORMAL] = lerped_normal_array; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (use_tangent_array) { | 
					
						
							|  |  |  | 			new_mesh_arrays[Mesh::ARRAY_TANGENT] = lerped_tangent_array; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bake_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, new_mesh_arrays, Array(), Dictionary(), surface_format); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return bake_mesh; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void MeshInstance3D::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshInstance3D::set_mesh); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_mesh"), &MeshInstance3D::get_mesh); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_skeleton_path", "skeleton_path"), &MeshInstance3D::set_skeleton_path); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_skeleton_path"), &MeshInstance3D::get_skeleton_path); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_skin", "skin"), &MeshInstance3D::set_skin); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_skin"), &MeshInstance3D::get_skin); | 
					
						
							| 
									
										
										
										
											2024-03-30 12:36:17 -07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_skin_reference"), &MeshInstance3D::get_skin_reference); | 
					
						
							| 
									
										
										
										
											2017-01-14 11:07:57 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 20:45:16 -07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_surface_override_material_count"), &MeshInstance3D::get_surface_override_material_count); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_surface_override_material", "surface", "material"), &MeshInstance3D::set_surface_override_material); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_surface_override_material", "surface"), &MeshInstance3D::get_surface_override_material); | 
					
						
							| 
									
										
										
										
											2020-01-30 17:18:09 -08:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_active_material", "surface"), &MeshInstance3D::get_active_material); | 
					
						
							| 
									
										
										
										
											2017-06-30 21:30:17 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("create_trimesh_collision"), &MeshInstance3D::create_trimesh_collision); | 
					
						
							|  |  |  | 	ClassDB::set_method_flags("MeshInstance3D", "create_trimesh_collision", METHOD_FLAGS_DEFAULT); | 
					
						
							| 
									
										
										
										
											2021-07-07 12:14:12 -07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("create_convex_collision", "clean", "simplify"), &MeshInstance3D::create_convex_collision, DEFVAL(true), DEFVAL(false)); | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::set_method_flags("MeshInstance3D", "create_convex_collision", METHOD_FLAGS_DEFAULT); | 
					
						
							| 
									
										
										
										
											2023-01-26 16:10:26 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("create_multiple_convex_collisions", "settings"), &MeshInstance3D::create_multiple_convex_collisions, DEFVAL(Ref<MeshConvexDecompositionSettings>())); | 
					
						
							| 
									
										
										
										
											2020-04-30 09:41:22 +03:00
										 |  |  | 	ClassDB::set_method_flags("MeshInstance3D", "create_multiple_convex_collisions", METHOD_FLAGS_DEFAULT); | 
					
						
							| 
									
										
										
										
											2017-01-04 01:16:14 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 19:04:35 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &MeshInstance3D::get_blend_shape_count); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("find_blend_shape_by_name", "name"), &MeshInstance3D::find_blend_shape_by_name); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_blend_shape_value", "blend_shape_idx"), &MeshInstance3D::get_blend_shape_value); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_blend_shape_value", "blend_shape_idx", "value"), &MeshInstance3D::set_blend_shape_value); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("create_debug_tangents"), &MeshInstance3D::create_debug_tangents); | 
					
						
							| 
									
										
										
										
											2023-05-06 02:08:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("bake_mesh_from_current_blend_shape_mix", "existing"), &MeshInstance3D::bake_mesh_from_current_blend_shape_mix, DEFVAL(Ref<ArrayMesh>())); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 01:11:37 +01:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); | 
					
						
							| 
									
										
										
										
											2019-10-31 19:54:21 -03:00
										 |  |  | 	ADD_GROUP("Skeleton", ""); | 
					
						
							| 
									
										
										
										
											2019-09-18 19:46:32 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skin", PROPERTY_HINT_RESOURCE_TYPE, "Skin"), "set_skin", "get_skin"); | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton3D"), "set_skeleton_path", "get_skeleton_path"); | 
					
						
							| 
									
										
										
										
											2019-11-01 00:35:26 -03:00
										 |  |  | 	ADD_GROUP("", ""); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | MeshInstance3D::MeshInstance3D() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | MeshInstance3D::~MeshInstance3D() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |