/**
* Copyright 2012 Jason Sorensen (sorensenj@smert.net)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package net.smert.frameworkgl.collision.broadphase;
import java.util.Iterator;
import net.smert.frameworkgl.collision.narrowphase.NarrowphaseDispatch;
import net.smert.frameworkgl.utils.HashMapIntGeneric;
/**
*
* @author Jason Sorensen <sorensenj@smert.net>
*/
public class HashedOverlappingPairCache implements OverlappingPairCache {
private final HashMapIntGeneric<OverlappingPair> overlappingPairs;
private final OverlappingPairFilterCallback overlappingPairFilterCallback;
public HashedOverlappingPairCache(OverlappingPairFilterCallback overlappingPairFilterCallback) {
this.overlappingPairFilterCallback = overlappingPairFilterCallback;
overlappingPairs = new HashMapIntGeneric<>();
}
private int getHashCode(BroadphaseProxy broadphaseProxy0, BroadphaseProxy broadphaseProxy1) {
int hash0 = broadphaseProxy0.hashCode();
int hash1 = broadphaseProxy1.hashCode();
if (hash0 < hash1) {
int tmp = hash0;
hash0 = hash1;
hash1 = tmp;
}
return (hash0 * 17) ^ (hash1 * 31);
}
@Override
public OverlappingPair addOverlappingPair(BroadphaseProxy broadphaseProxy0, BroadphaseProxy broadphaseProxy1) {
if (!overlappingPairFilterCallback.needsBroadphaseCollision(broadphaseProxy0, broadphaseProxy1)) {
return null;
}
// Calculate hash code and create new pair
int hashCode = getHashCode(broadphaseProxy0, broadphaseProxy1);
OverlappingPair pair = new OverlappingPair();
pair.proxy0 = broadphaseProxy0;
pair.proxy1 = broadphaseProxy1;
// Save pair
OverlappingPair oldPair = overlappingPairs.put(hashCode, pair);
return pair;
}
@Override
public OverlappingPair findOverlappingPair(BroadphaseProxy broadphaseProxy0, BroadphaseProxy broadphaseProxy1) {
int hashCode = getHashCode(broadphaseProxy0, broadphaseProxy1);
return overlappingPairs.get(hashCode);
}
@Override
public void processOverlappingPairs(NarrowphaseDispatch dispatch) {
Iterator it = overlappingPairs.values().iterator();
while (it.hasNext()) {
OverlappingPair pair = (OverlappingPair) it.next();
if (!dispatch.processOverlappingPair(pair)) {
it.remove();
}
}
}
@Override
public void removeOverlappingPair(BroadphaseProxy broadphaseProxy0, BroadphaseProxy broadphaseProxy1) {
int hashCode = getHashCode(broadphaseProxy0, broadphaseProxy1);
overlappingPairs.remove(hashCode);
}
@Override
public void removeOverlappingPairsContainingProxy(BroadphaseProxy broadphaseProxy) {
Iterator it = overlappingPairs.values().iterator();
while (it.hasNext()) {
OverlappingPair pair = (OverlappingPair) it.next();
if ((pair.proxy0 == broadphaseProxy) || (pair.proxy1 == broadphaseProxy)) {
it.remove();
}
}
}
}