| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  collision_object_sw.cpp                                              */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2019-01-01 12:53:14 +01:00
										 |  |  | /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "collision_object_sw.h"
 | 
					
						
							| 
									
										
										
										
											2017-09-03 14:53:17 -03:00
										 |  |  | #include "servers/physics/physics_server_sw.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "space_sw.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-24 10:38:31 +01:00
										 |  |  | void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform, bool p_disabled) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Shape s; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	s.shape = p_shape; | 
					
						
							|  |  |  | 	s.xform = p_transform; | 
					
						
							|  |  |  | 	s.xform_inv = s.xform.affine_inverse(); | 
					
						
							|  |  |  | 	s.bpid = 0; //needs update
 | 
					
						
							| 
									
										
										
										
											2019-03-24 10:38:31 +01:00
										 |  |  | 	s.disabled = p_disabled; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	shapes.push_back(s); | 
					
						
							|  |  |  | 	p_shape->add_owner(this); | 
					
						
							| 
									
										
										
										
											2017-09-03 14:53:17 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!pending_shape_update_list.in_list()) { | 
					
						
							|  |  |  | 		PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	//_update_shapes();
 | 
					
						
							|  |  |  | 	//_shapes_changed();
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void CollisionObjectSW::set_shape(int p_index, ShapeSW *p_shape) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_INDEX(p_index, shapes.size()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	shapes[p_index].shape->remove_owner(this); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	shapes.write[p_index].shape = p_shape; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	p_shape->add_owner(this); | 
					
						
							| 
									
										
										
										
											2017-09-03 14:53:17 -03:00
										 |  |  | 	if (!pending_shape_update_list.in_list()) { | 
					
						
							|  |  |  | 		PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	//_update_shapes();
 | 
					
						
							|  |  |  | 	//_shapes_changed();
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_transform) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_INDEX(p_index, shapes.size()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	shapes.write[p_index].xform = p_transform; | 
					
						
							|  |  |  | 	shapes.write[p_index].xform_inv = p_transform.affine_inverse(); | 
					
						
							| 
									
										
										
										
											2017-09-03 14:53:17 -03:00
										 |  |  | 	if (!pending_shape_update_list.in_list()) { | 
					
						
							|  |  |  | 		PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	//_update_shapes();
 | 
					
						
							|  |  |  | 	//_shapes_changed();
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CollisionObjectSW::remove_shape(ShapeSW *p_shape) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//remove a shape, all the times it appears
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < shapes.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (shapes[i].shape == p_shape) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			remove_shape(i); | 
					
						
							|  |  |  | 			i--; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void CollisionObjectSW::remove_shape(int p_index) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	//remove anything from shape to be erased to end, so subindices don't change
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_INDEX(p_index, shapes.size()); | 
					
						
							|  |  |  | 	for (int i = p_index; i < shapes.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (shapes[i].bpid == 0) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		//should never get here with a null owner
 | 
					
						
							|  |  |  | 		space->get_broadphase()->remove(shapes[i].bpid); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		shapes.write[i].bpid = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	shapes[p_index].shape->remove_owner(this); | 
					
						
							|  |  |  | 	shapes.remove(p_index); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-03 14:53:17 -03:00
										 |  |  | 	if (!pending_shape_update_list.in_list()) { | 
					
						
							|  |  |  | 		PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	//_update_shapes();
 | 
					
						
							|  |  |  | 	//_shapes_changed();
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CollisionObjectSW::_set_static(bool p_static) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (_static == p_static) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	_static = p_static; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!space) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < get_shape_count(); i++) { | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		const Shape &s = shapes[i]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (s.bpid > 0) { | 
					
						
							|  |  |  | 			space->get_broadphase()->set_static(s.bpid, _static); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CollisionObjectSW::_unregister_shapes() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < shapes.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		Shape &s = shapes.write[i]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (s.bpid > 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			space->get_broadphase()->remove(s.bpid); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			s.bpid = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CollisionObjectSW::_update_shapes() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!space) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < shapes.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		Shape &s = shapes.write[i]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (s.bpid == 0) { | 
					
						
							|  |  |  | 			s.bpid = space->get_broadphase()->create(this, i); | 
					
						
							|  |  |  | 			space->get_broadphase()->set_static(s.bpid, _static); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		//not quite correct, should compute the next matrix..
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | 		AABB shape_aabb = s.shape->get_aabb(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		Transform xform = transform * s.xform; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		shape_aabb = xform.xform(shape_aabb); | 
					
						
							|  |  |  | 		s.aabb_cache = shape_aabb; | 
					
						
							|  |  |  | 		s.aabb_cache = s.aabb_cache.grow((s.aabb_cache.size.x + s.aabb_cache.size.y) * 0.5 * 0.05); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-31 14:39:25 +00:00
										 |  |  | 		Vector3 scale = xform.get_basis().get_scale(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		s.area_cache = s.shape->get_area() * scale.x * scale.y * scale.z; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		space->get_broadphase()->move(s.bpid, s.aabb_cache); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void CollisionObjectSW::_update_shapes_with_motion(const Vector3 &p_motion) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!space) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = 0; i < shapes.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 		Shape &s = shapes.write[i]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (s.bpid == 0) { | 
					
						
							|  |  |  | 			s.bpid = space->get_broadphase()->create(this, i); | 
					
						
							|  |  |  | 			space->get_broadphase()->set_static(s.bpid, _static); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		//not quite correct, should compute the next matrix..
 | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | 		AABB shape_aabb = s.shape->get_aabb(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		Transform xform = transform * s.xform; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		shape_aabb = xform.xform(shape_aabb); | 
					
						
							| 
									
										
										
										
											2017-11-16 21:09:00 -05:00
										 |  |  | 		shape_aabb = shape_aabb.merge(AABB(shape_aabb.position + p_motion, shape_aabb.size)); //use motion
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		s.aabb_cache = shape_aabb; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		space->get_broadphase()->move(s.bpid, shape_aabb); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CollisionObjectSW::_set_space(SpaceSW *p_space) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (space) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		space->remove_object(this); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < shapes.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 			Shape &s = shapes.write[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			if (s.bpid) { | 
					
						
							|  |  |  | 				space->get_broadphase()->remove(s.bpid); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				s.bpid = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	space = p_space; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (space) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		space->add_object(this); | 
					
						
							|  |  |  | 		_update_shapes(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CollisionObjectSW::_shape_changed() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_update_shapes(); | 
					
						
							|  |  |  | 	_shapes_changed(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-06 21:36:34 +01:00
										 |  |  | CollisionObjectSW::CollisionObjectSW(Type p_type) : | 
					
						
							|  |  |  | 		pending_shape_update_list(this) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	_static = true; | 
					
						
							|  |  |  | 	type = p_type; | 
					
						
							|  |  |  | 	space = NULL; | 
					
						
							|  |  |  | 	instance_id = 0; | 
					
						
							| 
									
										
										
										
											2017-06-13 22:45:01 +07:00
										 |  |  | 	collision_layer = 1; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	collision_mask = 1; | 
					
						
							|  |  |  | 	ray_pickable = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |