mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 05:31:01 +00:00 
			
		
		
		
	Merge pull request #12756 from Stratos695/master
Allowing double-axis lock in RigidBody & KinematicBody (Fixes #12500)
This commit is contained in:
		
						commit
						25b36f18d3
					
				
					 12 changed files with 155 additions and 109 deletions
				
			
		|  | @ -723,15 +723,15 @@ void BulletPhysicsServer::body_set_axis_velocity(RID p_body, const Vector3 &p_ax | ||||||
| 	body->set_linear_velocity(v); | 	body->set_linear_velocity(v); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void BulletPhysicsServer::body_set_axis_lock(RID p_body, PhysicsServer::BodyAxisLock p_lock) { | void BulletPhysicsServer::body_set_axis_lock(RID p_body, int axis, bool p_lock) { | ||||||
| 	RigidBodyBullet *body = rigid_body_owner.get(p_body); | 	RigidBodyBullet *body = rigid_body_owner.get(p_body); | ||||||
| 	ERR_FAIL_COND(!body); | 	ERR_FAIL_COND(!body); | ||||||
| 	body->set_axis_lock(p_lock); | 	body->set_axis_lock(axis, p_lock); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PhysicsServer::BodyAxisLock BulletPhysicsServer::body_get_axis_lock(RID p_body) const { | bool BulletPhysicsServer::body_get_axis_lock(RID p_body) const { | ||||||
| 	const RigidBodyBullet *body = rigid_body_owner.get(p_body); | 	const RigidBodyBullet *body = rigid_body_owner.get(p_body); | ||||||
| 	ERR_FAIL_COND_V(!body, BODY_AXIS_LOCK_DISABLED); | 	ERR_FAIL_COND_V(!body, 0); | ||||||
| 	return body->get_axis_lock(); | 	return body->get_axis_lock(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -226,8 +226,8 @@ public: | ||||||
| 	virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse); | 	virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse); | ||||||
| 	virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity); | 	virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity); | ||||||
| 
 | 
 | ||||||
| 	virtual void body_set_axis_lock(RID p_body, BodyAxisLock p_lock); | 	virtual void body_set_axis_lock(RID p_body, int axis, bool p_lock); | ||||||
| 	virtual BodyAxisLock body_get_axis_lock(RID p_body) const; | 	virtual bool body_get_axis_lock(RID p_body) const; | ||||||
| 
 | 
 | ||||||
| 	virtual void body_add_collision_exception(RID p_body, RID p_body_b); | 	virtual void body_add_collision_exception(RID p_body, RID p_body_b); | ||||||
| 	virtual void body_remove_collision_exception(RID p_body, RID p_body_b); | 	virtual void body_remove_collision_exception(RID p_body, RID p_body_b); | ||||||
|  |  | ||||||
|  | @ -277,7 +277,7 @@ RigidBodyBullet::RigidBodyBullet() : | ||||||
| 	setupBulletCollisionObject(btBody); | 	setupBulletCollisionObject(btBody); | ||||||
| 
 | 
 | ||||||
| 	set_mode(PhysicsServer::BODY_MODE_RIGID); | 	set_mode(PhysicsServer::BODY_MODE_RIGID); | ||||||
| 	set_axis_lock(PhysicsServer::BODY_AXIS_LOCK_DISABLED); | 	set_axis_lock(0, locked_axis[0]); | ||||||
| 
 | 
 | ||||||
| 	areasWhereIam.resize(maxAreasWhereIam); | 	areasWhereIam.resize(maxAreasWhereIam); | ||||||
| 	for (int i = areasWhereIam.size() - 1; 0 <= i; --i) { | 	for (int i = areasWhereIam.size() - 1; 0 <= i; --i) { | ||||||
|  | @ -498,25 +498,25 @@ void RigidBodyBullet::set_mode(PhysicsServer::BodyMode p_mode) { | ||||||
| 	switch (p_mode) { | 	switch (p_mode) { | ||||||
| 		case PhysicsServer::BODY_MODE_KINEMATIC: | 		case PhysicsServer::BODY_MODE_KINEMATIC: | ||||||
| 			mode = PhysicsServer::BODY_MODE_KINEMATIC; | 			mode = PhysicsServer::BODY_MODE_KINEMATIC; | ||||||
| 			set_axis_lock(axis_lock); // Reload axis lock
 | 			set_axis_lock(0, locked_axis[0]); // Reload axis lock
 | ||||||
| 			_internal_set_mass(0); | 			_internal_set_mass(0); | ||||||
| 			init_kinematic_utilities(); | 			init_kinematic_utilities(); | ||||||
| 			break; | 			break; | ||||||
| 		case PhysicsServer::BODY_MODE_STATIC: | 		case PhysicsServer::BODY_MODE_STATIC: | ||||||
| 			mode = PhysicsServer::BODY_MODE_STATIC; | 			mode = PhysicsServer::BODY_MODE_STATIC; | ||||||
| 			set_axis_lock(axis_lock); // Reload axis lock
 | 			set_axis_lock(0, locked_axis[0]); // Reload axis lock
 | ||||||
| 			_internal_set_mass(0); | 			_internal_set_mass(0); | ||||||
| 			break; | 			break; | ||||||
| 		case PhysicsServer::BODY_MODE_RIGID: { | 		case PhysicsServer::BODY_MODE_RIGID: { | ||||||
| 			mode = PhysicsServer::BODY_MODE_RIGID; | 			mode = PhysicsServer::BODY_MODE_RIGID; | ||||||
| 			set_axis_lock(axis_lock); // Reload axis lock
 | 			set_axis_lock(0, locked_axis[0]); // Reload axis lock
 | ||||||
| 			_internal_set_mass(0 == mass ? 1 : mass); | 			_internal_set_mass(0 == mass ? 1 : mass); | ||||||
| 			scratch_space_override_modificator(); | 			scratch_space_override_modificator(); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		case PhysicsServer::BODY_MODE_CHARACTER: { | 		case PhysicsServer::BODY_MODE_CHARACTER: { | ||||||
| 			mode = PhysicsServer::BODY_MODE_CHARACTER; | 			mode = PhysicsServer::BODY_MODE_CHARACTER; | ||||||
| 			set_axis_lock(axis_lock); // Reload axis lock
 | 			set_axis_lock(0, locked_axis[0]); // Reload axis lock
 | ||||||
| 			_internal_set_mass(0 == mass ? 1 : mass); | 			_internal_set_mass(0 == mass ? 1 : mass); | ||||||
| 			scratch_space_override_modificator(); | 			scratch_space_override_modificator(); | ||||||
| 			break; | 			break; | ||||||
|  | @ -655,22 +655,14 @@ Vector3 RigidBodyBullet::get_applied_torque() const { | ||||||
| 	return gTotTorq; | 	return gTotTorq; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RigidBodyBullet::set_axis_lock(PhysicsServer::BodyAxisLock p_lock) { | void RigidBodyBullet::set_axis_lock(int axis, bool p_lock) { | ||||||
| 	axis_lock = p_lock; | 	locked_axis[axis] = p_lock; | ||||||
| 
 | 
 | ||||||
| 	if (PhysicsServer::BODY_AXIS_LOCK_DISABLED == axis_lock) { | 	btBody->setLinearFactor(btVector3(locked_axis[0] ? 0 : 1., locked_axis[1] ? 0 : 1., locked_axis[2] ? 0 : 1.)); | ||||||
| 		btBody->setLinearFactor(btVector3(1., 1., 1.)); | 	if (locked_axis[0] || locked_axis[1] || locked_axis[2]) | ||||||
|  | 		btBody->setAngularFactor(btVector3(locked_axis[0] ? 1. : 0, locked_axis[1] ? 1. : 0, locked_axis[2] ? 1. : 0)); | ||||||
|  | 	else | ||||||
| 		btBody->setAngularFactor(btVector3(1., 1., 1.)); | 		btBody->setAngularFactor(btVector3(1., 1., 1.)); | ||||||
| 	} else if (PhysicsServer::BODY_AXIS_LOCK_X == axis_lock) { |  | ||||||
| 		btBody->setLinearFactor(btVector3(0., 1., 1.)); |  | ||||||
| 		btBody->setAngularFactor(btVector3(1., 0., 0.)); |  | ||||||
| 	} else if (PhysicsServer::BODY_AXIS_LOCK_Y == axis_lock) { |  | ||||||
| 		btBody->setLinearFactor(btVector3(1., 0., 1.)); |  | ||||||
| 		btBody->setAngularFactor(btVector3(0., 1., 0.)); |  | ||||||
| 	} else if (PhysicsServer::BODY_AXIS_LOCK_Z == axis_lock) { |  | ||||||
| 		btBody->setLinearFactor(btVector3(1., 1., 0.)); |  | ||||||
| 		btBody->setAngularFactor(btVector3(0., 0., 1.)); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if (PhysicsServer::BODY_MODE_CHARACTER == mode) { | 	if (PhysicsServer::BODY_MODE_CHARACTER == mode) { | ||||||
| 		/// When character lock angular
 | 		/// When character lock angular
 | ||||||
|  | @ -678,17 +670,8 @@ void RigidBodyBullet::set_axis_lock(PhysicsServer::BodyAxisLock p_lock) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PhysicsServer::BodyAxisLock RigidBodyBullet::get_axis_lock() const { | bool RigidBodyBullet::get_axis_lock() const { | ||||||
| 	btVector3 vec = btBody->getLinearFactor(); | 	return locked_axis; | ||||||
| 	if (0. == vec.x()) { |  | ||||||
| 		return PhysicsServer::BODY_AXIS_LOCK_X; |  | ||||||
| 	} else if (0. == vec.y()) { |  | ||||||
| 		return PhysicsServer::BODY_AXIS_LOCK_Y; |  | ||||||
| 	} else if (0. == vec.z()) { |  | ||||||
| 		return PhysicsServer::BODY_AXIS_LOCK_Z; |  | ||||||
| 	} else { |  | ||||||
| 		return PhysicsServer::BODY_AXIS_LOCK_DISABLED; |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) { | void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) { | ||||||
|  |  | ||||||
|  | @ -184,7 +184,7 @@ private: | ||||||
| 	KinematicUtilities *kinematic_utilities; | 	KinematicUtilities *kinematic_utilities; | ||||||
| 
 | 
 | ||||||
| 	PhysicsServer::BodyMode mode; | 	PhysicsServer::BodyMode mode; | ||||||
| 	PhysicsServer::BodyAxisLock axis_lock; | 	bool locked_axis[3] = { false, false, false }; | ||||||
| 	GodotMotionState *godotMotionState; | 	GodotMotionState *godotMotionState; | ||||||
| 	btRigidBody *btBody; | 	btRigidBody *btBody; | ||||||
| 	real_t mass; | 	real_t mass; | ||||||
|  | @ -269,8 +269,8 @@ public: | ||||||
| 	void set_applied_torque(const Vector3 &p_torque); | 	void set_applied_torque(const Vector3 &p_torque); | ||||||
| 	Vector3 get_applied_torque() const; | 	Vector3 get_applied_torque() const; | ||||||
| 
 | 
 | ||||||
| 	void set_axis_lock(PhysicsServer::BodyAxisLock p_lock); | 	void set_axis_lock(int axis, bool p_lock); | ||||||
| 	PhysicsServer::BodyAxisLock get_axis_lock() const; | 	bool get_axis_lock() const; | ||||||
| 
 | 
 | ||||||
| 	/// Doc:
 | 	/// Doc:
 | ||||||
| 	/// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Anti_tunneling_by_Motion_Clamping
 | 	/// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Anti_tunneling_by_Motion_Clamping
 | ||||||
|  |  | ||||||
|  | @ -734,15 +734,31 @@ bool RigidBody::is_contact_monitor_enabled() const { | ||||||
| 	return contact_monitor != NULL; | 	return contact_monitor != NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RigidBody::set_axis_lock(AxisLock p_lock) { | void RigidBody::set_axis_lock_x(bool p_lock) { | ||||||
| 
 | 	RigidBody::locked_axis[0] = p_lock; | ||||||
| 	axis_lock = p_lock; | 	PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 0, locked_axis[0]); | ||||||
| 	PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), PhysicsServer::BodyAxisLock(axis_lock)); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RigidBody::AxisLock RigidBody::get_axis_lock() const { | void RigidBody::set_axis_lock_y(bool p_lock) { | ||||||
|  | 	RigidBody::locked_axis[1] = p_lock; | ||||||
|  | 	PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 1, locked_axis[1]); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	return axis_lock; | void RigidBody::set_axis_lock_z(bool p_lock) { | ||||||
|  | 	RigidBody::locked_axis[2] = p_lock; | ||||||
|  | 	PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 2, locked_axis[2]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool RigidBody::get_axis_lock_x() const { | ||||||
|  | 	return RigidBody::locked_axis[0]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool RigidBody::get_axis_lock_y() const { | ||||||
|  | 	return RigidBody::locked_axis[1]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool RigidBody::get_axis_lock_z() const { | ||||||
|  | 	return RigidBody::locked_axis[2]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Array RigidBody::get_colliding_bodies() const { | Array RigidBody::get_colliding_bodies() const { | ||||||
|  | @ -837,8 +853,12 @@ void RigidBody::_bind_methods() { | ||||||
| 	ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody::_body_enter_tree); | 	ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody::_body_enter_tree); | ||||||
| 	ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody::_body_exit_tree); | 	ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody::_body_exit_tree); | ||||||
| 
 | 
 | ||||||
| 	ClassDB::bind_method(D_METHOD("set_axis_lock", "axis_lock"), &RigidBody::set_axis_lock); | 	ClassDB::bind_method(D_METHOD("set_axis_lock_x", "axis_lock_x"), &RigidBody::set_axis_lock_x); | ||||||
| 	ClassDB::bind_method(D_METHOD("get_axis_lock"), &RigidBody::get_axis_lock); | 	ClassDB::bind_method(D_METHOD("set_axis_lock_y", "axis_lock_y"), &RigidBody::set_axis_lock_y); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("set_axis_lock_z", "axis_lock_z"), &RigidBody::set_axis_lock_z); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("get_axis_lock_x"), &RigidBody::get_axis_lock_x); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("get_axis_lock_y"), &RigidBody::get_axis_lock_y); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("get_axis_lock_z"), &RigidBody::get_axis_lock_z); | ||||||
| 
 | 
 | ||||||
| 	ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody::get_colliding_bodies); | 	ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody::get_colliding_bodies); | ||||||
| 
 | 
 | ||||||
|  | @ -856,7 +876,10 @@ void RigidBody::_bind_methods() { | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled"); | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled"); | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping"); | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping"); | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_lock", PROPERTY_HINT_ENUM, "Disabled,Lock X,Lock Y,Lock Z"), "set_axis_lock", "get_axis_lock"); | 	ADD_GROUP("Axis Lock", "axis_lock_"); | ||||||
|  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_x"), "set_axis_lock_x", "get_axis_lock_x"); | ||||||
|  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_y"), "set_axis_lock_y", "get_axis_lock_y"); | ||||||
|  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_z"), "set_axis_lock_z", "get_axis_lock_z"); | ||||||
| 	ADD_GROUP("Linear", "linear_"); | 	ADD_GROUP("Linear", "linear_"); | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); | 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp"); | 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp"); | ||||||
|  | @ -874,11 +897,6 @@ void RigidBody::_bind_methods() { | ||||||
| 	BIND_ENUM_CONSTANT(MODE_STATIC); | 	BIND_ENUM_CONSTANT(MODE_STATIC); | ||||||
| 	BIND_ENUM_CONSTANT(MODE_CHARACTER); | 	BIND_ENUM_CONSTANT(MODE_CHARACTER); | ||||||
| 	BIND_ENUM_CONSTANT(MODE_KINEMATIC); | 	BIND_ENUM_CONSTANT(MODE_KINEMATIC); | ||||||
| 
 |  | ||||||
| 	BIND_ENUM_CONSTANT(AXIS_LOCK_DISABLED); |  | ||||||
| 	BIND_ENUM_CONSTANT(AXIS_LOCK_X); |  | ||||||
| 	BIND_ENUM_CONSTANT(AXIS_LOCK_Y); |  | ||||||
| 	BIND_ENUM_CONSTANT(AXIS_LOCK_Z); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RigidBody::RigidBody() : | RigidBody::RigidBody() : | ||||||
|  | @ -904,8 +922,6 @@ RigidBody::RigidBody() : | ||||||
| 	contact_monitor = NULL; | 	contact_monitor = NULL; | ||||||
| 	can_sleep = true; | 	can_sleep = true; | ||||||
| 
 | 
 | ||||||
| 	axis_lock = AXIS_LOCK_DISABLED; |  | ||||||
| 
 |  | ||||||
| 	PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); | 	PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -952,6 +968,12 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli | ||||||
| 		r_collision.local_shape = result.collision_local_shape; | 		r_collision.local_shape = result.collision_local_shape; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	for (int i = 0; i < 3; i++) { | ||||||
|  | 		if (locked_axis[i]) { | ||||||
|  | 			result.motion[i] = 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	gt.origin += result.motion; | 	gt.origin += result.motion; | ||||||
| 	set_global_transform(gt); | 	set_global_transform(gt); | ||||||
| 
 | 
 | ||||||
|  | @ -960,9 +982,16 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli | ||||||
| 
 | 
 | ||||||
| Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) { | Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) { | ||||||
| 
 | 
 | ||||||
| 	Vector3 motion = (floor_velocity + p_linear_velocity) * get_physics_process_delta_time(); |  | ||||||
| 	Vector3 lv = p_linear_velocity; | 	Vector3 lv = p_linear_velocity; | ||||||
| 
 | 
 | ||||||
|  | 	for (int i = 0; i < 3; i++) { | ||||||
|  | 		if (locked_axis[i]) { | ||||||
|  | 			lv[i] = 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Vector3 motion = (floor_velocity + lv) * get_physics_process_delta_time(); | ||||||
|  | 
 | ||||||
| 	on_floor = false; | 	on_floor = false; | ||||||
| 	on_ceiling = false; | 	on_ceiling = false; | ||||||
| 	on_wall = false; | 	on_wall = false; | ||||||
|  | @ -1008,6 +1037,12 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve | ||||||
| 			motion = motion.slide(n); | 			motion = motion.slide(n); | ||||||
| 			lv = lv.slide(n); | 			lv = lv.slide(n); | ||||||
| 
 | 
 | ||||||
|  | 			for (int i = 0; i < 3; i++) { | ||||||
|  | 				if (locked_axis[i]) { | ||||||
|  | 					lv[i] = 0; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			colliders.push_back(collision); | 			colliders.push_back(collision); | ||||||
| 
 | 
 | ||||||
| 		} else { | 		} else { | ||||||
|  | @ -1047,6 +1082,33 @@ bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion) | ||||||
| 	return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion); | 	return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void KinematicBody::set_axis_lock_x(bool p_lock) { | ||||||
|  | 	KinematicBody::locked_axis[0] = p_lock; | ||||||
|  | 	PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 0, locked_axis[0]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void KinematicBody::set_axis_lock_y(bool p_lock) { | ||||||
|  | 	KinematicBody::locked_axis[1] = p_lock; | ||||||
|  | 	PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 1, locked_axis[1]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void KinematicBody::set_axis_lock_z(bool p_lock) { | ||||||
|  | 	KinematicBody::locked_axis[2] = p_lock; | ||||||
|  | 	PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 2, locked_axis[2]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool KinematicBody::get_axis_lock_x() const { | ||||||
|  | 	return KinematicBody::locked_axis[0]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool KinematicBody::get_axis_lock_y() const { | ||||||
|  | 	return KinematicBody::locked_axis[1]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool KinematicBody::get_axis_lock_z() const { | ||||||
|  | 	return KinematicBody::locked_axis[2]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void KinematicBody::set_safe_margin(float p_margin) { | void KinematicBody::set_safe_margin(float p_margin) { | ||||||
| 
 | 
 | ||||||
| 	margin = p_margin; | 	margin = p_margin; | ||||||
|  | @ -1095,12 +1157,24 @@ void KinematicBody::_bind_methods() { | ||||||
| 	ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall); | 	ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall); | ||||||
| 	ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity); | 	ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity); | ||||||
| 
 | 
 | ||||||
|  | 	ClassDB::bind_method(D_METHOD("set_axis_lock_x", "axis_lock_x"), &KinematicBody::set_axis_lock_x); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("set_axis_lock_y", "axis_lock_y"), &KinematicBody::set_axis_lock_y); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("set_axis_lock_z", "axis_lock_z"), &KinematicBody::set_axis_lock_z); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("get_axis_lock_x"), &KinematicBody::get_axis_lock_x); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("get_axis_lock_y"), &KinematicBody::get_axis_lock_y); | ||||||
|  | 	ClassDB::bind_method(D_METHOD("get_axis_lock_z"), &KinematicBody::get_axis_lock_z); | ||||||
|  | 
 | ||||||
| 	ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin); | 	ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin); | ||||||
| 	ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin); | 	ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin); | ||||||
| 
 | 
 | ||||||
| 	ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count); | 	ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count); | ||||||
| 	ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision); | 	ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision); | ||||||
| 
 | 
 | ||||||
|  | 	ADD_GROUP("Axis Lock", "axis_lock_"); | ||||||
|  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_x"), "set_axis_lock_x", "get_axis_lock_x"); | ||||||
|  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_y"), "set_axis_lock_y", "get_axis_lock_y"); | ||||||
|  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_z"), "set_axis_lock_z", "get_axis_lock_z"); | ||||||
|  | 
 | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); | 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -114,13 +114,6 @@ public: | ||||||
| 		MODE_KINEMATIC, | 		MODE_KINEMATIC, | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	enum AxisLock { |  | ||||||
| 		AXIS_LOCK_DISABLED, |  | ||||||
| 		AXIS_LOCK_X, |  | ||||||
| 		AXIS_LOCK_Y, |  | ||||||
| 		AXIS_LOCK_Z, |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| private: | private: | ||||||
| 	bool can_sleep; | 	bool can_sleep; | ||||||
| 	PhysicsDirectBodyState *state; | 	PhysicsDirectBodyState *state; | ||||||
|  | @ -139,7 +132,7 @@ private: | ||||||
| 	bool sleeping; | 	bool sleeping; | ||||||
| 	bool ccd; | 	bool ccd; | ||||||
| 
 | 
 | ||||||
| 	AxisLock axis_lock; | 	bool locked_axis[3] = { false, false, false }; | ||||||
| 
 | 
 | ||||||
| 	int max_contacts_reported; | 	int max_contacts_reported; | ||||||
| 
 | 
 | ||||||
|  | @ -245,8 +238,12 @@ public: | ||||||
| 	void set_use_continuous_collision_detection(bool p_enable); | 	void set_use_continuous_collision_detection(bool p_enable); | ||||||
| 	bool is_using_continuous_collision_detection() const; | 	bool is_using_continuous_collision_detection() const; | ||||||
| 
 | 
 | ||||||
| 	void set_axis_lock(AxisLock p_lock); | 	void set_axis_lock_x(bool p_lock); | ||||||
| 	AxisLock get_axis_lock() const; | 	void set_axis_lock_y(bool p_lock); | ||||||
|  | 	void set_axis_lock_z(bool p_lock); | ||||||
|  | 	bool get_axis_lock_x() const; | ||||||
|  | 	bool get_axis_lock_y() const; | ||||||
|  | 	bool get_axis_lock_z() const; | ||||||
| 
 | 
 | ||||||
| 	Array get_colliding_bodies() const; | 	Array get_colliding_bodies() const; | ||||||
| 
 | 
 | ||||||
|  | @ -259,7 +256,6 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| VARIANT_ENUM_CAST(RigidBody::Mode); | VARIANT_ENUM_CAST(RigidBody::Mode); | ||||||
| VARIANT_ENUM_CAST(RigidBody::AxisLock); |  | ||||||
| 
 | 
 | ||||||
| class KinematicCollision; | class KinematicCollision; | ||||||
| 
 | 
 | ||||||
|  | @ -281,6 +277,8 @@ public: | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | 	bool locked_axis[3] = { false, false, false }; | ||||||
|  | 
 | ||||||
| 	float margin; | 	float margin; | ||||||
| 
 | 
 | ||||||
| 	Vector3 floor_velocity; | 	Vector3 floor_velocity; | ||||||
|  | @ -303,6 +301,13 @@ public: | ||||||
| 	bool move_and_collide(const Vector3 &p_motion, Collision &r_collision); | 	bool move_and_collide(const Vector3 &p_motion, Collision &r_collision); | ||||||
| 	bool test_move(const Transform &p_from, const Vector3 &p_motion); | 	bool test_move(const Transform &p_from, const Vector3 &p_motion); | ||||||
| 
 | 
 | ||||||
|  | 	void set_axis_lock_x(bool p_lock); | ||||||
|  | 	void set_axis_lock_y(bool p_lock); | ||||||
|  | 	void set_axis_lock_z(bool p_lock); | ||||||
|  | 	bool get_axis_lock_x() const; | ||||||
|  | 	bool get_axis_lock_y() const; | ||||||
|  | 	bool get_axis_lock_z() const; | ||||||
|  | 
 | ||||||
| 	void set_safe_margin(float p_margin); | 	void set_safe_margin(float p_margin); | ||||||
| 	float get_safe_margin() const; | 	float get_safe_margin() const; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -559,6 +559,20 @@ void BodySW::integrate_velocities(real_t p_step) { | ||||||
| 	if (fi_callback) | 	if (fi_callback) | ||||||
| 		get_space()->body_add_to_state_query_list(&direct_state_query_list); | 		get_space()->body_add_to_state_query_list(&direct_state_query_list); | ||||||
| 
 | 
 | ||||||
|  | 	//apply axis lock
 | ||||||
|  | 	if (locked_axis[0] || locked_axis[1] || locked_axis[2]) { | ||||||
|  | 		for (int i = 0; i < 3; i++) { | ||||||
|  | 			if (locked_axis[i]) { | ||||||
|  | 				linear_velocity[i] = 0; | ||||||
|  | 				biased_linear_velocity[i] = 0; | ||||||
|  | 				new_transform.origin[i] = get_transform().origin[i]; | ||||||
|  | 			} else { | ||||||
|  | 				angular_velocity[i] = 0; | ||||||
|  | 				biased_angular_velocity[i] = 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if (mode == PhysicsServer::BODY_MODE_KINEMATIC) { | 	if (mode == PhysicsServer::BODY_MODE_KINEMATIC) { | ||||||
| 
 | 
 | ||||||
| 		_set_transform(new_transform, false); | 		_set_transform(new_transform, false); | ||||||
|  | @ -569,22 +583,6 @@ void BodySW::integrate_velocities(real_t p_step) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//apply axis lock
 |  | ||||||
| 	if (axis_lock != PhysicsServer::BODY_AXIS_LOCK_DISABLED) { |  | ||||||
| 
 |  | ||||||
| 		int axis = axis_lock - 1; |  | ||||||
| 		for (int i = 0; i < 3; i++) { |  | ||||||
| 			if (i == axis) { |  | ||||||
| 				linear_velocity[i] = 0; |  | ||||||
| 				biased_linear_velocity[i] = 0; |  | ||||||
| 			} else { |  | ||||||
| 
 |  | ||||||
| 				angular_velocity[i] = 0; |  | ||||||
| 				biased_angular_velocity[i] = 0; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	Vector3 total_angular_velocity = angular_velocity + biased_angular_velocity; | 	Vector3 total_angular_velocity = angular_velocity + biased_angular_velocity; | ||||||
| 
 | 
 | ||||||
| 	real_t ang_vel = total_angular_velocity.length(); | 	real_t ang_vel = total_angular_velocity.length(); | ||||||
|  | @ -775,7 +773,6 @@ BodySW::BodySW() : | ||||||
| 	continuous_cd = false; | 	continuous_cd = false; | ||||||
| 	can_sleep = false; | 	can_sleep = false; | ||||||
| 	fi_callback = NULL; | 	fi_callback = NULL; | ||||||
| 	axis_lock = PhysicsServer::BODY_AXIS_LOCK_DISABLED; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BodySW::~BodySW() { | BodySW::~BodySW() { | ||||||
|  |  | ||||||
|  | @ -53,7 +53,7 @@ class BodySW : public CollisionObjectSW { | ||||||
| 	real_t angular_damp; | 	real_t angular_damp; | ||||||
| 	real_t gravity_scale; | 	real_t gravity_scale; | ||||||
| 
 | 
 | ||||||
| 	PhysicsServer::BodyAxisLock axis_lock; | 	bool locked_axis[3] = { false, false, false }; | ||||||
| 
 | 
 | ||||||
| 	real_t kinematic_safe_margin; | 	real_t kinematic_safe_margin; | ||||||
| 	real_t _inv_mass; | 	real_t _inv_mass; | ||||||
|  | @ -288,8 +288,8 @@ public: | ||||||
| 	_FORCE_INLINE_ Vector3 get_gravity() const { return gravity; } | 	_FORCE_INLINE_ Vector3 get_gravity() const { return gravity; } | ||||||
| 	_FORCE_INLINE_ real_t get_bounce() const { return bounce; } | 	_FORCE_INLINE_ real_t get_bounce() const { return bounce; } | ||||||
| 
 | 
 | ||||||
| 	_FORCE_INLINE_ void set_axis_lock(PhysicsServer::BodyAxisLock p_lock) { axis_lock = p_lock; } | 	_FORCE_INLINE_ void set_axis_lock(int axis, bool lock) { locked_axis[axis] = lock; } | ||||||
| 	_FORCE_INLINE_ PhysicsServer::BodyAxisLock get_axis_lock() const { return axis_lock; } | 	_FORCE_INLINE_ bool get_axis_lock() const { return locked_axis; } | ||||||
| 
 | 
 | ||||||
| 	void integrate_forces(real_t p_step); | 	void integrate_forces(real_t p_step); | ||||||
| 	void integrate_velocities(real_t p_step); | 	void integrate_velocities(real_t p_step); | ||||||
|  |  | ||||||
|  | @ -794,19 +794,19 @@ void PhysicsServerSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_v | ||||||
| 	body->wakeup(); | 	body->wakeup(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void PhysicsServerSW::body_set_axis_lock(RID p_body, BodyAxisLock p_lock) { | void PhysicsServerSW::body_set_axis_lock(RID p_body, int axis, bool lock) { | ||||||
| 
 | 
 | ||||||
| 	BodySW *body = body_owner.get(p_body); | 	BodySW *body = body_owner.get(p_body); | ||||||
| 	ERR_FAIL_COND(!body); | 	ERR_FAIL_COND(!body); | ||||||
| 
 | 
 | ||||||
| 	body->set_axis_lock(p_lock); | 	body->set_axis_lock(axis, lock); | ||||||
| 	body->wakeup(); | 	body->wakeup(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PhysicsServerSW::BodyAxisLock PhysicsServerSW::body_get_axis_lock(RID p_body) const { | bool PhysicsServerSW::body_get_axis_lock(RID p_body) const { | ||||||
| 
 | 
 | ||||||
| 	const BodySW *body = body_owner.get(p_body); | 	const BodySW *body = body_owner.get(p_body); | ||||||
| 	ERR_FAIL_COND_V(!body, BODY_AXIS_LOCK_DISABLED); | 	ERR_FAIL_COND_V(!body, 0); | ||||||
| 	return body->get_axis_lock(); | 	return body->get_axis_lock(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -203,8 +203,8 @@ public: | ||||||
| 	virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse); | 	virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse); | ||||||
| 	virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity); | 	virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity); | ||||||
| 
 | 
 | ||||||
| 	virtual void body_set_axis_lock(RID p_body, BodyAxisLock p_lock); | 	virtual void body_set_axis_lock(RID p_body, int axis, bool p_lock); | ||||||
| 	virtual BodyAxisLock body_get_axis_lock(RID p_body) const; | 	virtual bool body_get_axis_lock(RID p_body) const; | ||||||
| 
 | 
 | ||||||
| 	virtual void body_add_collision_exception(RID p_body, RID p_body_b); | 	virtual void body_add_collision_exception(RID p_body, RID p_body_b); | ||||||
| 	virtual void body_remove_collision_exception(RID p_body, RID p_body_b); | 	virtual void body_remove_collision_exception(RID p_body, RID p_body_b); | ||||||
|  |  | ||||||
|  | @ -472,7 +472,7 @@ void PhysicsServer::_bind_methods() { | ||||||
| 	ClassDB::bind_method(D_METHOD("body_apply_torque_impulse", "body", "impulse"), &PhysicsServer::body_apply_torque_impulse); | 	ClassDB::bind_method(D_METHOD("body_apply_torque_impulse", "body", "impulse"), &PhysicsServer::body_apply_torque_impulse); | ||||||
| 	ClassDB::bind_method(D_METHOD("body_set_axis_velocity", "body", "axis_velocity"), &PhysicsServer::body_set_axis_velocity); | 	ClassDB::bind_method(D_METHOD("body_set_axis_velocity", "body", "axis_velocity"), &PhysicsServer::body_set_axis_velocity); | ||||||
| 
 | 
 | ||||||
| 	ClassDB::bind_method(D_METHOD("body_set_axis_lock", "body", "axis"), &PhysicsServer::body_set_axis_lock); | 	ClassDB::bind_method(D_METHOD("body_set_axis_lock", "body", "axis", "lock"), &PhysicsServer::body_set_axis_lock); | ||||||
| 	ClassDB::bind_method(D_METHOD("body_get_axis_lock", "body"), &PhysicsServer::body_get_axis_lock); | 	ClassDB::bind_method(D_METHOD("body_get_axis_lock", "body"), &PhysicsServer::body_get_axis_lock); | ||||||
| 
 | 
 | ||||||
| 	ClassDB::bind_method(D_METHOD("body_add_collision_exception", "body", "excepted_body"), &PhysicsServer::body_add_collision_exception); | 	ClassDB::bind_method(D_METHOD("body_add_collision_exception", "body", "excepted_body"), &PhysicsServer::body_add_collision_exception); | ||||||
|  | @ -702,11 +702,6 @@ void PhysicsServer::_bind_methods() { | ||||||
| 	BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP); | 	BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP); | ||||||
| 	BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO); | 	BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO); | ||||||
| 	BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS); | 	BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS); | ||||||
| 
 |  | ||||||
| 	BIND_ENUM_CONSTANT(BODY_AXIS_LOCK_DISABLED); |  | ||||||
| 	BIND_ENUM_CONSTANT(BODY_AXIS_LOCK_X); |  | ||||||
| 	BIND_ENUM_CONSTANT(BODY_AXIS_LOCK_Y); |  | ||||||
| 	BIND_ENUM_CONSTANT(BODY_AXIS_LOCK_Z); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| PhysicsServer::PhysicsServer() { | PhysicsServer::PhysicsServer() { | ||||||
|  |  | ||||||
|  | @ -421,15 +421,8 @@ public: | ||||||
| 	virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) = 0; | 	virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) = 0; | ||||||
| 	virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) = 0; | 	virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) = 0; | ||||||
| 
 | 
 | ||||||
| 	enum BodyAxisLock { | 	virtual void body_set_axis_lock(RID p_body, int axis, bool lock) = 0; | ||||||
| 		BODY_AXIS_LOCK_DISABLED, | 	virtual bool body_get_axis_lock(RID p_body) const = 0; | ||||||
| 		BODY_AXIS_LOCK_X, |  | ||||||
| 		BODY_AXIS_LOCK_Y, |  | ||||||
| 		BODY_AXIS_LOCK_Z, |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	virtual void body_set_axis_lock(RID p_body, BodyAxisLock p_lock) = 0; |  | ||||||
| 	virtual BodyAxisLock body_get_axis_lock(RID p_body) const = 0; |  | ||||||
| 
 | 
 | ||||||
| 	//fix
 | 	//fix
 | ||||||
| 	virtual void body_add_collision_exception(RID p_body, RID p_body_b) = 0; | 	virtual void body_add_collision_exception(RID p_body, RID p_body_b) = 0; | ||||||
|  | @ -692,7 +685,6 @@ VARIANT_ENUM_CAST(PhysicsServer::AreaSpaceOverrideMode); | ||||||
| VARIANT_ENUM_CAST(PhysicsServer::BodyMode); | VARIANT_ENUM_CAST(PhysicsServer::BodyMode); | ||||||
| VARIANT_ENUM_CAST(PhysicsServer::BodyParameter); | VARIANT_ENUM_CAST(PhysicsServer::BodyParameter); | ||||||
| VARIANT_ENUM_CAST(PhysicsServer::BodyState); | VARIANT_ENUM_CAST(PhysicsServer::BodyState); | ||||||
| VARIANT_ENUM_CAST(PhysicsServer::BodyAxisLock); |  | ||||||
| VARIANT_ENUM_CAST(PhysicsServer::PinJointParam); | VARIANT_ENUM_CAST(PhysicsServer::PinJointParam); | ||||||
| VARIANT_ENUM_CAST(PhysicsServer::JointType); | VARIANT_ENUM_CAST(PhysicsServer::JointType); | ||||||
| VARIANT_ENUM_CAST(PhysicsServer::HingeJointParam); | VARIANT_ENUM_CAST(PhysicsServer::HingeJointParam); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue