public DbvtBroadphase(IOverlappingPairCache paircache) { m_sets[0] = new Dbvt(); m_sets[1] = new Dbvt(); m_deferedcollide = false; m_needcleanup = true; m_releasepaircache = (paircache != null) ? false : true; m_prediction = 0; m_stageCurrent = 0; m_fixedleft = 0; m_fupdates = 1; m_dupdates = 0; m_cupdates = 10; m_newpairs = 1; m_updates_call = 0; m_updates_done = 0; m_updates_ratio = 0; m_paircache = paircache != null ? paircache : new HashedOverlappingPairCache(); m_gid = 0; m_pid = 0; m_cid = 0; #if DBVT_BP_PROFILE m_profiling = new ProfileBlock(); m_profiling.clear(); #endif }
public DbvtNode(Dbvt tree, DbvtNode aparent, ref DbvtAabbMm avolume, Object adata) { volume = avolume; parent = aparent; data = adata; if (data is int) { dataAsInt = (int)data; } }
public CompoundShape(bool enableDynamicAabbTree) { m_children = new List<CompoundShapeChild>(); m_localAabbMax = new Vector3(float.MinValue, float.MinValue, float.MinValue); m_localAabbMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); m_collisionMargin = 0f; m_localScaling = new Vector3(1f, 1f, 1f); m_dynamicAabbTree = null; m_updateRevision = 1; m_shapeType = BroadphaseNativeTypes.COMPOUND_SHAPE_PROXYTYPE; if (enableDynamicAabbTree) { m_dynamicAabbTree = new Dbvt(); } }
public static DbvtNode RemoveLeaf(Dbvt pdbvt, DbvtNode leaf) { if (leaf == pdbvt.Root) { pdbvt.Root = null; return null; } else { DbvtNode parent = leaf.parent; DbvtNode prev = parent.parent; DbvtNode sibling = parent._children[1 - IndexOf(leaf)]; if (prev != null) { prev._children[IndexOf(parent)] = sibling; sibling.parent = prev; DeleteNode(pdbvt, ref parent); while (prev != null) { DbvtAabbMm pb = prev.volume; DbvtAabbMm.Merge(ref prev._children[0].volume, ref prev._children[1].volume, ref prev.volume); if (DbvtAabbMm.NotEqual(ref pb, ref prev.volume)) { sibling = prev; prev = prev.parent; } else { break; } } return (prev != null ? prev : pdbvt.Root); } else { pdbvt.Root = sibling; sibling.parent = null; DeleteNode(pdbvt, ref parent); return (pdbvt.Root); } } }
public static void DeleteNode(Dbvt dbvt, ref DbvtNode node) { node = null; }
public static void InsertLeaf(Dbvt pdbvt, DbvtNode root, DbvtNode leaf) { if (pdbvt.Root == null) { pdbvt.Root = leaf; leaf.parent = null; } else { if (!root.IsLeaf()) { do { if (DbvtAabbMm.Proximity(ref root._children[0].volume, ref leaf.volume) < DbvtAabbMm.Proximity(ref root._children[1].volume, ref leaf.volume)) { root = root._children[0]; } else { root = root._children[1]; } } while (!root.IsLeaf()); } DbvtNode prev = root.parent; DbvtAabbMm mergeResults = DbvtAabbMm.Merge(ref leaf.volume, ref root.volume); DbvtNode node = new DbvtNode(pdbvt, prev, ref mergeResults, null); if (prev != null) { prev._children[IndexOf(root)] = node; node._children[0] = root; root.parent = node; node._children[1] = leaf; leaf.parent = node; do { if (!prev.volume.Contain(ref node.volume)) { DbvtAabbMm.Merge(ref prev._children[0].volume, ref prev._children[1].volume, ref prev.volume); } else { break; } node = prev; } while (null != (prev = node.parent)); } else { node._children[0] = root; root.parent = node; node._children[1] = leaf; leaf.parent = node; pdbvt.Root = node; } } }
public static DbvtNode TopDown(Dbvt pdbvt, List<DbvtNode> leafs, int bu_treshold) { if (leafs.Count > 1) { if (leafs.Count > bu_treshold) { DbvtAabbMm volume = Bounds(leafs); Vector3 org = volume.Center(); List<DbvtNode>[] sets = { new List<DbvtNode>(), new List<DbvtNode>() }; int bestaxis = -1; int bestmidp = leafs.Count; int[] a1 = new int[] { 0, 0 }; int[] a2 = new int[] { 0, 0 }; int[] a3 = new int[] { 0, 0 }; int[][] splitcount = new int[][] { a1, a2, a3 }; for (int i = 0; i < leafs.Count; ++i) { Vector3 x = leafs[i].volume.Center() - org; for (int j = 0; j < 3; ++j) { ++splitcount[j][Vector3.Dot(x, axis[j]) > 0 ? 1 : 0]; } } for (int i = 0; i < 3; ++i) { if ((splitcount[i][0] > 0) && (splitcount[i][1] > 0)) { int midp = (int)System.Math.Abs((splitcount[i][0] - splitcount[i][1])); if (midp < bestmidp) { bestaxis = i; bestmidp = midp; } } } if (bestaxis >= 0) { sets[0].Capacity = (splitcount[bestaxis][0]); sets[1].Capacity = (splitcount[bestaxis][1]); Split(leafs, sets[0], sets[1], ref org, ref axis[bestaxis]); } else { sets[0].Capacity = (leafs.Count / 2 + 1); sets[1].Capacity = (leafs.Count / 2); for (int i = 0, ni = leafs.Count; i < ni; ++i) { sets[i & 1].Add(leafs[i]); } } DbvtNode node = new DbvtNode(pdbvt, null, ref volume, null); node._children[0] = TopDown(pdbvt, sets[0], bu_treshold); node._children[1] = TopDown(pdbvt, sets[1], bu_treshold); node._children[0].parent = node; node._children[1].parent = node; return (node); } else { BottomUp(pdbvt, leafs); return (leafs[0]); } } return (leafs[0]); }
// public static void BottomUp(Dbvt pdbvt, List<DbvtNode> leafs) { while (leafs.Count > 1) { float minsize = float.MaxValue; int[] minidx = { -1, -1 }; for (int i = 0; i < leafs.Count; ++i) { for (int j = i + 1; j < leafs.Count; ++j) { DbvtAabbMm mergeResults = DbvtAabbMm.Merge(ref leafs[i].volume, ref leafs[j].volume); float sz = Size(ref mergeResults); if (sz < minsize) { minsize = sz; minidx[0] = i; minidx[1] = j; } } } DbvtNode[] n = { leafs[minidx[0]], leafs[minidx[1]] }; DbvtAabbMm mergeResults2 = DbvtAabbMm.Merge(ref n[0].volume, ref n[1].volume); DbvtNode p = new DbvtNode(pdbvt, null, ref mergeResults2, null); p._children[0] = n[0]; p._children[1] = n[1]; n[0].parent = p; n[1].parent = p; leafs[minidx[0]] = p; DbvtNode left = leafs[minidx[1]]; DbvtNode right = leafs[leafs.Count - 1]; leafs[minidx[1]] = right; leafs[leafs.Count - 1] = left; leafs.RemoveAt(leafs.Count - 1); } }
public static void FetchLeafs(Dbvt pdbvt, DbvtNode root, List<DbvtNode> leafs, int depth) { if (root.IsInternal() && depth != 0) { FetchLeafs(pdbvt, root._children[0], leafs, depth - 1); FetchLeafs(pdbvt, root._children[1], leafs, depth - 1); DeleteNode(pdbvt, ref root); } else { leafs.Add(root); } }
// // depth is defaulted to -1 public static void FetchLeafs(Dbvt pdbvt, DbvtNode root, List<DbvtNode> leafs) { FetchLeafs(pdbvt, root, leafs, -1); }