public void UpdateData(string action, string key, string psr)
        {
            bool isItemInDictionary = itemDictionary.ContainsKey(key);

            if (action == "child_added" || action == "child_changed")
            {
                if (isItemInDictionary)
                {
                    // Set existing data entry
                    ItemData existingItem;
                    bool     exists = itemDictionary.TryGetValue(key, out existingItem);
                    // re-add the item again into the tree, as it is not possible to move it directly to another position
                    itemTree.Remove(existingItem);
                    existingItem.CalculatePSR(psr);
                    itemTree.Add(existingItem, existingItem.Position);
                    // set existing item game object, because we want nearby data update to be immediate
                    if (existingItem.DistanceTo(Camera.main.transform) <= visibleDistance)
                    {
                        SetChild(existingItem);
                    }
                }
                else
                {
                    // Add data entry
                    var item = new ItemData(key, psr);
                    itemTree.Add(item, item.Position);
                    itemDictionary.Add(item.Key, item);
                    // create object if it is nearby
                    if (item.DistanceTo(Camera.main.transform) <= visibleDistance)
                    {
                        CreateChild(item);
                    }
                }
            }
            else if (action == "child_removed")
            {
                if (isItemInDictionary)
                {
                    var existingItem = itemDictionary[key];
                    itemTree.Remove(existingItem);
                    itemDictionary.Remove(key);
                    RemoveChild(existingItem);
                }
            }
            // Start Proximity Check If not yet
            if (coroutine == null)
            {
                coroutine = CoroutineSpawnDespawnChildren(manageGameObjectInterval);
                StartCoroutine(coroutine);
            }
        }
Beispiel #2
0
 public static void Update(ServerWorldEntity entity)
 {
     lock (octree)
     {
         octree.Remove(entity);
         Register(entity);
     }
 }
