• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "ContactCache.h"
2 
3 ContactCache *currentContactCache = 0;
4 
ContactCacheStarted_CB(btPersistentManifold * const & manifold)5 inline void ContactCacheStarted_CB(btPersistentManifold* const &manifold) {
6 	currentContactCache->contactStarted(manifold);
7 }
ContactCacheEnded_CB(btPersistentManifold * const & manifold)8 inline void ContactCacheEnded_CB(btPersistentManifold* const &manifold) {
9 	currentContactCache->contactEnded(manifold);
10 }
11 
12 struct ContactPair {
13 	const btCollisionObject *object0;
14 	const btCollisionObject *object1;
15 	float time;
16 
ContactPairContactPair17 	ContactPair() : object0(0), object1(0), time(0) {}
18 
ContactPairContactPair19 	ContactPair(const ContactPair &rhs) : object0(rhs.object0), object1(rhs.object1), time(rhs.time) {}
20 
ContactPairContactPair21 	ContactPair(const btCollisionObject* const &object0, const btCollisionObject* const &object1, const float &time) : object0(object0), object1(object1), time(time) {}
22 
operator =ContactPair23 	ContactPair &operator=(const ContactPair &rhs) {
24 		object0 = rhs.object0;
25 		object1 = rhs.object1;
26 		time = rhs.time;
27 		return *this;
28 	}
29 
operator ==ContactPair30 	inline bool operator==(const ContactPair &rhs) const {
31 		return ((rhs.object0 == object0) && (rhs.object1 == object1)) || ((rhs.object0 == object1) && (rhs.object1 == object0));
32 	}
33 
operator <ContactPair34 	inline bool operator<(const ContactPair &rhs) const {
35 		if (*this == rhs)
36 			return false;
37 		return object0 < rhs.object0;
38 	}
39 
equalsContactPair40 	inline bool equals(const btCollisionObject* const &obj0, const btCollisionObject* const &obj1) const {
41 		return ((obj0 == object0) && (obj1 == object1)) || ((obj0 == object1) && (obj1 == object0));
42 	}
43 };
44 
ContactCache(bool dummy)45 ContactCache::ContactCache(bool dummy)
46 	: events(0), cacheTime(0.2f), filter(true) {}
47 
~ContactCache()48 ContactCache::~ContactCache() {
49 	disable();
50 }
51 
setEvents(const int & events)52 void ContactCache::setEvents(const int &events) {
53 	this->events = events;
54 }
55 
enable()56 void ContactCache::enable() {
57 	currentContactCache = this;
58 	gContactStartedCallback = ContactCacheStarted_CB;
59 	gContactEndedCallback = ContactCacheEnded_CB;
60 }
61 
disable()62 void ContactCache::disable() {
63 	if (currentContactCache == this) {
64 		currentContactCache = 0;
65 		if (gContactStartedCallback == ContactCacheStarted_CB)
66 			gContactStartedCallback = 0;
67 		if (gContactEndedCallback == ContactCacheEnded_CB)
68 			gContactEndedCallback = 0;
69 	}
70 }
71 
isEnabled()72 bool ContactCache::isEnabled() {
73 	return (currentContactCache == this) && (gContactStartedCallback == ContactCacheStarted_CB) && (gContactEndedCallback == ContactCacheEnded_CB);
74 }
75 
clear()76 void ContactCache::clear() {
77 	cache.clear();
78 }
79 
update(float delta)80 void ContactCache::update(float delta) {
81 	for (int i = cache.size() - 1; i >= 0; --i) {
82 		ContactPair &pair = cache.at(i);
83 		if ((pair.time -= delta) < 0) {
84 			const btCollisionObject* const &object0 = pair.object0;
85 			const btCollisionObject* const &object1 = pair.object1;
86 			const bool match0 = gdxCheckFilter(object0, object1);
87 			const bool match1 = gdxCheckFilter(object1, object0);
88 			if (!filter || match0 || match1)
89 				onContactEnded(object0, match0, object1, match1);
90 			cache.swap(i, cache.size()-1);
91 			cache.pop_back();
92 		}
93 	}
94 }
95 
indexOf(const btCollisionObject * const & obj0,const btCollisionObject * const & obj1)96 int ContactCache::indexOf(const btCollisionObject* const &obj0, const btCollisionObject* const &obj1) {
97 	for (int i = cache.size() - 1; i >= 0; --i) {
98 		ContactPair &pair = cache.at(i);
99 		if (pair.equals(obj0, obj1))
100 			return i;
101 	}
102 	return -1;
103 }
104 
contactStarted(btPersistentManifold * manifold)105 void ContactCache::contactStarted(btPersistentManifold* manifold) {
106 	const bool match0 = gdxCheckFilter(manifold->getBody0(), manifold->getBody1());
107 	const bool match1 = gdxCheckFilter(manifold->getBody1(), manifold->getBody0());
108 	if (filter && !match0 && !match1)
109 		return;
110 	const int idx = indexOf(manifold->getBody0(), manifold->getBody1());
111 	if (idx >= 0) {
112 		cache.swap(idx, cache.size()-1);
113 		cache.pop_back();
114 	}
115 	else
116 		onContactStarted(manifold, match0, match1);
117 }
118 
contactEnded(btPersistentManifold * manifold)119 void ContactCache::contactEnded(btPersistentManifold* manifold) {
120 	const bool match0 = gdxCheckFilter(manifold->getBody0(), manifold->getBody1());
121 	const bool match1 = gdxCheckFilter(manifold->getBody1(), manifold->getBody0());
122 	if (filter && !match0 && !match1)
123 		return;
124 	const int idx = indexOf(manifold->getBody0(), manifold->getBody1());
125 	if (idx >= 0)
126 		cache[idx].time = cacheTime;
127 	else
128 		cache.push_back(ContactPair(manifold->getBody0(), manifold->getBody1(), cacheTime));
129 }
130