コード例 #1
0
 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;
 }
コード例 #2
0
 public void BeginBuild(int count)
 {
     if (null == m_Objects || m_Objects.Length < count)
     {
         m_Objects = new KdTreeObject[count * 2];
     }
     m_ObjectNum = 0;
 }
コード例 #3
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));
     }
 }
コード例 #4
0
 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;
 }
コード例 #5
0
 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));
     }
 }
コード例 #6
0
 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));
     }
 }
コード例 #7
0
 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));
     }
 }
コード例 #8
0
 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));
     }
 }
コード例 #9
0
 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));
     }
 }
コード例 #10
0
 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;
         }
     }
 }
コード例 #11
0
        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);
                    }
                }
            }
        }
コード例 #12
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();

                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;
                }
            }
        }
コード例 #13
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;
                }
            }
        }
コード例 #14
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);
     }
 }