public void AddObjForBuild(EntityInfo obj) { if (null == m_Objects[m_ObjectNum]) m_Objects[m_ObjectNum] = new KdTreeObject(obj); else m_Objects[m_ObjectNum].CopyFrom(obj); ++m_ObjectNum; }
public void BeginBuild(int count) { if (null == m_Objects || m_Objects.Length < count) { m_Objects = new KdTreeObject[count * 2]; } m_ObjectNum = 0; }
static public int get_Radius(IntPtr l) { try { GameFramework.KdTreeObject self = (GameFramework.KdTreeObject)checkSelf(l); pushValue(l, true); pushValue(l, self.Radius); return(2); } catch (Exception e) { return(error(l, e)); } }
public void AddObjForBuild(EntityInfo obj) { if (null == m_Objects[m_ObjectNum]) { m_Objects[m_ObjectNum] = new KdTreeObject(obj); } else { m_Objects[m_ObjectNum].CopyFrom(obj); } ++m_ObjectNum; }
static public int set_Position(IntPtr l) { try { GameFramework.KdTreeObject self = (GameFramework.KdTreeObject)checkSelf(l); ScriptRuntime.Vector3 v; checkValueType(l, 2, out v); self.Position = v; pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static public int set_Object(IntPtr l) { try { GameFramework.KdTreeObject self = (GameFramework.KdTreeObject)checkSelf(l); GameFramework.EntityInfo v; checkType(l, 2, out v); self.Object = v; pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static public int CopyFrom(IntPtr l) { try { GameFramework.KdTreeObject self = (GameFramework.KdTreeObject)checkSelf(l); GameFramework.EntityInfo a1; checkType(l, 2, out a1); self.CopyFrom(a1); pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static public int set_Radius(IntPtr l) { try { GameFramework.KdTreeObject self = (GameFramework.KdTreeObject)checkSelf(l); System.Single v; checkType(l, 2, out v); self.Radius = v; pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static public int constructor(IntPtr l) { try { GameFramework.KdTreeObject o; GameFramework.EntityInfo a1; checkType(l, 2, out a1); o = new GameFramework.KdTreeObject(a1); pushValue(l, true); pushValue(l, o); return(2); } catch (Exception e) { return(error(l, e)); } }
public void BeginBuild(int count) { if (null == m_Objects || m_Objects.Length < count) { m_Objects = new KdTreeObject[count * 2]; } m_ObjectNum = 0; for (int i = 0; i < m_Objects.Length; ++i) { var obj = m_Objects[i]; if (null != obj) { obj.Object = null; } } }
private void QueryImpl(Vector3 pos, float range, float rangeSq, MyFunc <float, KdTreeObject, bool> visitor) { m_QueryStack.Push(0); while (m_QueryStack.Count > 0) { int node = m_QueryStack.Pop(); int begin = m_KdTree[node].m_Begin; int end = m_KdTree[node].m_End; int left = m_KdTree[node].m_Left; int right = m_KdTree[node].m_Right; if (end > begin) { for (int i = begin; i < end; ++i) { KdTreeObject obj = m_Objects[i]; if (Geometry.RectangleOverlapRectangle(pos.X - range, pos.Z - range, pos.X + range, pos.Z + range, obj.MinX, obj.MinZ, obj.MaxX, obj.MaxZ)) { float distSq = Geometry.DistanceSquare(pos, obj.Position); if (!visitor(distSq, obj)) { m_QueryStack.Clear(); return; } } } } float minX = m_KdTree[node].m_MinX; float minZ = m_KdTree[node].m_MinZ; float maxX = m_KdTree[node].m_MaxX; float maxZ = m_KdTree[node].m_MaxZ; bool isVertical = (maxX - minX > maxZ - minZ); float splitValue = (isVertical ? 0.5f * (maxX + minX) : 0.5f * (maxZ + minZ)); if ((isVertical ? pos.X + range : pos.Z + range) < splitValue) { if (left > 0) { m_QueryStack.Push(left); } } else if ((isVertical ? pos.X - range : pos.Z - range) < splitValue) { if (left > 0) { m_QueryStack.Push(left); } if (right > 0) { m_QueryStack.Push(right); } } else { if (right > 0) { m_QueryStack.Push(right); } } } }
private void BuildImpl() { int nextUnusedNode = 1; m_BuildStack.Push(0); m_BuildStack.Push(m_ObjectNum); m_BuildStack.Push(0); while (m_BuildStack.Count >= 3) { int begin = m_BuildStack.Pop(); int end = m_BuildStack.Pop(); int node = m_BuildStack.Pop(); KdTreeObject obj0 = m_Objects[begin]; float minX = obj0.MinX; float maxX = obj0.MaxX; float minZ = obj0.MinZ; float maxZ = obj0.MaxZ; for (int i = begin + 1; i < end; ++i) { KdTreeObject obj = m_Objects[i]; float newMaxX = obj.MaxX; float newMinX = obj.MinX; float newMaxZ = obj.MaxZ; float newMinZ = obj.MinZ; if (minX > newMinX) { minX = newMinX; } if (maxX < newMaxX) { maxX = newMaxX; } if (minZ > newMinZ) { minZ = newMinZ; } if (maxZ < newMaxZ) { maxZ = newMaxZ; } } m_KdTree[node].m_MinX = minX; m_KdTree[node].m_MaxX = maxX; m_KdTree[node].m_MinZ = minZ; m_KdTree[node].m_MaxZ = maxZ; if (end - begin > c_MaxLeafSize) { m_KdTree[node].m_Left = nextUnusedNode; ++nextUnusedNode; m_KdTree[node].m_Right = nextUnusedNode; ++nextUnusedNode; bool isVertical = (maxX - minX > maxZ - minZ); float splitValue = (isVertical ? 0.5f * (maxX + minX) : 0.5f * (maxZ + minZ)); int begin0 = begin; int left = begin; int right = end; bool canSplit = false; while (left < right) { while (left < right) { KdTreeObject obj = m_Objects[left]; if ((isVertical ? obj.MaxX : obj.MaxZ) < splitValue) { ++left; canSplit = true; } else if ((isVertical ? obj.MinX : obj.MinZ) < splitValue) { obj.Indexed = true; break; } else { break; } } while (left < right) { KdTreeObject obj = m_Objects[right - 1]; if ((isVertical ? obj.MinX : obj.MinZ) >= splitValue) { --right; } else if ((isVertical ? obj.MaxX : obj.MaxZ) >= splitValue) { obj.Indexed = true; break; } else { break; } } if (left < right) { if (m_Objects[left].Indexed || m_Objects[right - 1].Indexed) { if (m_Objects[left].Indexed) { KdTreeObject tmp = m_Objects[begin]; m_Objects[begin] = m_Objects[left]; m_Objects[left] = tmp; ++begin; ++left; canSplit = true; } if (left < right && m_Objects[right - 1].Indexed) { KdTreeObject tmp = m_Objects[begin]; m_Objects[begin] = m_Objects[right - 1]; m_Objects[right - 1] = tmp; ++begin; if (begin >= left) { ++left; canSplit = true; } } } else { KdTreeObject tmp = m_Objects[left]; m_Objects[left] = m_Objects[right - 1]; m_Objects[right - 1] = tmp; ++left; --right; canSplit = true; } } } if (canSplit) { m_KdTree[node].m_Begin = begin0; m_KdTree[node].m_End = begin; if (left > begin) { m_BuildStack.Push(m_KdTree[node].m_Left); m_BuildStack.Push(left); m_BuildStack.Push(begin); } if (end > left) { m_BuildStack.Push(m_KdTree[node].m_Right); m_BuildStack.Push(end); m_BuildStack.Push(left); } } else { m_KdTree[node].m_Begin = begin0; m_KdTree[node].m_End = begin0; m_KdTree[node].m_Left = 0; m_KdTree[node].m_Right = 0; nextUnusedNode -= 2; } } else { m_KdTree[node].m_Begin = begin; m_KdTree[node].m_End = end; m_KdTree[node].m_Left = 0; m_KdTree[node].m_Right = 0; } } }
private void BuildImpl() { int nextUnusedNode = 1; m_BuildStack.Push(0); m_BuildStack.Push(m_ObjectNum); m_BuildStack.Push(0); while (m_BuildStack.Count >= 3) { int begin = m_BuildStack.Pop(); //待分类数据对象开始位置 int end = m_BuildStack.Pop(); //待分类数据对象结束位置的后一个位置 int node = m_BuildStack.Pop(); //kdtree上用来构造新结点的位置 KdTreeObject obj0 = m_Objects[begin]; float minX = obj0.MinX; float maxX = obj0.MaxX; float minZ = obj0.MinZ; float maxZ = obj0.MaxZ; for (int i = begin + 1; i < end; ++i) { KdTreeObject obj = m_Objects[i]; float newMaxX = obj.MaxX; float newMinX = obj.MinX; float newMaxZ = obj.MaxZ; float newMinZ = obj.MinZ; if (minX > newMinX) { minX = newMinX; } if (maxX < newMaxX) { maxX = newMaxX; } if (minZ > newMinZ) { minZ = newMinZ; } if (maxZ < newMaxZ) { maxZ = newMaxZ; } } m_KdTree[node].m_MinX = minX; m_KdTree[node].m_MaxX = maxX; m_KdTree[node].m_MinZ = minZ; m_KdTree[node].m_MaxZ = maxZ; if (end - begin > c_MaxLeafSize) { //kdtree上2个子结点的位置预留 m_KdTree[node].m_Left = nextUnusedNode; ++nextUnusedNode; m_KdTree[node].m_Right = nextUnusedNode; ++nextUnusedNode; bool isVertical = (maxX - minX > maxZ - minZ); float splitValue = (isVertical ? 0.5f * (maxX + minX) : 0.5f * (maxZ + minZ)); int begin0 = begin; int left = begin; int right = end; //接下来,变量涵义如下: //begin0为当前结点上挂的数据对象的起始位置 //begin为当前结点上挂的数据对象的结束位置的后一个位置,同时也是左子树的数据对象的起始位置 //left为左子树的数据对象的结束位置的后一个位置,也是待分类数据对象的起始位置 //right为当前已确定的右子树数据对象的起始位置 //end为右子树数据对象结束位置的后一个位置 bool canSplit = false; while (left < right) { while (left < right) { KdTreeObject obj = m_Objects[left]; if ((isVertical ? obj.MaxX : obj.MaxZ) < splitValue) { //obj为左子树上的数据对象,标记要拆分子树 ++left; canSplit = true; } else if ((isVertical ? obj.MinX : obj.MinZ) <= splitValue) { //obj为当前结点上的数据对象,后续要调整begin的数据与begin位置 obj.Indexed = true; break; } else { break; } } while (left < right) { KdTreeObject obj = m_Objects[right - 1]; if ((isVertical ? obj.MinX : obj.MinZ) > splitValue) { //obj为右子树上的数据对象,这里不需要标记拆分 --right; } else if ((isVertical ? obj.MaxX : obj.MaxZ) >= splitValue) { //obj为当前结点上的数据对象,后续要调整begin的数据与begin位置 obj.Indexed = true; break; } else { break; } } if (left < right) { if (m_Objects[left].Indexed || m_Objects[right - 1].Indexed) { if (m_Objects[left].Indexed) { KdTreeObject tmp = m_Objects[begin]; m_Objects[begin] = m_Objects[left]; m_Objects[left] = tmp; ++begin; ++left; canSplit = true; //将数据对象挂到当前结点上(数据交换到begin位置),begin后移一个位置,left也后移一个位置 } if (left < right && m_Objects[right - 1].Indexed) { KdTreeObject tmp = m_Objects[begin]; m_Objects[begin] = m_Objects[right - 1]; m_Objects[right - 1] = m_Objects[left]; m_Objects[left] = tmp; ++begin; ++left; canSplit = true; //将数据对象挂到当前结点上(数据交换到begin位置),left位置的数据对象放到right-1(继续处理),begin后移一个位置,left也后移一个位置 } //处理完要挂接的数据后,继续处理(可能left或right-1位置有一处是不合分类标准的数据) } else { KdTreeObject tmp = m_Objects[left]; m_Objects[left] = m_Objects[right - 1]; m_Objects[right - 1] = tmp; ++left; --right; canSplit = true; //left与right-1位置都是不符合分类标准的数据,交换数据后继续处理 } } } if (canSplit) { m_KdTree[node].m_Begin = begin0; m_KdTree[node].m_End = begin; if (left > begin) { m_BuildStack.Push(m_KdTree[node].m_Left); m_BuildStack.Push(left); m_BuildStack.Push(begin); } if (end > left) { m_BuildStack.Push(m_KdTree[node].m_Right); m_BuildStack.Push(end); m_BuildStack.Push(left); } } else { m_KdTree[node].m_Begin = begin0; m_KdTree[node].m_End = begin0; m_KdTree[node].m_Left = 0; m_KdTree[node].m_Right = 0; nextUnusedNode -= 2; } } else { m_KdTree[node].m_Begin = begin; m_KdTree[node].m_End = end; m_KdTree[node].m_Left = 0; m_KdTree[node].m_Right = 0; } } }
private bool Visit(MyFunc <float, KdTreeObject, bool> visitor, float distSqr, KdTreeObject obj) { try { return(visitor(distSqr, obj)); }catch (Exception ex) { LogSystem.Error("exception:{0}\n{1}", ex.Message, ex.StackTrace); return(false); } }