public virtual void GetAabb(BroadphaseProxy proxy, out IndexedVector3 aabbMin, out IndexedVector3 aabbMax) { MultiSapProxy multiProxy = (MultiSapProxy)(proxy); aabbMin = multiProxy.m_aabbMin; aabbMax = multiProxy.m_aabbMax; }
public bool TestAabbOverlap(BroadphaseProxy childProxy0, BroadphaseProxy childProxy1) { MultiSapProxy multiSapProxy0 = (MultiSapProxy)childProxy0.m_multiSapParentProxy; MultiSapProxy multiSapProxy1 = (MultiSapProxy)childProxy1.m_multiSapParentProxy; return(AabbUtil2.TestAabbAgainstAabb2(ref multiSapProxy0.m_aabbMin, ref multiSapProxy0.m_aabbMax, ref multiSapProxy1.m_aabbMin, ref multiSapProxy1.m_aabbMax)); }
public void AddToChildBroadphase(MultiSapProxy parentMultiSapProxy, BroadphaseProxy childProxy, IBroadphaseInterface childBroadphase) { BridgeProxy bridgeProxyRef = new BridgeProxy(); bridgeProxyRef.m_childProxy = childProxy; bridgeProxyRef.m_childBroadphase = childBroadphase; parentMultiSapProxy.m_bridgeProxies.Add(bridgeProxyRef); }
public virtual BroadphaseProxy CreateProxy(ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax, BroadphaseNativeTypes shapeType, Object userPtr, CollisionFilterGroups collisionFilterGroup, CollisionFilterGroups collisionFilterMask, IDispatcher dispatcher, Object multiSapProxy) { //void* ignoreMe -> we could think of recursive multi-sap, if someone is interested MultiSapProxy proxy = new MultiSapProxy(ref aabbMin, ref aabbMax, shapeType, userPtr, collisionFilterGroup, collisionFilterMask); m_multiSapProxies.Add(proxy); ///this should deal with inserting/removal into child broadphases SetAabb(proxy, ref aabbMin, ref aabbMax, dispatcher); return proxy; }
public virtual BroadphaseProxy CreateProxy(ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax, BroadphaseNativeTypes shapeType, Object userPtr, CollisionFilterGroups collisionFilterGroup, CollisionFilterGroups collisionFilterMask, IDispatcher dispatcher, Object multiSapProxy) { //void* ignoreMe -> we could think of recursive multi-sap, if someone is interested MultiSapProxy proxy = new MultiSapProxy(ref aabbMin, ref aabbMax, shapeType, userPtr, collisionFilterGroup, collisionFilterMask); m_multiSapProxies.Add(proxy); ///this should deal with inserting/removal into child broadphases SetAabb(proxy, ref aabbMin, ref aabbMax, dispatcher); return(proxy); }
public MyNodeOverlapCallback(MultiSapBroadphase multiSap, MultiSapProxy multiProxy, IDispatcher dispatcher) { m_multiSap = multiSap; m_multiProxy = multiProxy; m_dispatcher = dispatcher; }
public virtual void SetAabb(BroadphaseProxy proxy, ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax, IDispatcher dispatcher) { MultiSapProxy multiProxy = (MultiSapProxy)proxy; multiProxy.m_aabbMin = aabbMin; multiProxy.m_aabbMax = aabbMax; MyNodeOverlapCallback myNodeCallback = new MyNodeOverlapCallback(this, multiProxy, dispatcher); if (m_optimizedAabbTree != null) { m_optimizedAabbTree.ReportAabbOverlappingNodex(myNodeCallback, ref aabbMin, ref aabbMax); } for (int i = 0; i < multiProxy.m_bridgeProxies.Count; i++) { IndexedVector3 worldAabbMin; IndexedVector3 worldAabbMax; multiProxy.m_bridgeProxies[i].m_childBroadphase.GetBroadphaseAabb(out worldAabbMin, out worldAabbMax); bool overlapsBroadphase = AabbUtil2.TestAabbAgainstAabb2(ref worldAabbMin, ref worldAabbMax, ref multiProxy.m_aabbMin, ref multiProxy.m_aabbMax); if (!overlapsBroadphase) { //remove it now BridgeProxy bridgeProxy = multiProxy.m_bridgeProxies[i]; BroadphaseProxy childProxy = bridgeProxy.m_childProxy; bridgeProxy.m_childBroadphase.DestroyProxy(childProxy, dispatcher); multiProxy.m_bridgeProxies.RemoveAtQuick(i); } } /* * * if (1) * { * * //find broadphase that contain this multiProxy * int numChildBroadphases = getBroadphaseArray().size(); * for (int i=0;i<numChildBroadphases;i++) * { * btBroadphaseInterface* childBroadphase = getBroadphaseArray()[i]; * btVector3 worldAabbMin,worldAabbMax; * childBroadphase->getBroadphaseAabb(worldAabbMin,worldAabbMax); * bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax); * * // fullyContained = fullyContained || boxIsContainedWithinBox(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax); * int containingBroadphaseIndex = -1; * * //if already contains this * * for (int i=0;i<multiProxy->m_bridgeProxies.size();i++) * { * if (multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase) * { * containingBroadphaseIndex = i; * } * alreadyInSimple = alreadyInSimple || (multiProxy->m_bridgeProxies[i]->m_childBroadphase == m_simpleBroadphase); * } * * if (overlapsBroadphase) * { * if (containingBroadphaseIndex<0) * { * btBroadphaseProxy* childProxy = childBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher); * childProxy->m_multiSapParentProxy = multiProxy; * addToChildBroadphase(multiProxy,childProxy,childBroadphase); * } * } else * { * if (containingBroadphaseIndex>=0) * { * //remove * btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[containingBroadphaseIndex]; * * btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy; * bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher); * * multiProxy->m_bridgeProxies.swap( containingBroadphaseIndex,multiProxy->m_bridgeProxies.size()-1); * multiProxy->m_bridgeProxies.pop_back(); * } * } * } * * * ///If we are in no other child broadphase, stick the proxy in the global 'simple' broadphase (brute force) * ///hopefully we don't end up with many entries here (can assert/provide feedback on stats) * if (0)//!multiProxy->m_bridgeProxies.size()) * { * ///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision * ///this is needed to be able to calculate the aabb overlap * btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher); * childProxy->m_multiSapParentProxy = multiProxy; * addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase); * } * } * * if (!multiProxy->m_bridgeProxies.size()) * { * ///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision * ///this is needed to be able to calculate the aabb overlap * btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher); * childProxy->m_multiSapParentProxy = multiProxy; * addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase); * } */ //update for (int i = 0; i < multiProxy.m_bridgeProxies.Count; i++) { BridgeProxy bridgeProxyRef = multiProxy.m_bridgeProxies[i]; bridgeProxyRef.m_childBroadphase.SetAabb(bridgeProxyRef.m_childProxy, ref aabbMin, ref aabbMax, dispatcher); } }
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb public void CalculateOverlappingPairs(IDispatcher dispatcher) { if (!m_stopUpdating && GetOverlappingPairCache().HasDeferredRemoval()) { IList <BroadphasePair> overlappingPairArray = GetOverlappingPairCache().GetOverlappingPairArray(); ((List <BroadphasePair>)overlappingPairArray).Sort(); m_invalidPair = 0; int i; BroadphasePair previousPair = new BroadphasePair(); previousPair.m_pProxy0 = null; previousPair.m_pProxy1 = null; previousPair.m_algorithm = null; for (i = 0; i < overlappingPairArray.Count; i++) { BroadphasePair pair = overlappingPairArray[i]; MultiSapProxy aProxy0 = pair.m_pProxy0 != null ? (MultiSapProxy)pair.m_pProxy0.m_multiSapParentProxy : null; MultiSapProxy aProxy1 = pair.m_pProxy1 != null ? (MultiSapProxy)pair.m_pProxy1.m_multiSapParentProxy : null; MultiSapProxy bProxy0 = previousPair.m_pProxy0 != null ? (MultiSapProxy)previousPair.m_pProxy0.m_multiSapParentProxy : null; MultiSapProxy bProxy1 = previousPair.m_pProxy1 != null ? (MultiSapProxy)previousPair.m_pProxy1.m_multiSapParentProxy : null; bool isDuplicate = (aProxy0 == bProxy0) && (aProxy1 == bProxy1); previousPair = pair; bool needsRemoval = false; if (!isDuplicate) { bool hasOverlap = TestAabbOverlap(pair.m_pProxy0, pair.m_pProxy1); if (hasOverlap) { needsRemoval = false;//callback->processOverlap(pair); } else { needsRemoval = true; } } else { //remove duplicate needsRemoval = true; //should have no algorithm Debug.Assert(pair.m_algorithm == null); } if (needsRemoval) { GetOverlappingPairCache().CleanOverlappingPair(pair, dispatcher); // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); // m_overlappingPairArray.pop_back(); pair.m_pProxy0 = null; pair.m_pProxy1 = null; m_invalidPair++; BulletGlobals.gOverlappingPairs--; } } ///if you don't like to skip the invalid pairs in the array, execute following code: //#define CLEAN_INVALID_PAIRS 1 //#ifdef CLEAN_INVALID_PAIRS // //perform a sort, to sort 'invalid' pairs to the end // //overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate()); // overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate()); // overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); // m_invalidPair = 0; //#endif//CLEAN_INVALID_PAIRS //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size()); } }