/*
|
* Java port of Bullet (c) 2008 Martin Dvorak <jezek2@advel.cz>
|
*
|
* Bullet Continuous Collision Detection and Physics Library
|
* Copyright (c) 2003-2008 Erwin Coumans http://www.bulletphysics.com/
|
*
|
* This software is provided 'as-is', without any express or implied warranty.
|
* In no event will the authors be held liable for any damages arising from
|
* the use of this software.
|
*
|
* Permission is granted to anyone to use this software for any purpose,
|
* including commercial applications, and to alter it and redistribute it
|
* freely, subject to the following restrictions:
|
*
|
* 1. The origin of this software must not be misrepresented; you must not
|
* claim that you wrote the original software. If you use this software
|
* in a product, an acknowledgment in the product documentation would be
|
* appreciated but is not required.
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
* misrepresented as being the original software.
|
* 3. This notice may not be removed or altered from any source distribution.
|
*/
|
|
package com.bulletphysics.collision.dispatch;
|
|
import java.util.Collections;
|
import com.bulletphysics.util.ObjectPool;
|
import com.bulletphysics.collision.broadphase.BroadphaseNativeType;
|
import com.bulletphysics.collision.broadphase.BroadphasePair;
|
import com.bulletphysics.collision.broadphase.CollisionAlgorithm;
|
import com.bulletphysics.collision.broadphase.CollisionAlgorithmConstructionInfo;
|
import com.bulletphysics.collision.broadphase.Dispatcher;
|
import com.bulletphysics.collision.broadphase.DispatcherInfo;
|
import com.bulletphysics.collision.broadphase.OverlapCallback;
|
import com.bulletphysics.collision.broadphase.OverlappingPairCache;
|
import com.bulletphysics.collision.narrowphase.PersistentManifold;
|
import com.bulletphysics.util.ObjectArrayList;
|
|
/**
|
* CollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs.
|
* Time of Impact, Closest Points and Penetration Depth.
|
*
|
* @author jezek2
|
*/
|
public class CollisionDispatcher extends Dispatcher {
|
|
protected final ObjectPool<PersistentManifold> manifoldsPool = ObjectPool.get(PersistentManifold.class);
|
|
private static final int MAX_BROADPHASE_COLLISION_TYPES = BroadphaseNativeType.MAX_BROADPHASE_COLLISION_TYPES.ordinal();
|
private int count = 0;
|
private final ObjectArrayList<PersistentManifold> manifoldsPtr = new ObjectArrayList<PersistentManifold>();
|
private boolean useIslands = true;
|
private boolean staticWarningReported = false;
|
private ManifoldResult defaultManifoldResult;
|
private NearCallback nearCallback;
|
//private PoolAllocator* m_collisionAlgorithmPoolAllocator;
|
//private PoolAllocator* m_persistentManifoldPoolAllocator;
|
private final CollisionAlgorithmCreateFunc[][] doubleDispatch = new CollisionAlgorithmCreateFunc[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
|
private CollisionConfiguration collisionConfiguration;
|
//private static int gNumManifold = 0;
|
|
private CollisionAlgorithmConstructionInfo tmpCI = new CollisionAlgorithmConstructionInfo();
|
|
public CollisionDispatcher(CollisionConfiguration collisionConfiguration) {
|
this.collisionConfiguration = collisionConfiguration;
|
|
setNearCallback(new DefaultNearCallback());
|
|
//m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool();
|
//m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool();
|
|
for (int i = 0; i < MAX_BROADPHASE_COLLISION_TYPES; i++) {
|
for (int j = 0; j < MAX_BROADPHASE_COLLISION_TYPES; j++) {
|
doubleDispatch[i][j] = collisionConfiguration.getCollisionAlgorithmCreateFunc(
|
BroadphaseNativeType.forValue(i),
|
BroadphaseNativeType.forValue(j)
|
);
|
assert (doubleDispatch[i][j] != null);
|
}
|
}
|
}
|
|
public void registerCollisionCreateFunc(int proxyType0, int proxyType1, CollisionAlgorithmCreateFunc createFunc) {
|
doubleDispatch[proxyType0][proxyType1] = createFunc;
|
}
|
|
public NearCallback getNearCallback() {
|
return nearCallback;
|
}
|
|
public void setNearCallback(NearCallback nearCallback) {
|
this.nearCallback = nearCallback;
|
}
|
|
public CollisionConfiguration getCollisionConfiguration() {
|
return collisionConfiguration;
|
}
|
|
public void setCollisionConfiguration(CollisionConfiguration collisionConfiguration) {
|
this.collisionConfiguration = collisionConfiguration;
|
}
|
|
@Override
|
public CollisionAlgorithm findAlgorithm(CollisionObject body0, CollisionObject body1, PersistentManifold sharedManifold) {
|
CollisionAlgorithmConstructionInfo ci = tmpCI;
|
ci.dispatcher1 = this;
|
ci.manifold = sharedManifold;
|
CollisionAlgorithmCreateFunc createFunc = doubleDispatch[body0.getCollisionShape().getShapeType().ordinal()][body1.getCollisionShape().getShapeType().ordinal()];
|
CollisionAlgorithm algo = createFunc.createCollisionAlgorithm(ci, body0, body1);
|
algo.internalSetCreateFunc(createFunc);
|
|
return algo;
|
}
|
|
@Override
|
public void freeCollisionAlgorithm(CollisionAlgorithm algo) {
|
CollisionAlgorithmCreateFunc createFunc = algo.internalGetCreateFunc();
|
algo.internalSetCreateFunc(null);
|
createFunc.releaseCollisionAlgorithm(algo);
|
algo.destroy();
|
}
|
|
@Override
|
public PersistentManifold getNewManifold(Object b0, Object b1) {
|
//gNumManifold++;
|
|
//btAssert(gNumManifold < 65535);
|
|
CollisionObject body0 = (CollisionObject)b0;
|
CollisionObject body1 = (CollisionObject)b1;
|
|
/*
|
void* mem = 0;
|
|
if (m_persistentManifoldPoolAllocator->getFreeCount())
|
{
|
mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold));
|
} else
|
{
|
mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
|
|
}
|
btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0);
|
manifold->m_index1a = m_manifoldsPtr.size();
|
m_manifoldsPtr.push_back(manifold);
|
*/
|
|
PersistentManifold manifold = manifoldsPool.get();
|
manifold.init(body0,body1,0);
|
|
manifold.index1a = manifoldsPtr.size();
|
manifoldsPtr.add(manifold);
|
|
return manifold;
|
}
|
|
@Override
|
public void releaseManifold(PersistentManifold manifold) {
|
//gNumManifold--;
|
|
//printf("releaseManifold: gNumManifold %d\n",gNumManifold);
|
clearManifold(manifold);
|
|
// TODO: optimize
|
int findIndex = manifold.index1a;
|
assert (findIndex < manifoldsPtr.size());
|
Collections.swap(manifoldsPtr, findIndex, manifoldsPtr.size()-1);
|
manifoldsPtr.getQuick(findIndex).index1a = findIndex;
|
manifoldsPtr.removeQuick(manifoldsPtr.size()-1);
|
|
manifoldsPool.release(manifold);
|
/*
|
manifold->~btPersistentManifold();
|
if (m_persistentManifoldPoolAllocator->validPtr(manifold))
|
{
|
m_persistentManifoldPoolAllocator->freeMemory(manifold);
|
} else
|
{
|
btAlignedFree(manifold);
|
}
|
*/
|
}
|
|
@Override
|
public void clearManifold(PersistentManifold manifold) {
|
manifold.clearManifold();
|
}
|
|
@Override
|
public boolean needsCollision(CollisionObject body0, CollisionObject body1) {
|
assert (body0 != null);
|
assert (body1 != null);
|
|
boolean needsCollision = true;
|
|
//#ifdef BT_DEBUG
|
if (!staticWarningReported) {
|
// broadphase filtering already deals with this
|
if ((body0.isStaticObject() || body0.isKinematicObject()) &&
|
(body1.isStaticObject() || body1.isKinematicObject())) {
|
staticWarningReported = true;
|
System.err.println("warning CollisionDispatcher.needsCollision: static-static collision!");
|
}
|
}
|
//#endif //BT_DEBUG
|
|
if ((!body0.isActive()) && (!body1.isActive())) {
|
needsCollision = false;
|
}
|
else if (!body0.checkCollideWith(body1)) {
|
needsCollision = false;
|
}
|
|
return needsCollision;
|
}
|
|
@Override
|
public boolean needsResponse(CollisionObject body0, CollisionObject body1) {
|
//here you can do filtering
|
boolean hasResponse = (body0.hasContactResponse() && body1.hasContactResponse());
|
//no response between two static/kinematic bodies:
|
hasResponse = hasResponse && ((!body0.isStaticOrKinematicObject()) || (!body1.isStaticOrKinematicObject()));
|
return hasResponse;
|
}
|
|
private static class CollisionPairCallback extends OverlapCallback {
|
private DispatcherInfo dispatchInfo;
|
private CollisionDispatcher dispatcher;
|
|
public void init(DispatcherInfo dispatchInfo, CollisionDispatcher dispatcher) {
|
this.dispatchInfo = dispatchInfo;
|
this.dispatcher = dispatcher;
|
}
|
|
public boolean processOverlap(BroadphasePair pair) {
|
dispatcher.getNearCallback().handleCollision(pair, dispatcher, dispatchInfo);
|
return false;
|
}
|
}
|
|
private CollisionPairCallback collisionPairCallback = new CollisionPairCallback();
|
|
@Override
|
public void dispatchAllCollisionPairs(OverlappingPairCache pairCache, DispatcherInfo dispatchInfo, Dispatcher dispatcher) {
|
//m_blockedForChanges = true;
|
collisionPairCallback.init(dispatchInfo, this);
|
pairCache.processAllOverlappingPairs(collisionPairCallback, dispatcher);
|
//m_blockedForChanges = false;
|
}
|
|
@Override
|
public int getNumManifolds() {
|
return manifoldsPtr.size();
|
}
|
|
@Override
|
public PersistentManifold getManifoldByIndexInternal(int index) {
|
return manifoldsPtr.getQuick(index);
|
}
|
|
@Override
|
public ObjectArrayList<PersistentManifold> getInternalManifoldPointer() {
|
return manifoldsPtr;
|
}
|
|
}
|