Beispiel #1
0
        public static SpaceNode CreateSpaceNodeWithBounds(Bounds bounds)
        {
            var spaceNode = new SpaceNode();

            spaceNode.Bounds = bounds;
            return(spaceNode);
        }
Beispiel #2
0
        private List <SpaceNode> CreateChildSpaceNodes(SpaceNode parentNode)
        {
            List <SpaceNode> childSpaceNodes = new List <SpaceNode>(4);

            float size   = parentNode.Bounds.size.x;
            float extend = size * 0.5f;
            float offset = extend * 0.5f;

            Vector3 center          = parentNode.Bounds.center;
            Vector3 looseBoundsSize = new Vector3(extend + m_looseSize, size, extend + m_looseSize);

            childSpaceNodes.Add(
                SpaceNode.CreateSpaceNodeWithBounds(
                    new Bounds(center + new Vector3(-offset, 0.0f, -offset), looseBoundsSize)
                    ));
            childSpaceNodes.Add(
                SpaceNode.CreateSpaceNodeWithBounds(
                    new Bounds(center + new Vector3(-offset, 0.0f, offset), looseBoundsSize)
                    ));
            childSpaceNodes.Add(
                SpaceNode.CreateSpaceNodeWithBounds(
                    new Bounds(center + new Vector3(offset, 0.0f, -offset), looseBoundsSize)
                    ));
            childSpaceNodes.Add(
                SpaceNode.CreateSpaceNodeWithBounds(
                    new Bounds(center + new Vector3(offset, 0.0f, offset), looseBoundsSize)
                    ));

            return(childSpaceNodes);
        }
Beispiel #3
0
        public SpaceNode CreateSpaceTree(Bounds initBounds, List <GameObject> targetObjects, Action <float> onProgress)
        {
            SpaceNode rootNode = new SpaceNode();

            rootNode.Bounds = initBounds;

            if (onProgress != null)
            {
                onProgress(0.0f);
            }

            for (int oi = 0; oi < targetObjects.Count; ++oi)
            {
                Bounds?objectBounds = CalculateBounds(targetObjects[oi]);
                if (objectBounds == null)
                {
                    continue;
                }

                SpaceNode target = rootNode;

                while (true)
                {
                    if (target.Bounds.size.x > m_minSize)
                    {
                        if (target.ChildTreeNodes == null)
                        {
                            target.ChildTreeNodes = CreateChildSpaceNodes(target);
                        }


                        //the object can be in the over 2 nodes.
                        //we should figure out which node is more close with the object.
                        int   nearestChild    = -1;
                        float nearestDistance = float.MaxValue;

                        for (int ci = 0; ci < target.ChildTreeNodes.Count; ++ci)
                        {
                            if (objectBounds.Value.IsPartOf(target.ChildTreeNodes[ci].Bounds))
                            {
                                float dist = Vector3.Distance(target.ChildTreeNodes[ci].Bounds.center, objectBounds.Value.center);

                                if (dist < nearestDistance)
                                {
                                    nearestChild    = ci;
                                    nearestDistance = dist;
                                }
                            }
                        }

                        //We should find out it until we get the fit size from the bottom.
                        //this means the object is small to add in the current node.
                        if (nearestChild >= 0)
                        {
                            target = target.ChildTreeNodes[nearestChild];
                            continue;
                        }
                    }

                    target.Objects.Add(targetObjects[oi]);
                    break;
                }

                if (onProgress != null)
                {
                    onProgress((float)oi / (float)targetObjects.Count);
                }
            }

            return(rootNode);
        }
        public SpaceNode CreateSpaceTree(Bounds initBounds, float chunkSize, Vector3 rootPosition, List <GameObject> targetObjects, Action <float> onProgress)
        {
            SpaceNode rootNode = new SpaceNode();

            rootNode.Bounds = initBounds;

            if (onProgress != null)
            {
                onProgress(0.0f);
            }

            //space split first
            Stack <SpaceNode> nodeStack = new Stack <SpaceNode>();

            nodeStack.Push(rootNode);

            while (nodeStack.Count > 0)
            {
                SpaceNode node = nodeStack.Pop();
                if (node.Bounds.size.x > chunkSize)
                {
                    List <SpaceNode> childNodes = CreateChildSpaceNodes(node);

                    for (int i = 0; i < childNodes.Count; ++i)
                    {
                        childNodes[i].ParentNode = node;
                        nodeStack.Push(childNodes[i]);
                    }
                }
            }

            if (targetObjects == null)
            {
                return(rootNode);
            }

            for (int oi = 0; oi < targetObjects.Count; ++oi)
            {
                Bounds?objectBounds = CalculateBounds(targetObjects[oi], rootPosition);
                if (objectBounds == null)
                {
                    continue;
                }

                SpaceNode target = rootNode;

                while (true)
                {
                    if (target.HasChild())
                    {
                        //the object can be in the over 2 nodes.
                        //we should figure out which node is more close with the object.
                        int   nearestChild    = -1;
                        float nearestDistance = float.MaxValue;

                        for (int ci = 0; ci < target.GetChildCount(); ++ci)
                        {
                            if (objectBounds.Value.IsPartOf(target.GetChild(ci).Bounds))
                            {
                                float dist = Vector3.Distance(target.GetChild(ci).Bounds.center, objectBounds.Value.center);

                                if (dist < nearestDistance)
                                {
                                    nearestChild    = ci;
                                    nearestDistance = dist;
                                }
                            }
                        }

                        //We should find out it until we get the fit size from the bottom.
                        //this means the object is small to add in the current node.
                        if (nearestChild >= 0)
                        {
                            target = target.GetChild(nearestChild);
                            continue;
                        }
                    }

                    target.Objects.Add(targetObjects[oi]);
                    break;
                }

                if (onProgress != null)
                {
                    onProgress((float)oi / (float)targetObjects.Count);
                }
            }

            return(rootNode);
        }