GameFramework.KdObjectTree.BuildImpl C# (CSharp) Method

BuildImpl() private method

private BuildImpl ( ) : void
return void
        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;
                }
            }
        }