| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | #include "..\e2dmanager.h"
 | 
					
						
							|  |  |  |  | #include "..\e2dnode.h"
 | 
					
						
							|  |  |  |  | #include "..\e2dtool.h"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | e2d::CollisionManager * e2d::CollisionManager::GetInstance() | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-08-19 15:11:20 +08:00
										 |  |  |  | 	static CollisionManager instance; | 
					
						
							|  |  |  |  | 	return &instance; | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::CollisionManager::CollisionManager() | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	: collision_enabled_(false) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | e2d::CollisionManager::~CollisionManager() | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | void e2d::CollisionManager::AddCollider(Collider * collider) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	colliders_.push_back(collider); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | void e2d::CollisionManager::RemoveCollider(Collider * collider) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	auto iter = std::find(colliders_.begin(), colliders_.end(), collider); | 
					
						
							|  |  |  |  | 	if (iter != colliders_.end()) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 		colliders_.erase(iter); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | void e2d::CollisionManager::UpdateCollider(Collider* active) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	if (!collision_enabled_ || | 
					
						
							|  |  |  |  | 		Game::GetInstance()->IsTransitioning()) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	auto currScene = Game::GetInstance()->GetCurrentScene(); | 
					
						
							|  |  |  |  | 	if (active->GetNode()->GetParentScene() != currScene) | 
					
						
							| 
									
										
										
										
											2018-08-28 00:06:10 +08:00
										 |  |  |  | 		return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-12 15:38:02 +08:00
										 |  |  |  | 	std::vector<Collider*> currColliders; | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	currColliders.reserve(colliders_.size()); | 
					
						
							| 
									
										
										
										
											2018-08-12 15:38:02 +08:00
										 |  |  |  | 	std::copy_if( | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 		colliders_.begin(), | 
					
						
							|  |  |  |  | 		colliders_.end(), | 
					
						
							| 
									
										
										
										
											2018-08-12 15:38:02 +08:00
										 |  |  |  | 		std::back_inserter(currColliders), | 
					
						
							| 
									
										
										
										
											2018-08-28 00:06:10 +08:00
										 |  |  |  | 		[this, active, currScene](Collider* passive) -> bool | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-08-28 00:06:10 +08:00
										 |  |  |  | 			return active != passive && | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 				passive->GetNode()->IsVisible() && | 
					
						
							|  |  |  |  | 				passive->GetNode()->GetParentScene() == currScene && | 
					
						
							|  |  |  |  | 				this->IsCollidable(active->GetNode(), passive->GetNode()); | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-08-12 15:38:02 +08:00
										 |  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-12 15:38:02 +08:00
										 |  |  |  | 	for (const auto& passive : currColliders) | 
					
						
							|  |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 		// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD>彻<EFBFBD><E5BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 		Collider::Relation relation = active->GetRelationWith(passive); | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 		// <20><><EFBFBD><EFBFBD> UNKNOWN <20><> DISJOIN <20><><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | 		if (relation != Collider::Relation::Unknown && | 
					
						
							|  |  |  |  | 			relation != Collider::Relation::Disjoin) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 			auto activeNode = active->GetNode(); | 
					
						
							|  |  |  |  | 			auto passiveNode = passive->GetNode(); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:08:03 +08:00
										 |  |  |  | 			// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD>¼<EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2018-08-12 15:38:02 +08:00
										 |  |  |  | 			Collision activeCollision(passiveNode, relation); | 
					
						
							| 
									
										
										
										
											2018-08-19 17:46:37 +08:00
										 |  |  |  | 			if (dynamic_cast<CollisionHandler*>(activeNode)) | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 				dynamic_cast<CollisionHandler*>(activeNode)->Handle(activeCollision); | 
					
						
							| 
									
										
										
										
											2018-07-17 14:08:03 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 			Collision passiveCollision(activeNode, passive->GetRelationWith(active)); | 
					
						
							| 
									
										
										
										
											2018-08-19 17:46:37 +08:00
										 |  |  |  | 			if (dynamic_cast<CollisionHandler*>(passiveNode)) | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 				dynamic_cast<CollisionHandler*>(passiveNode)->Handle(passiveCollision); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | void e2d::CollisionManager::SetCollisionEnabled(bool enabled) | 
					
						
							| 
									
										
										
										
											2018-08-19 15:11:20 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	collision_enabled_ = enabled; | 
					
						
							| 
									
										
										
										
											2018-08-19 15:11:20 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | void e2d::CollisionManager::AddName(const String & name1, const String & name2) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	if (!name1.IsEmpty() && !name2.IsEmpty()) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 		collision_list_.insert(std::make_pair(name1.GetHash(), name2.GetHash())); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | void e2d::CollisionManager::AddName(const std::vector<std::pair<String, String> >& names) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-08-12 14:30:28 +08:00
										 |  |  |  | 	for (const auto& name : names) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 		if (!name.first.IsEmpty() && !name.second.IsEmpty()) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 			collision_list_.insert(std::make_pair(name.first.GetHash(), name.second.GetHash())); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | bool e2d::CollisionManager::IsCollidable(Node * node1, Node * node2) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	return CollisionManager::IsCollidable(node1->GetName(), node2->GetName()); | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | bool e2d::CollisionManager::IsCollidable(const String & name1, const String & name2) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	size_t hashName1 = name1.GetHash(),  | 
					
						
							|  |  |  |  | 		hashName2 = name2.GetHash(); | 
					
						
							| 
									
										
										
										
											2018-07-13 00:45:39 +08:00
										 |  |  |  | 	auto pair1 = std::make_pair(hashName1, hashName2),  | 
					
						
							|  |  |  |  | 		pair2 = std::make_pair(hashName2, hashName1); | 
					
						
							| 
									
										
										
										
											2018-09-04 22:42:34 +08:00
										 |  |  |  | 	for (const auto& pair : collision_list_) | 
					
						
							| 
									
										
										
										
											2018-07-08 16:57:12 +08:00
										 |  |  |  | 	{ | 
					
						
							|  |  |  |  | 		if (pair == pair1 || pair == pair2) | 
					
						
							|  |  |  |  | 		{ | 
					
						
							|  |  |  |  | 			return true; | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return false; | 
					
						
							|  |  |  |  | } |