Beispiel #3
0
        // Use this for initialization
        IEnumerator Start()
        {
            {
                for (int x = -99; x <= 99; x += 6)
                {
                    for (int y = -99; y <= 99; y += 6)
                    {
                        for (int z = -99; z <= 99; z += 6)
                        {
                            positions.Add(new Vector3(x, y, z));
                        }
                    }
                }
            }
            tree = new LooseOctree <GameObject>(200F, Vector3.zero, 1.25F, positions.Count);
            numObjectsDisplay.text = "Objects per iteration: " + positions.Count;
            float[] buildResults = new float[20];
            float   buildTotal   = 0;

            float[] destroyResults = new float[20];
            float   destroyTotal   = 0;

            Stopwatch timer = new Stopwatch();

            for (int i = 0; i < buildResults.Length; i++)
            {
                iterationsDisplay.text = "Iterations: " + (i + 1);
                buildResults[i]        = PopulateTree(timer);
                timer.Stop();
                buildTotal             += buildResults[i];
                numNodesDisplay.text    = "Nodes per iteration: " + tree.nodeCount;
                destroyResults[i]       = DestroyTree(timer);
                destroyTotal           += destroyResults[i];
                averageTimeDisplay.text = "Average time: Build(" + Mathf.Round(buildTotal / (i + 1)) + "ms) - Destroy(" + Mathf.Round(destroyTotal / (i + 1)) + "ms)";
                totalTimeDisplay.text   = "Total time: Build(" + buildTotal + "ms) - Destroy(" + destroyTotal + "ms)";
                yield return(new WaitForSeconds(0.1F));
            }
            PopulateTree(timer);
            pointTree = new PointOctree <OctreeObject <GameObject> >(200F, Vector3.zero, 1.25F);
            OctreeObject <GameObject>          obj;
            Queue <OctreeObject <GameObject> > remObj = new Queue <OctreeObject <GameObject> >();

            timer.Reset();
            while (treeObj.Count > 0)
            {
                obj = treeObj.Dequeue();
                timer.Start();
                pointTree.Add(obj, obj.boundsCenter);
                timer.Stop();
                remObj.Enqueue(obj);
            }
            pointTreeAddTimeDisplay.text = timer.ElapsedMilliseconds + "ms";
            timer.Reset();
            while (remObj.Count > 0)
            {
                obj = remObj.Dequeue();
                timer.Start();
                pointTree.Remove(obj);
                timer.Stop();
            }
            pointTreeRemoveTimeDisplay.text = timer.ElapsedMilliseconds + "ms";
            averageTimeDisplay.text         = "Average time: Build(" + buildTotal / buildResults.Length + "ms) - Destroy(" + destroyTotal / destroyResults.Length + "ms)";
            StartCoroutine(PopulateTreeSlow());
        }
        /// <summary>
        /// Runs current tracked object data through Octree.
        /// </summary>
        private TrackedObjectStates evaluateOctree(OctreeThreadParameters otp)
        {
            int alloc = WorldMonitor.Instance.AllocationSpace;

            updatePositions = new Vector3[alloc];  // otp.ObjectIDs.Count
            float[] thresholds = new float[alloc]; // otp.ObjectIDs.Count

            //for (int i = 0; i < otp.ObjectIDs.Count; i++)
            foreach (int id in otp.ObjectIDs)
            {
                KeyValuePair <float, Vector3> pos;

                if (!otp.Coordinates.TryGetValue(id, out pos))
                {
                    Debug.LogError("unknown object position request in octree eval");
                }

                thresholds[id]      = pos.Key;
                updatePositions[id] = pos.Value;

                PointOctree.Remove(id);
                PointOctree.Add(id, pos.Value);
            }

            List <int[]> enteringIDs = new List <int[]>();
            List <int[]> leavingIDs  = new List <int[]>();

            List <int> parentIDLeavers  = new List <int>();
            List <int> parentIDEnterers = new List <int>();

            int ind = 0;

            foreach (int id in otp.ObjectIDs)
            {
                List <int> validConflicts = new List <int>();
                List <int> stayers        = new List <int>();

                int[] areaObjects = PointOctree.GetNearby(updatePositions[id], thresholds[id]);

                for (int j = 0; j < areaObjects.Length; j++)
                {
                    string affiliateObj     = WorldMonitor.Instance.TrackedObjectAffiliations[id];
                    string affiliateCompare = WorldMonitor.Instance.TrackedObjectAffiliations[areaObjects[j]];

                    /*
                     * run conflict validity checks: if not the same object && not an object of the same class type && is a new conflict
                     */

                    if (areaObjects[j] != id && !MasterList[id].Contains(areaObjects[j]) && string.Compare(affiliateObj, affiliateCompare) != 0)
                    {
                        if (!parentIDEnterers.Contains(id))
                        {
                            parentIDEnterers.Add(id);
                        }

                        MasterList[id].Add(areaObjects[j]); // add conflicting object to master list of current conflicts
                        validConflicts.Add(areaObjects[j]); // *new* conflicts
                        stayers.Add(areaObjects[j]);        // use to look for conflicts that have ended
                    }
                    else if (MasterList[id].Contains(areaObjects[j]))
                    {
                        stayers.Add(areaObjects[j]); // this is an object staying in conflict
                    }
                }

                bool       leaverDetected = false;
                List <int> leavers        = new List <int>();

                foreach (int _id in MasterList[id]) // look at master list's record of conflicts for this parent ID - if it isn't in stayers, it has left the conflict area or been destroyed
                {
                    if (!stayers.Contains(_id))
                    {
                        leaverDetected = true;
                        leavers.Add(_id);
                    }

                    switch (WorldMonitor.Instance.ConflictEndMode)
                    {
                    case ConflictEndMode.OnAllConflictsEnded:
                        if (leavers.Count == MasterList[id].Count)
                        {
                            parentIDLeavers.Add(id);
                        }
                        break;

                    case ConflictEndMode.OnIndividualConflictEnded:
                        if (leaverDetected && !parentIDEnterers.Contains(id) && !parentIDLeavers.Contains(id))
                        {
                            parentIDLeavers.Add(id);
                        }
                        break;
                    }
                }

                foreach (int leaver in leavers)
                {
                    MasterList[id].Remove(leaver);
                }

                int numValid = leavers.ToArray().Length;

                if (numValid > 0)
                {
                    leavingIDs.Add(leavers.ToArray());
                }

                numValid = validConflicts.ToArray().Length;

                if (numValid > 0)
                {
                    enteringIDs.Add(validConflicts.ToArray());
                }

                ind++;
            }

            return(new TrackedObjectStates
            {
                ParentIDEnterers = parentIDEnterers.ToArray(), // parent IDs of new or increased conflict states
                ParentIDLeavers = parentIDLeavers.ToArray(),   // parent IDs of expired or reduced conflict states
                LeavingIDs = leavingIDs,                       // child IDs - ended conflict(s)
                EnteringIDs = enteringIDs,                     // child IDs - the conflict(s)
                PriorConflictingIDs = parentIDLeavers          // parent IDs that need informed all conflicts have ceased
            });
        }