| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | /*  ray_cast_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 "ray_cast_3d.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-26 07:15:31 +01:00
										 |  |  | #include "scene/3d/physics/collision_object_3d.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-19 01:02:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-10 19:06:21 +02:00
										 |  |  | void RayCast3D::set_target_position(const Vector3 &p_point) { | 
					
						
							|  |  |  | 	target_position = p_point; | 
					
						
							| 
									
										
										
										
											2021-06-23 16:49:50 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (Engine::get_singleton()->is_editor_hint()) { | 
					
						
							|  |  |  | 		if (is_inside_tree()) { | 
					
						
							|  |  |  | 			_update_debug_shape_vertices(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	} else if (debug_instance.is_valid()) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 		_update_debug_shape(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-10 19:06:21 +02:00
										 |  |  | Vector3 RayCast3D::get_target_position() const { | 
					
						
							|  |  |  | 	return target_position; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::set_collision_mask(uint32_t p_mask) { | 
					
						
							| 
									
										
										
										
											2017-10-21 22:17:26 +02:00
										 |  |  | 	collision_mask = p_mask; | 
					
						
							| 
									
										
										
										
											2016-04-09 21:54:09 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | uint32_t RayCast3D::get_collision_mask() const { | 
					
						
							| 
									
										
										
										
											2017-10-21 22:17:26 +02:00
										 |  |  | 	return collision_mask; | 
					
						
							| 
									
										
										
										
											2016-04-09 21:54:09 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-11 16:01:38 -07:00
										 |  |  | void RayCast3D::set_collision_mask_value(int p_layer_number, bool p_value) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive."); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive."); | 
					
						
							| 
									
										
										
										
											2017-10-23 14:31:18 +02:00
										 |  |  | 	uint32_t mask = get_collision_mask(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (p_value) { | 
					
						
							| 
									
										
										
										
											2021-08-11 16:01:38 -07:00
										 |  |  | 		mask |= 1 << (p_layer_number - 1); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2021-08-11 16:01:38 -07:00
										 |  |  | 		mask &= ~(1 << (p_layer_number - 1)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-23 14:31:18 +02:00
										 |  |  | 	set_collision_mask(mask); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-11 16:01:38 -07:00
										 |  |  | bool RayCast3D::get_collision_mask_value(int p_layer_number) const { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive."); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive."); | 
					
						
							|  |  |  | 	return get_collision_mask() & (1 << (p_layer_number - 1)); | 
					
						
							| 
									
										
										
										
											2017-10-23 14:31:18 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | bool RayCast3D::is_colliding() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return collided; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | Object *RayCast3D::get_collider() const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (against.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
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ObjectDB::get_instance(against); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-14 10:09:35 +02:00
										 |  |  | RID RayCast3D::get_collider_rid() const { | 
					
						
							|  |  |  | 	return against_rid; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | int RayCast3D::get_collider_shape() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return against_shape; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | Vector3 RayCast3D::get_collision_point() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return collision_point; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | Vector3 RayCast3D::get_collision_normal() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return collision_normal; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-05 15:59:22 -06:00
										 |  |  | int RayCast3D::get_collision_face_index() const { | 
					
						
							|  |  |  | 	return collision_face_index; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::set_enabled(bool p_enabled) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	enabled = p_enabled; | 
					
						
							| 
									
										
										
										
											2021-06-23 16:49:50 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2019-08-21 15:27:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) { | 
					
						
							| 
									
										
										
										
											2018-04-11 09:28:14 +02:00
										 |  |  | 		set_physics_process_internal(p_enabled); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (!p_enabled) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		collided = false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (p_enabled) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 			_update_debug_shape(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 			_clear_debug_shape(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | bool RayCast3D::is_enabled() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return enabled; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::set_exclude_parent_body(bool p_exclude_parent_body) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (exclude_parent_body == p_exclude_parent_body) { | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	exclude_parent_body = p_exclude_parent_body; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!is_inside_tree()) { | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	if (Object::cast_to<CollisionObject3D>(get_parent())) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (exclude_parent_body) { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 			exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 			exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | bool RayCast3D::get_exclude_parent_body() const { | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 	return exclude_parent_body; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	switch (p_what) { | 
					
						
							| 
									
										
										
										
											2014-11-05 21:20:42 -03:00
										 |  |  | 		case NOTIFICATION_ENTER_TREE: { | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 			if (Engine::get_singleton()->is_editor_hint()) { | 
					
						
							|  |  |  | 				_update_debug_shape_vertices(); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-08-19 01:02:56 +02:00
										 |  |  | 			if (enabled && !Engine::get_singleton()->is_editor_hint()) { | 
					
						
							| 
									
										
										
										
											2018-04-11 09:28:14 +02:00
										 |  |  | 				set_physics_process_internal(true); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2018-04-11 09:28:14 +02:00
										 |  |  | 				set_physics_process_internal(false); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 15:52:01 -07:00
										 |  |  | 			if (get_tree()->is_debugging_collisions_hint()) { | 
					
						
							|  |  |  | 				_update_debug_shape(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 			if (Object::cast_to<CollisionObject3D>(get_parent())) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (exclude_parent_body) { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 					exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 					exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 21:20:42 -03:00
										 |  |  | 		case NOTIFICATION_EXIT_TREE: { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			if (enabled) { | 
					
						
							| 
									
										
										
										
											2018-04-11 09:28:14 +02:00
										 |  |  | 				set_physics_process_internal(false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 			if (debug_instance.is_valid()) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 				_clear_debug_shape(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 		case NOTIFICATION_VISIBILITY_CHANGED: { | 
					
						
							|  |  |  | 			if (is_inside_tree() && debug_instance.is_valid()) { | 
					
						
							|  |  |  | 				RenderingServer::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-11 09:28:14 +02:00
										 |  |  | 		case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (!enabled) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 			bool prev_collision_state = collided; | 
					
						
							| 
									
										
										
										
											2016-08-09 19:52:15 +02:00
										 |  |  | 			_update_raycast_state(); | 
					
						
							| 
									
										
										
										
											2024-04-17 11:21:53 -03:00
										 |  |  | 			if (get_tree()->is_debugging_collisions_hint()) { | 
					
						
							|  |  |  | 				if (prev_collision_state != collided) { | 
					
						
							|  |  |  | 					_update_debug_shape_material(true); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 				if (is_inside_tree() && debug_instance.is_valid()) { | 
					
						
							|  |  |  | 					RenderingServer::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-08-09 19:52:15 +02:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::_update_raycast_state() { | 
					
						
							| 
									
										
										
										
											2020-04-18 11:00:51 +02:00
										 |  |  | 	Ref<World3D> w3d = get_world_3d(); | 
					
						
							| 
									
										
										
										
											2016-08-09 19:52:15 +02:00
										 |  |  | 	ERR_FAIL_COND(w3d.is_null()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-27 15:21:27 -03:00
										 |  |  | 	PhysicsDirectSpaceState3D *dss = PhysicsServer3D::get_singleton()->space_get_direct_state(w3d->get_space()); | 
					
						
							| 
									
										
										
										
											2023-06-06 14:59:54 +02:00
										 |  |  | 	ERR_FAIL_NULL(dss); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 01:08:21 -04:00
										 |  |  | 	Transform3D gt = get_global_transform(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-10 19:06:21 +02:00
										 |  |  | 	Vector3 to = target_position; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (to == Vector3()) { | 
					
						
							| 
									
										
										
										
											2016-08-09 19:52:15 +02:00
										 |  |  | 		to = Vector3(0, 0.01, 0); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-01 18:00:58 -07:00
										 |  |  | 	PhysicsDirectSpaceState3D::RayParameters ray_params; | 
					
						
							|  |  |  | 	ray_params.from = gt.get_origin(); | 
					
						
							|  |  |  | 	ray_params.to = gt.xform(to); | 
					
						
							|  |  |  | 	ray_params.exclude = exclude; | 
					
						
							|  |  |  | 	ray_params.collision_mask = collision_mask; | 
					
						
							|  |  |  | 	ray_params.collide_with_bodies = collide_with_bodies; | 
					
						
							|  |  |  | 	ray_params.collide_with_areas = collide_with_areas; | 
					
						
							| 
									
										
										
										
											2021-11-10 15:57:11 -07:00
										 |  |  | 	ray_params.hit_from_inside = hit_from_inside; | 
					
						
							| 
									
										
										
										
											2023-07-11 13:02:13 +02:00
										 |  |  | 	ray_params.hit_back_faces = hit_back_faces; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-01 18:00:58 -07:00
										 |  |  | 	PhysicsDirectSpaceState3D::RayResult rr; | 
					
						
							|  |  |  | 	if (dss->intersect_ray(ray_params, rr)) { | 
					
						
							| 
									
										
										
										
											2016-08-09 19:52:15 +02:00
										 |  |  | 		collided = true; | 
					
						
							|  |  |  | 		against = rr.collider_id; | 
					
						
							| 
									
										
										
										
											2022-08-14 10:09:35 +02:00
										 |  |  | 		against_rid = rr.rid; | 
					
						
							| 
									
										
										
										
											2016-08-09 19:52:15 +02:00
										 |  |  | 		collision_point = rr.position; | 
					
						
							|  |  |  | 		collision_normal = rr.normal; | 
					
						
							| 
									
										
										
										
											2023-03-05 15:59:22 -06:00
										 |  |  | 		collision_face_index = rr.face_index; | 
					
						
							| 
									
										
										
										
											2016-08-09 19:52:15 +02:00
										 |  |  | 		against_shape = rr.shape; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		collided = false; | 
					
						
							| 
									
										
										
										
											2020-02-12 14:24:06 -03:00
										 |  |  | 		against = ObjectID(); | 
					
						
							| 
									
										
										
										
											2022-08-14 10:09:35 +02:00
										 |  |  | 		against_rid = RID(); | 
					
						
							| 
									
										
										
										
											2018-01-12 12:31:02 +01:00
										 |  |  | 		against_shape = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::force_raycast_update() { | 
					
						
							| 
									
										
										
										
											2016-08-09 19:52:15 +02:00
										 |  |  | 	_update_raycast_state(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::add_exception_rid(const RID &p_rid) { | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | 	exclude.insert(p_rid); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-28 15:06:54 +01:00
										 |  |  | void RayCast3D::add_exception(const CollisionObject3D *p_node) { | 
					
						
							|  |  |  | 	ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject3D."); | 
					
						
							|  |  |  | 	add_exception_rid(p_node->get_rid()); | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::remove_exception_rid(const RID &p_rid) { | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | 	exclude.erase(p_rid); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-28 15:06:54 +01:00
										 |  |  | void RayCast3D::remove_exception(const CollisionObject3D *p_node) { | 
					
						
							|  |  |  | 	ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject3D."); | 
					
						
							|  |  |  | 	remove_exception_rid(p_node->get_rid()); | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::clear_exceptions() { | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | 	exclude.clear(); | 
					
						
							| 
									
										
										
										
											2022-02-08 16:31:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (exclude_parent_body && is_inside_tree()) { | 
					
						
							|  |  |  | 		CollisionObject3D *parent = Object::cast_to<CollisionObject3D>(get_parent()); | 
					
						
							|  |  |  | 		if (parent) { | 
					
						
							|  |  |  | 			exclude.insert(parent->get_rid()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 15:57:11 -07:00
										 |  |  | void RayCast3D::set_collide_with_areas(bool p_enabled) { | 
					
						
							|  |  |  | 	collide_with_areas = p_enabled; | 
					
						
							| 
									
										
										
										
											2018-08-21 15:30:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | bool RayCast3D::is_collide_with_areas_enabled() const { | 
					
						
							| 
									
										
										
										
											2018-08-21 15:30:41 -03:00
										 |  |  | 	return collide_with_areas; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 15:57:11 -07:00
										 |  |  | void RayCast3D::set_collide_with_bodies(bool p_enabled) { | 
					
						
							|  |  |  | 	collide_with_bodies = p_enabled; | 
					
						
							| 
									
										
										
										
											2018-08-21 15:30:41 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | bool RayCast3D::is_collide_with_bodies_enabled() const { | 
					
						
							| 
									
										
										
										
											2018-08-21 15:30:41 -03:00
										 |  |  | 	return collide_with_bodies; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 15:57:11 -07:00
										 |  |  | void RayCast3D::set_hit_from_inside(bool p_enabled) { | 
					
						
							|  |  |  | 	hit_from_inside = p_enabled; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RayCast3D::is_hit_from_inside_enabled() const { | 
					
						
							|  |  |  | 	return hit_from_inside; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 13:02:13 +02:00
										 |  |  | void RayCast3D::set_hit_back_faces(bool p_enabled) { | 
					
						
							|  |  |  | 	hit_back_faces = p_enabled; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool RayCast3D::is_hit_back_faces_enabled() const { | 
					
						
							|  |  |  | 	return hit_back_faces; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast3D::set_enabled); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast3D::is_enabled); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-10 19:06:21 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_target_position", "local_point"), &RayCast3D::set_target_position); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_target_position"), &RayCast3D::get_target_position); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("is_colliding"), &RayCast3D::is_colliding); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast3D::force_raycast_update); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_collider"), &RayCast3D::get_collider); | 
					
						
							| 
									
										
										
										
											2022-08-14 10:09:35 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_collider_rid"), &RayCast3D::get_collider_rid); | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_collider_shape"), &RayCast3D::get_collider_shape); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_collision_point"), &RayCast3D::get_collision_point); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_collision_normal"), &RayCast3D::get_collision_normal); | 
					
						
							| 
									
										
										
										
											2023-03-05 15:59:22 -06:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_collision_face_index"), &RayCast3D::get_collision_face_index); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("add_exception_rid", "rid"), &RayCast3D::add_exception_rid); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("add_exception", "node"), &RayCast3D::add_exception); | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("remove_exception_rid", "rid"), &RayCast3D::remove_exception_rid); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("remove_exception", "node"), &RayCast3D::remove_exception); | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("clear_exceptions"), &RayCast3D::clear_exceptions); | 
					
						
							| 
									
										
										
										
											2015-01-03 16:52:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &RayCast3D::set_collision_mask); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_collision_mask"), &RayCast3D::get_collision_mask); | 
					
						
							| 
									
										
										
										
											2016-04-09 21:54:09 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-11 16:01:38 -07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &RayCast3D::set_collision_mask_value); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &RayCast3D::get_collision_mask_value); | 
					
						
							| 
									
										
										
										
											2017-10-23 14:31:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_exclude_parent_body", "mask"), &RayCast3D::set_exclude_parent_body); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_exclude_parent_body"), &RayCast3D::get_exclude_parent_body); | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &RayCast3D::set_collide_with_areas); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &RayCast3D::is_collide_with_areas_enabled); | 
					
						
							| 
									
										
										
										
											2018-08-21 15:30:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast3D::set_collide_with_bodies); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast3D::is_collide_with_bodies_enabled); | 
					
						
							| 
									
										
										
										
											2018-08-21 15:30:41 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 15:57:11 -07:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_hit_from_inside", "enable"), &RayCast3D::set_hit_from_inside); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_hit_from_inside_enabled"), &RayCast3D::is_hit_from_inside_enabled); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-11 13:02:13 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_hit_back_faces", "enable"), &RayCast3D::set_hit_back_faces); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_hit_back_faces_enabled"), &RayCast3D::is_hit_back_faces_enabled); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_debug_shape_custom_color", "debug_shape_custom_color"), &RayCast3D::set_debug_shape_custom_color); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_debug_shape_custom_color"), &RayCast3D::get_debug_shape_custom_color); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_debug_shape_thickness", "debug_shape_thickness"), &RayCast3D::set_debug_shape_thickness); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_debug_shape_thickness"), &RayCast3D::get_debug_shape_thickness); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 01:11:37 +01:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); | 
					
						
							| 
									
										
										
										
											2017-11-30 04:26:13 +01:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body"); | 
					
						
							| 
									
										
										
										
											2021-12-02 18:09:19 -06:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position", PROPERTY_HINT_NONE, "suffix:m"), "set_target_position", "get_target_position"); | 
					
						
							| 
									
										
										
										
											2017-10-21 22:17:26 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); | 
					
						
							| 
									
										
										
										
											2021-11-10 15:57:11 -07:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hit_from_inside"), "set_hit_from_inside", "is_hit_from_inside_enabled"); | 
					
						
							| 
									
										
										
										
											2023-07-11 13:02:13 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hit_back_faces"), "set_hit_back_faces", "is_hit_back_faces_enabled"); | 
					
						
							| 
									
										
										
										
											2018-08-21 15:30:41 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ADD_GROUP("Collide With", "collide_with"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ADD_GROUP("Debug Shape", "debug_shape"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_shape_custom_color"), "set_debug_shape_custom_color", "get_debug_shape_custom_color"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_shape_thickness", PROPERTY_HINT_RANGE, "1,5"), "set_debug_shape_thickness", "get_debug_shape_thickness"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-11 09:47:42 +05:30
										 |  |  | int RayCast3D::get_debug_shape_thickness() const { | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 	return debug_shape_thickness; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RayCast3D::_update_debug_shape_vertices() { | 
					
						
							|  |  |  | 	debug_shape_vertices.clear(); | 
					
						
							|  |  |  | 	debug_line_vertices.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (target_position == Vector3()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	debug_line_vertices.push_back(Vector3()); | 
					
						
							|  |  |  | 	debug_line_vertices.push_back(target_position); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (debug_shape_thickness > 1) { | 
					
						
							|  |  |  | 		float scale_factor = 100.0; | 
					
						
							|  |  |  | 		Vector3 dir = Vector3(target_position).normalized(); | 
					
						
							|  |  |  | 		// Draw truncated pyramid
 | 
					
						
							|  |  |  | 		Vector3 normal = (fabs(dir.x) + fabs(dir.y) > CMP_EPSILON) ? Vector3(-dir.y, dir.x, 0).normalized() : Vector3(0, -dir.z, dir.y).normalized(); | 
					
						
							|  |  |  | 		normal *= debug_shape_thickness / scale_factor; | 
					
						
							|  |  |  | 		int vertices_strip_order[14] = { 4, 5, 0, 1, 2, 5, 6, 4, 7, 0, 3, 2, 7, 6 }; | 
					
						
							|  |  |  | 		for (int v = 0; v < 14; v++) { | 
					
						
							|  |  |  | 			Vector3 vertex = vertices_strip_order[v] < 4 ? normal : normal / 3.0 + target_position; | 
					
						
							|  |  |  | 			debug_shape_vertices.push_back(vertex.rotated(dir, Math_PI * (0.5 * (vertices_strip_order[v] % 4) + 0.25))); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-11 09:47:42 +05:30
										 |  |  | void RayCast3D::set_debug_shape_thickness(const int p_debug_shape_thickness) { | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 	debug_shape_thickness = p_debug_shape_thickness; | 
					
						
							| 
									
										
										
										
											2021-06-23 16:49:50 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (Engine::get_singleton()->is_editor_hint()) { | 
					
						
							|  |  |  | 		if (is_inside_tree()) { | 
					
						
							|  |  |  | 			_update_debug_shape_vertices(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	} else if (debug_instance.is_valid()) { | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 		_update_debug_shape(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const Vector<Vector3> &RayCast3D::get_debug_shape_vertices() const { | 
					
						
							|  |  |  | 	return debug_shape_vertices; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | const Vector<Vector3> &RayCast3D::get_debug_line_vertices() const { | 
					
						
							|  |  |  | 	return debug_line_vertices; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RayCast3D::set_debug_shape_custom_color(const Color &p_color) { | 
					
						
							|  |  |  | 	debug_shape_custom_color = p_color; | 
					
						
							|  |  |  | 	if (debug_material.is_valid()) { | 
					
						
							|  |  |  | 		_update_debug_shape_material(); | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<StandardMaterial3D> RayCast3D::get_debug_material() { | 
					
						
							|  |  |  | 	_update_debug_shape_material(); | 
					
						
							|  |  |  | 	return debug_material; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const Color &RayCast3D::get_debug_shape_custom_color() const { | 
					
						
							|  |  |  | 	return debug_shape_custom_color; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RayCast3D::_create_debug_shape() { | 
					
						
							|  |  |  | 	_update_debug_shape_material(); | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	if (!debug_instance.is_valid()) { | 
					
						
							|  |  |  | 		debug_instance = RenderingServer::get_singleton()->instance_create(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	if (debug_mesh.is_null()) { | 
					
						
							| 
									
										
										
										
											2024-06-09 15:21:41 -05:00
										 |  |  | 		debug_mesh.instantiate(); | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | void RayCast3D::_update_debug_shape_material(bool p_check_collision) { | 
					
						
							| 
									
										
										
										
											2024-08-25 14:15:10 +02:00
										 |  |  | 	if (debug_material.is_null()) { | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 		Ref<StandardMaterial3D> material = memnew(StandardMaterial3D); | 
					
						
							|  |  |  | 		debug_material = material; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); | 
					
						
							| 
									
										
										
										
											2023-09-27 00:45:57 +02:00
										 |  |  | 		material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); | 
					
						
							| 
									
										
										
										
											2021-06-19 05:05:58 +02:00
										 |  |  | 		// Use double-sided rendering so that the RayCast can be seen if the camera is inside.
 | 
					
						
							|  |  |  | 		material->set_cull_mode(BaseMaterial3D::CULL_DISABLED); | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 		material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Color color = debug_shape_custom_color; | 
					
						
							|  |  |  | 	if (color == Color(0.0, 0.0, 0.0)) { | 
					
						
							|  |  |  | 		// Use the default debug shape color defined in the Project Settings.
 | 
					
						
							|  |  |  | 		color = get_tree()->get_debug_collisions_color(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-24 19:41:19 -07:00
										 |  |  | 	if (p_check_collision && collided) { | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 		if ((color.get_h() < 0.055 || color.get_h() > 0.945) && color.get_s() > 0.5 && color.get_v() > 0.5) { | 
					
						
							| 
									
										
										
										
											2021-03-12 19:05:16 +05:30
										 |  |  | 			// If base color is already quite reddish, highlight collision with green color
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 			color = Color(0.0, 1.0, 0.0, color.a); | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2021-03-12 19:05:16 +05:30
										 |  |  | 			// Else, highlight collision with red color
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 			color = Color(1.0, 0, 0, color.a); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Ref<StandardMaterial3D> material = static_cast<Ref<StandardMaterial3D>>(debug_material); | 
					
						
							|  |  |  | 	material->set_albedo(color); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::_update_debug_shape() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!enabled) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	if (!debug_instance.is_valid()) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 		_create_debug_shape(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	if (!debug_instance.is_valid() || debug_mesh.is_null()) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 	_update_debug_shape_vertices(); | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	debug_mesh->clear_surfaces(); | 
					
						
							| 
									
										
										
										
											2021-01-14 15:52:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 	Array a; | 
					
						
							|  |  |  | 	a.resize(Mesh::ARRAY_MAX); | 
					
						
							| 
									
										
										
										
											2021-01-14 15:52:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 	uint32_t flags = 0; | 
					
						
							|  |  |  | 	int surface_count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!debug_line_vertices.is_empty()) { | 
					
						
							|  |  |  | 		a[Mesh::ARRAY_VERTEX] = debug_line_vertices; | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 		debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); | 
					
						
							|  |  |  | 		debug_mesh->surface_set_material(surface_count, debug_material); | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 		++surface_count; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-01-14 15:52:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 	if (!debug_shape_vertices.is_empty()) { | 
					
						
							|  |  |  | 		a[Mesh::ARRAY_VERTEX] = debug_shape_vertices; | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 		debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLE_STRIP, a, Array(), Dictionary(), flags); | 
					
						
							|  |  |  | 		debug_mesh->surface_set_material(surface_count, debug_material); | 
					
						
							| 
									
										
										
										
											2021-02-28 22:15:52 +01:00
										 |  |  | 		++surface_count; | 
					
						
							| 
									
										
										
										
											2021-01-14 15:52:01 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	RenderingServer::get_singleton()->instance_set_base(debug_instance, debug_mesh->get_rid()); | 
					
						
							|  |  |  | 	if (is_inside_tree()) { | 
					
						
							|  |  |  | 		RenderingServer::get_singleton()->instance_set_scenario(debug_instance, get_world_3d()->get_scenario()); | 
					
						
							|  |  |  | 		RenderingServer::get_singleton()->instance_set_visible(debug_instance, is_visible_in_tree()); | 
					
						
							|  |  |  | 		RenderingServer::get_singleton()->instance_set_transform(debug_instance, get_global_transform()); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | void RayCast3D::_clear_debug_shape() { | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	ERR_FAIL_NULL(RenderingServer::get_singleton()); | 
					
						
							|  |  |  | 	if (debug_instance.is_valid()) { | 
					
						
							|  |  |  | 		RenderingServer::get_singleton()->free(debug_instance); | 
					
						
							|  |  |  | 		debug_instance = RID(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-10-01 00:16:42 +02:00
										 |  |  | 	if (debug_mesh.is_valid()) { | 
					
						
							|  |  |  | 		RenderingServer::get_singleton()->free(debug_mesh->get_rid()); | 
					
						
							|  |  |  | 		debug_mesh = Ref<ArrayMesh>(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-21 17:09:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | RayCast3D::RayCast3D() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |