forked from Revolutionary-Games/Thrive
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Revolutionary-Games#64 from Revolutionary-Games/62…
…-Collision-functionality Implementation of custom collision events.
- Loading branch information
Showing
17 changed files
with
903 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
#include "collision_filter.h" | ||
#include <luabind/iterator_policy.hpp> | ||
#include "engine/game_state.h" | ||
#include "scripting/luabind.h" | ||
|
||
|
||
|
||
using namespace thrive; | ||
|
||
struct CollisionFilter::Implementation { | ||
|
||
Implementation( | ||
const std::string& collisionGroup1, | ||
const std::string& collisionGroup2 | ||
) : m_signature(collisionGroup1, collisionGroup2) | ||
{ | ||
} | ||
|
||
CollisionMap m_collisions; | ||
|
||
Signature m_signature; | ||
|
||
CollisionSystem* m_collisionSystem = nullptr; | ||
|
||
}; | ||
|
||
|
||
luabind::scope | ||
CollisionFilter::luaBindings() { | ||
using namespace luabind; | ||
return class_<CollisionFilter>("CollisionFilter") | ||
.def(constructor<const std::string&, const std::string&>()) | ||
.def("init", &CollisionFilter::init) | ||
.def("shutdown", &CollisionFilter::shutdown) | ||
.def("collisions", &CollisionFilter::collisions, return_stl_iterator) | ||
.def("clearCollisions", &CollisionFilter::clearCollisions) | ||
; | ||
} | ||
|
||
|
||
CollisionFilter::CollisionFilter( | ||
const std::string& collisionGroup1, | ||
const std::string& collisionGroup2 | ||
) : m_impl(new Implementation(collisionGroup1, collisionGroup2)) | ||
{ | ||
} | ||
|
||
CollisionFilter::~CollisionFilter(){} | ||
|
||
void | ||
CollisionFilter::init( | ||
GameState* gameState | ||
) { | ||
m_impl->m_collisionSystem = gameState->findSystem<CollisionSystem>(); | ||
m_impl->m_collisionSystem->registerCollisionFilter(*this); | ||
} | ||
|
||
void | ||
CollisionFilter::shutdown() { | ||
m_impl->m_collisionSystem->unregisterCollisionFilter(*this); | ||
m_impl->m_collisionSystem = nullptr; | ||
} | ||
|
||
const CollisionFilter::CollisionIterator | ||
CollisionFilter::collisions() { | ||
return m_impl->m_collisions | boost::adaptors::map_values; | ||
} | ||
|
||
|
||
void | ||
CollisionFilter::addCollision( | ||
Collision collision | ||
) { | ||
CollisionMap::iterator foundCollision = m_impl->m_collisions.find(CollisionId(collision.entityId1, collision.entityId2)); | ||
if (foundCollision != m_impl->m_collisions.end()) | ||
foundCollision->second.addedCollisionDuration += collision.addedCollisionDuration; //Add collision time. | ||
else | ||
{ | ||
CollisionId key(collision.entityId1, collision.entityId2); | ||
m_impl->m_collisions.emplace(key, collision); | ||
} | ||
|
||
} | ||
|
||
|
||
typename CollisionFilter::CollisionIterator::iterator | ||
CollisionFilter::begin() const { | ||
return (m_impl->m_collisions | boost::adaptors::map_values).begin(); | ||
} | ||
|
||
|
||
typename CollisionFilter::CollisionIterator::iterator | ||
CollisionFilter::end() const { | ||
return (m_impl->m_collisions | boost::adaptors::map_values).end(); | ||
} | ||
|
||
|
||
void | ||
CollisionFilter::clearCollisions() { | ||
m_impl->m_collisions.clear(); | ||
} | ||
|
||
|
||
const CollisionFilter::Signature& | ||
CollisionFilter::getCollisionSignature() const { | ||
return m_impl->m_signature; | ||
} | ||
|
||
|
||
size_t | ||
CollisionFilter::IdHash::operator() ( | ||
const CollisionId& collisionId | ||
) const { | ||
std::size_t hash1 = std::hash<EntityId>()(collisionId.first); | ||
std::size_t hash2 = std::hash<EntityId>()(collisionId.second); | ||
// Hash needs to be symmetric so that hash(entityId1, entityId2) == hash(entityId2, entityId1) | ||
return hash1 ^ hash2; | ||
} | ||
|
||
|
||
bool | ||
CollisionFilter::IdEquals::operator() ( | ||
const CollisionId& lhs, | ||
const CollisionId& rhs | ||
) const{ | ||
// Equality needs to be symmetric for collisions | ||
return (lhs.first == rhs.first && lhs.second == rhs.second) || | ||
(lhs.first == rhs.second && lhs.second == rhs.first); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
#pragma once | ||
|
||
#include <boost/range/adaptor/map.hpp> | ||
|
||
#include "bullet/collision_system.h" | ||
|
||
#include <iostream> | ||
#include <string> | ||
|
||
#include <unordered_set> | ||
#include <utility> | ||
|
||
|
||
namespace luabind { | ||
class scope; | ||
} | ||
|
||
namespace thrive { | ||
|
||
class Collision; | ||
class CollisionSystem; | ||
|
||
/** | ||
* @brief Filters for collisions that contain specific collision groups | ||
* | ||
* Collision filter makes it easy for systems and other peices of code to get easy | ||
* access to the right collisions | ||
* | ||
*/ | ||
|
||
class CollisionFilter { | ||
|
||
public: | ||
|
||
using CollisionId = std::pair<EntityId, EntityId>; | ||
|
||
using Signature = std::pair<std::string, std::string>; | ||
|
||
struct IdHash { | ||
std::size_t | ||
operator() ( | ||
const CollisionId& collisionId | ||
) const; | ||
}; | ||
|
||
struct IdEquals { | ||
bool | ||
operator() ( | ||
const CollisionId& lhs, | ||
const CollisionId& rhs | ||
) const; | ||
}; | ||
|
||
using CollisionMap = std::unordered_map<CollisionId, Collision, IdHash, IdEquals>; | ||
using CollisionIterator = boost::range_detail::select_second_mutable_range<CollisionMap>; | ||
|
||
/** | ||
* @brief Constructor | ||
* | ||
* @param collisionGroup1 | ||
* The first collision group to monitor | ||
* | ||
* @param collisionGroup2 | ||
* The second collision group to monitor | ||
* | ||
*/ | ||
CollisionFilter( | ||
const std::string& collisionGroup1, | ||
const std::string& collisionGroup2 | ||
); | ||
|
||
/** | ||
* @brief Destructor | ||
*/ | ||
~CollisionFilter(); | ||
|
||
/** | ||
* @brief Initialized the collision filter | ||
* | ||
* @param gameState | ||
* The gamestate the filter belongs in. | ||
*/ | ||
void | ||
init( | ||
GameState* gameState | ||
); | ||
|
||
/** | ||
* @brief Shuts down the filter. | ||
*/ | ||
void | ||
shutdown(); | ||
|
||
/** | ||
* @brief Lua bindings | ||
* | ||
* Exposes the following \b constructors: | ||
* - CollisionFilter(const std::string&, const std::string&) | ||
* - CollisionFilter::init(GameState*) | ||
* - CollisionFilter::shutdown() | ||
* - CollisionFilter::collisions() | ||
* - CollisionFilter::clearCollisions() | ||
*/ | ||
static luabind::scope | ||
luaBindings(); | ||
|
||
/** | ||
* @brief Returns the collisions that has occoured | ||
* | ||
* Is only reset when clearCollisions() is called | ||
*/ | ||
const CollisionIterator | ||
collisions(); | ||
|
||
/** | ||
* @brief Clears the collisions | ||
*/ | ||
void | ||
clearCollisions(); | ||
|
||
/** | ||
* @brief Adds a collision | ||
* | ||
* @param collision | ||
* Collision to add | ||
*/ | ||
void | ||
addCollision(Collision collision); | ||
|
||
/** | ||
* @brief Iterator | ||
* | ||
* Equivalent to | ||
* \code | ||
* collisions().cbegin() | ||
* \endcode | ||
* | ||
* @return An iterator to the first collision | ||
*/ | ||
typename CollisionIterator::iterator | ||
begin() const; | ||
|
||
/** | ||
* @brief Iterator | ||
* | ||
* Equivalent to | ||
* \code | ||
* collisions().cend() | ||
* \endcode | ||
* | ||
* @return An iterator to the end of the collisions | ||
*/ | ||
typename CollisionIterator::iterator | ||
end() const; | ||
|
||
/** | ||
* @brief Returns the signature of the collision filter | ||
* | ||
* @return | ||
* A pair of the two collision group strings. | ||
*/ | ||
const Signature& | ||
getCollisionSignature() const; | ||
|
||
private: | ||
|
||
struct Implementation; | ||
std::unique_ptr<Implementation> m_impl; | ||
|
||
}; | ||
|
||
} |
Oops, something went wrong.