@Override public final int createProxy(final AABB aabb, Object userData) { final int node = allocateNode(); // Fatten the aabb final AABB nodeAABB = m_aabb[node]; nodeAABB.lowerBound.x = aabb.lowerBound.x - Settings.aabbExtension; nodeAABB.lowerBound.y = aabb.lowerBound.y - Settings.aabbExtension; nodeAABB.upperBound.x = aabb.upperBound.x + Settings.aabbExtension; nodeAABB.upperBound.y = aabb.upperBound.y + Settings.aabbExtension; m_userData[node] = userData; insertLeaf(node); return node; }
/** * Validate this tree. For testing. */ public void validate() { validateStructure(m_root); validateMetrics(m_root); int freeCount = 0; int freeNode = m_freeList; while (freeNode != NULL_NODE) { assert (0 <= freeNode && freeNode < m_nodeCapacity); freeNode = m_parent[freeNode]; ++freeCount; } assert (getHeight() == computeHeight()); assert (m_nodeCount + freeCount == m_nodeCapacity); }
@Override public final void destroyProxy(int proxyId) { assert (0 <= proxyId && proxyId < m_nodeCapacity); assert (m_child1[proxyId] == NULL_NODE); removeLeaf(proxyId); freeNode(proxyId); }
@Override public void drawTree(DebugDraw argDraw) { if (m_root == NULL_NODE) { return; } int height = computeHeight(); drawTree(argDraw, m_root, 0, height); }
removeLeaf(node); insertLeaf(proxyId); return true;
final int newParent = allocateNode(); m_parent[newParent] = oldParent; m_userData[newParent] = null; index = balance(index);
@Override public final int computeHeight() { return computeHeight(m_root); }
private final int allocateNode() { if (m_freeList == NULL_NODE) { assert (m_nodeCount == m_nodeCapacity); m_nodeCapacity *= 2; expandBuffers(m_nodeCount, m_nodeCapacity); } assert (m_freeList != NULL_NODE); int node = m_freeList; m_freeList = m_parent[node]; m_parent[node] = NULL_NODE; m_child1[node] = NULL_NODE; m_height[node] = 0; ++m_nodeCount; return node; }
public void drawTree(DebugDraw argDraw, int node, int spot, int height) { AABB a = m_aabb[node]; a.getVertices(drawVecs); color.set(1, (height - spot) * 1f / height, (height - spot) * 1f / height); argDraw.drawPolygon(drawVecs, 4, color); argDraw.getViewportTranform().getWorldToScreen(a.upperBound, textVec); argDraw.drawString(textVec.x, textVec.y, node + "-" + (spot + 1) + "/" + height, color); int c1 = m_child1[node]; int c2 = m_child2[node]; if (c1 != NULL_NODE) { drawTree(argDraw, c1, spot + 1, height); } if (c2 != NULL_NODE) { drawTree(argDraw, c2, spot + 1, height); } } }
private void validateMetrics(int node) { if (node == NULL_NODE) { return; } int child1 = m_child1[node]; int child2 = m_child2[node]; if (child1 == NULL_NODE) { assert (child1 == NULL_NODE); assert (child2 == NULL_NODE); assert (m_height[node] == 0); return; } assert (child1 != NULL_NODE && 0 <= child1 && child1 < m_nodeCapacity); assert (child2 != child1 && 0 <= child2 && child2 < m_nodeCapacity); int height1 = m_height[child1]; int height2 = m_height[child2]; int height; height = 1 + MathUtils.max(height1, height2); assert (m_height[node] == height); AABB aabb = new AABB(); aabb.combine(m_aabb[child1], m_aabb[child2]); assert (aabb.lowerBound.equals(m_aabb[node].lowerBound)); assert (aabb.upperBound.equals(m_aabb[node].upperBound)); validateMetrics(child1); validateMetrics(child2); }
@Override public final void destroyProxy(int proxyId) { assert (0 <= proxyId && proxyId < m_nodeCapacity); assert (m_child1[proxyId] == NULL_NODE); removeLeaf(proxyId); freeNode(proxyId); }
@Override public void drawTree(DebugDraw argDraw) { if (m_root == NULL_NODE) { return; } int height = computeHeight(); drawTree(argDraw, m_root, 0, height); }
removeLeaf(node); insertLeaf(proxyId); return true;
final int newParent = allocateNode(); m_parent[newParent] = oldParent; m_userData[newParent] = null; index = balance(index);
private final int computeHeight(int node) { assert (0 <= node && node < m_nodeCapacity); if (m_child1[node] == NULL_NODE) { return 0; } int height1 = computeHeight(m_child1[node]); int height2 = computeHeight(m_child2[node]); return 1 + MathUtils.max(height1, height2); }
public DynamicTreeFlatNodes() { m_root = NULL_NODE; m_nodeCount = 0; m_nodeCapacity = 16; expandBuffers(0, m_nodeCapacity); for (int i = 0; i < drawVecs.length; i++) { drawVecs[i] = new Vec2(); } }
public void drawTree(DebugDraw argDraw, int node, int spot, int height) { AABB a = m_aabb[node]; a.getVertices(drawVecs); color.set(1, (height - spot) * 1f / height, (height - spot) * 1f / height); argDraw.drawPolygon(drawVecs, 4, color); argDraw.getViewportTranform().getWorldToScreen(a.upperBound, textVec); argDraw.drawString(textVec.x, textVec.y, node + "-" + (spot + 1) + "/" + height, color); int c1 = m_child1[node]; int c2 = m_child2[node]; if (c1 != NULL_NODE) { drawTree(argDraw, c1, spot + 1, height); } if (c2 != NULL_NODE) { drawTree(argDraw, c2, spot + 1, height); } } }
private void validateMetrics(int node) { if (node == NULL_NODE) { return; } int child1 = m_child1[node]; int child2 = m_child2[node]; if (child1 == NULL_NODE) { assert (child1 == NULL_NODE); assert (child2 == NULL_NODE); assert (m_height[node] == 0); return; } assert (child1 != NULL_NODE && 0 <= child1 && child1 < m_nodeCapacity); assert (child2 != child1 && 0 <= child2 && child2 < m_nodeCapacity); int height1 = m_height[child1]; int height2 = m_height[child2]; int height; height = 1 + MathUtils.max(height1, height2); assert (m_height[node] == height); AABB aabb = new AABB(); aabb.combine(m_aabb[child1], m_aabb[child2]); assert (aabb.lowerBound.equals(m_aabb[node].lowerBound)); assert (aabb.upperBound.equals(m_aabb[node].upperBound)); validateMetrics(child1); validateMetrics(child2); }
/** * Validate this tree. For testing. */ public void validate() { validateStructure(m_root); validateMetrics(m_root); int freeCount = 0; int freeNode = m_freeList; while (freeNode != NULL_NODE) { assert (0 <= freeNode && freeNode < m_nodeCapacity); freeNode = m_parent[freeNode]; ++freeCount; } assert (getHeight() == computeHeight()); assert (m_nodeCount + freeCount == m_nodeCapacity); }