public BroadPhase(AABB worldAABB, PairCallback callback) { if (debugPrint) { System.out.println("BroadPhase()"); } // array initialization m_proxyPool = new Proxy[Settings.maxProxies]; pairBuffer = new BufferedPair[Settings.maxPairs]; m_bounds = new Bound[2][2 * Settings.maxProxies]; m_queryResults = new int[Settings.maxProxies]; for (int i = 0; i < 2 * Settings.maxProxies; i++) { m_bounds[0][i] = new Bound(); m_bounds[1][i] = new Bound(); } for (int i = 0; i < Settings.maxProxies; i++) { pairBuffer[i] = new BufferedPair(); } m_pairManager = new PairManager(); m_pairManager.initialize(this, callback); assert worldAABB.isValid(); m_worldAABB = new AABB(worldAABB); m_proxyCount = 0; Vec2 d = worldAABB.upperBound.sub(worldAABB.lowerBound); m_quantizationFactor = new Vec2(Integer.MAX_VALUE / d.x, Integer.MAX_VALUE / d.y); for (int i = 0; i < Settings.maxProxies - 1; ++i) { m_proxyPool[i] = new Proxy(); m_proxyPool[i].setNext(i + 1); m_proxyPool[i].timeStamp = 0; m_proxyPool[i].overlapCount = INVALID; m_proxyPool[i].userData = null; } m_proxyPool[Settings.maxProxies - 1] = new Proxy(); m_proxyPool[Settings.maxProxies - 1].setNext(PairManager.NULL_PROXY); m_proxyPool[Settings.maxProxies - 1].timeStamp = 0; m_proxyPool[Settings.maxProxies - 1].overlapCount = INVALID; m_proxyPool[Settings.maxProxies - 1].userData = null; m_freeProxy = 0; m_timeStamp = 1; m_queryResultCount = 0; }
// Call MoveProxy as many times as you like, then when you are done // call Flush to finalized the proxy pairs (for your time step). void moveProxy(int proxyId, AABB aabb) { if (debugPrint) { System.out.println("MoveProxy()"); } if (proxyId == PairManager.NULL_PROXY || Settings.maxProxies <= proxyId) { return; } assert (aabb.isValid()) : "invalid AABB"; int boundCount = 2 * m_proxyCount; Proxy proxy = m_proxyPool[proxyId]; // Get new bound values BoundValues newValues = new BoundValues(); computeBounds(newValues.lowerValues, newValues.upperValues, aabb); // Get old bound values BoundValues oldValues = new BoundValues(); for (int axis = 0; axis < 2; ++axis) { oldValues.lowerValues[axis] = m_bounds[axis][proxy.lowerBounds[axis]].value; oldValues.upperValues[axis] = m_bounds[axis][proxy.upperBounds[axis]].value; } for (int axis = 0; axis < 2; ++axis) { Bound[] bounds = m_bounds[axis]; int lowerIndex = proxy.lowerBounds[axis]; int upperIndex = proxy.upperBounds[axis]; int lowerValue = newValues.lowerValues[axis]; int upperValue = newValues.upperValues[axis]; int deltaLower = lowerValue - bounds[lowerIndex].value; int deltaUpper = upperValue - bounds[upperIndex].value; bounds[lowerIndex].value = lowerValue; bounds[upperIndex].value = upperValue; // // Expanding adds overlaps // // Should we move the lower bound down? if (deltaLower < 0) { int index = lowerIndex; while (index > 0 && lowerValue < bounds[index - 1].value) { Bound bound = bounds[index]; Bound prevBound = bounds[index - 1]; int prevProxyId = prevBound.proxyId; Proxy prevProxy = m_proxyPool[prevBound.proxyId]; ++prevBound.stabbingCount; if (prevBound.isUpper() == true) { if (testOverlap(newValues, prevProxy)) { m_pairManager.addBufferedPair(proxyId, prevProxyId); } ++prevProxy.upperBounds[axis]; ++bound.stabbingCount; } else { ++prevProxy.lowerBounds[axis]; --bound.stabbingCount; } --proxy.lowerBounds[axis]; // b2Swap(*bound, *prevEdge); Bound tmp = new Bound(bound); bound.set(prevBound); prevBound.set(tmp); --index; } } // Should we move the upper bound up? if (deltaUpper > 0) { int index = upperIndex; while (index < boundCount - 1 && bounds[index + 1].value <= upperValue) { Bound bound = bounds[index]; Bound nextBound = bounds[index + 1]; int nextProxyId = nextBound.proxyId; Proxy nextProxy = m_proxyPool[nextProxyId]; ++nextBound.stabbingCount; if (nextBound.isLower() == true) { if (testOverlap(newValues, nextProxy)) { m_pairManager.addBufferedPair(proxyId, nextProxyId); } --nextProxy.lowerBounds[axis]; ++bound.stabbingCount; } else { --nextProxy.upperBounds[axis]; --bound.stabbingCount; } ++proxy.upperBounds[axis]; // b2Swap(*bound, *nextEdge); // wasn't actually swapping! bounds[index] and // bounds[index+1] need to be swapped by VALUE Bound tmp = new Bound(bound); bound.set(nextBound); nextBound.set(tmp); ++index; } } // // Shrinking removes overlaps // // Should we move the lower bound up? if (deltaLower > 0) { int index = lowerIndex; while (index < boundCount - 1 && bounds[index + 1].value <= lowerValue) { Bound bound = bounds[index]; Bound nextBound = bounds[index + 1]; int nextProxyId = nextBound.proxyId; Proxy nextProxy = m_proxyPool[nextProxyId]; --nextBound.stabbingCount; if (nextBound.isUpper()) { if (testOverlap(oldValues, nextProxy)) { m_pairManager.removeBufferedPair(proxyId, nextProxyId); } --nextProxy.upperBounds[axis]; --bound.stabbingCount; } else { --nextProxy.lowerBounds[axis]; ++bound.stabbingCount; } ++proxy.lowerBounds[axis]; // b2Swap(*bound, *nextEdge); // Bound tmp = bound; // bound = nextEdge; // nextEdge = tmp; Bound tmp = new Bound(bound); bound.set(nextBound); nextBound.set(tmp); ++index; } } // Should we move the upper bound down? if (deltaUpper < 0) { int index = upperIndex; while (index > 0 && upperValue < bounds[index - 1].value) { Bound bound = bounds[index]; Bound prevBound = bounds[index - 1]; int prevProxyId = prevBound.proxyId; Proxy prevProxy = m_proxyPool[prevProxyId]; --prevBound.stabbingCount; if (prevBound.isLower() == true) { if (testOverlap(oldValues, prevProxy)) { m_pairManager.removeBufferedPair(proxyId, prevProxyId); } ++prevProxy.lowerBounds[axis]; --bound.stabbingCount; } else { ++prevProxy.upperBounds[axis]; ++bound.stabbingCount; } --proxy.upperBounds[axis]; // b2Swap(*bound, *prevEdge); // Bound tmp = bound; // bound = prevEdge; // prevEdge = tmp; Bound tmp = new Bound(bound); bound.set(prevBound); prevBound.set(tmp); --index; } } } if (s_validate) { validate(); } }