コード例 #1
0
        /// <summary>
        /// Handles end of conflict events if user chooses to do so.
        /// </summary>
        private void handleEndConflicts(ConflictEndMode mode, TrackedObjectStates tos)
        {
            switch (mode)
            {
            case ConflictEndMode.OnIndividualConflictEnded:
                //find conflicts that have partially or completely ended and inform agents monitoring
                int numStates = tos.ParentIDLeavers.Length;

                for (int endParentID = 0; endParentID < numStates; endParentID++)
                {
                    int parentID = tos.ParentIDLeavers[endParentID];

                    TrackedObjectData TOData;    // = TrackedObjectDataRef[parentID];
                    if (TrackedObjectDataRef.TryGetValue(parentID, out TOData))
                    {
                        int numConflicts = tos.LeavingIDs[endParentID].Length;

                        // allocate arrays for conflict data
                        GameObject[] leavers = new GameObject[numConflicts];
                        string[]     conflictorAffiliations = new string[numConflicts];

                        // fill conflict data
                        for (int i = 0; i < numConflicts; i++)
                        {
                            int m = TrackedObjectStates.LeavingIDs[endParentID][i];
                            leavers[i] = gameObjectReference[m];
                            conflictorAffiliations[i] = TrackedObjectAffiliations[m];
                        }

                        //inform the agents monitoring this object
                        foreach (WorldMonitors wm in TOData.ObjectOwners)
                        {
                            wm.RaiseConflictLeavers(TOData.Object, leavers, conflictorAffiliations);
                        }
                    }
                }
                break;

            case ConflictEndMode.OnAllConflictsEnded:
                //find conflicts that have completely ended and inform the agents monitoring

                foreach (int endParentID in TrackedObjectStates.PriorConflictingIDs)
                {
                    TrackedObjectData TOData;
                    if (TrackedObjectDataRef.TryGetValue(endParentID, out TOData))     // preserve the ability to have non-owned tracked objects
                    {
                        if (TOData.ObjectOwners.Count > 0)
                        {
                            foreach (WorldMonitors wm in TOData.ObjectOwners)
                            {
                                wm.EndConflicts(gameObjectReference[endParentID]);
                            }
                        }
                    }
                }
                break;
            }
        }
コード例 #2
0
        /// <summary>
        /// Call this method to begin the threaded Octree operations.
        /// </summary>
        /// <param name="otp"<see cref="OctreeThreadParameters"/></param>
        public void ThreadOctreeInit(OctreeThreadParameters otp, bool restrictToMainThread)
        {
            if (restrictToMainThread)
            {
                TrackedObjectStates = evaluateOctree(otp);
                return;
            }

            ThreadRunning = true;

            IsDone = false;
            base.StartOctree(otp);
        }
コード例 #3
0
        public void Start()
        {
            usingTriggers = TrackingMode == TrackingMode.UnityTriggers;

            agentMonitors = GameObject.FindObjectsOfType <WorldMonitors>();

            /*
             * Start procedure is O(i*j*k) and a faster solution may exist
             */

            for (int i = 0; i < agentMonitors.Length; i++)
            {
                for (int j = 0; j < agentMonitors[i].TrackedObjects.Count; j++)
                {
                    for (int k = 0; k < agentMonitors[i].TrackedObjects[j].TrackedObjects.Count; k++)
                    {
                        // double threshold size if user wishes for point octree to mimic trigger interaction distances
                        float threshold = (OctreeMimicTriggerInteraction && TrackingMode == TrackingMode.Octree) ? agentMonitors[i].ThresholdSet[j] * 3 / 2 : agentMonitors[i].ThresholdSet[j];

                        GameObject go = agentMonitors[i].TrackedObjects[j].TrackedObjects[k];

                        if (go) // allows user to leave empty gameobject slots in tracked object inspector
                        {
                            int id;
                            if (GameObjectIDReference.TryGetValue(go, out id))
                            {
                                TrackedObjectData TOData;
                                TrackedObjectDataRef.TryGetValue(id, out TOData);
                                TOData.ObjectOwners.Add(agentMonitors[i]);
                                TrackedObjectDataRef[id] = TOData;

                                if (usingTriggers)
                                {
                                    // WorldMonitors will declare ownership in its Start() method

                                    if (!go.GetComponent <TrackedObjectTriggers>())
                                    {
                                        go.AddComponent <TrackedObjectTriggers>();
                                    }

                                    go.GetComponent <TrackedObjectTriggers>().Initialize();
                                }
                            }
                            else
                            {
                                GameObjectIDReference.Add(go, TotalTrackedObjects); //object ID = current number of tracked objects
                                gameObjectReference.Add(TotalTrackedObjects, go);   //using IDs necessary to run aux thread

                                TrackedObjectData TOData = new TrackedObjectData
                                {
                                    Object       = go,
                                    Threshold    = threshold,
                                    ObjectOwners = new List <WorldMonitors>()
                                };

                                TOData.ObjectOwners.Add(agentMonitors[i]);
                                TrackedObjectDataRef.Add(TotalTrackedObjects, TOData);
                                TrackedObjectAffiliations.Add(TotalTrackedObjects, OTIEditorBase._AlphabetAssembler(j));

                                if (usingTriggers)
                                {
                                    if (!go.GetComponent <TrackedObjectTriggers>())
                                    {
                                        go.AddComponent <TrackedObjectTriggers>();
                                    }
                                    go.GetComponent <TrackedObjectTriggers>().Initialize();
                                }

                                TotalTrackedObjects++;
                            }
                        }
                    }
                }
            }

            AllocationSpace = TotalTrackedObjects;
            FreeSpace       = MaximumObjectsAllowed - AllocationSpace >= 0;

            if (usingTriggers || ExhaustiveMethod)
            {
                return; // no more set up required; switching between modes is not allowed at runtime.
            }
            Octree = new Octree();

            //configure tracked object states at start
            for (int i = 0; i < TotalTrackedObjects; i++)
            {
                List <int> locals = new List <int>();

                if (Octree.MasterList.ContainsKey(i))
                {
                    Octree.MasterList[i] = locals;
                }
                else
                {
                    Octree.MasterList.Add(i, locals);
                }
            }

            OctreeThreadParameters otp = new OctreeThreadParameters
            {
                ObjectIDs           = new List <int>(TrackedObjectDataRef.Keys),
                TotalTrackedObjects = TotalTrackedObjects,
                Coordinates         = getUpdatedPositions(new List <int>(TrackedObjectDataRef.Keys)),
                DynamicObjects      = TrackedObjectAffiliations
            };

            //construct initial octree
            Octree.Initialize(InitialWorldSize, WorldOrigin, MinimumObjectSize);

            Octree.IsDone = true; //allows an initial pass into job start
            Octree.ThreadOctreeInit(otp, RestrictToMainThread);

            while (!Octree.UpdateOctree())
            {
            }                                  //wait until conflict states are established

            TrackedObjectStates = Octree.TrackedObjectStates;

            // wipe initial results so conflicts existing before start register
            for (int i = 0; i < Octree.MasterList.Count; i++)
            {
                Octree.MasterList[i] = new List <int>();
            }
        }
コード例 #4
0
        void Update()
        {
            if (ExhaustiveMethod || usingTriggers) // if you are not using these features you can remove this if statement
            {
                if (ExhaustiveMethod)
                {
                    exhaustiveCalculation();
                }
                return;
            }

            if (Octree.UpdateOctree()) // job has concluded
            {
                passedFrames = 0;      // in sync with update

                TrackedObjectStates = Octree.TrackedObjectStates;

                OctreeThreadParameters otp = refreshThreadingParameters();

                int numStates = TrackedObjectStates.ParentIDEnterers.Length;

                for (int tos = 0; tos < numStates; tos++)
                {
                    int parentID = TrackedObjectStates.ParentIDEnterers[tos];

                    TrackedObjectData TOData;
                    if (TrackedObjectDataRef.TryGetValue(parentID, out TOData))
                    {
                        int numConflicts = TrackedObjectStates.EnteringIDs[tos].Length;

                        GameObject[] conflictors            = new GameObject[numConflicts]; // allocate arrays for conflict data
                        string[]     conflictorAffiliations = new string[numConflicts];

                        // fill conflict data
                        for (int i = 0; i < numConflicts; i++)
                        {
                            int m = TrackedObjectStates.EnteringIDs[tos][i];
                            conflictors[i]            = gameObjectReference[m];
                            conflictorAffiliations[i] = TrackedObjectAffiliations[m];
                        }

                        foreach (WorldMonitors wm in TOData.ObjectOwners) //inform the agents monitoring this object}
                        {
                            wm.RaiseConflictEnterers(TOData.Object, conflictors, conflictorAffiliations);
                        }
                    }
                }

                // if user wishes for no end conflict events to be raised, the update has concluded.
                if (ConflictEndMode == ConflictEndMode.NoConflictEndEvents)
                {
                    Octree.ThreadOctreeInit(otp, RestrictToMainThread);
                    return;
                }

                handleEndConflicts(ConflictEndMode, TrackedObjectStates);

                Octree.ThreadOctreeInit(otp, RestrictToMainThread);
            }
            else
            {
                passedFrames++;
            }
        }
コード例 #5
0
 protected override void ThreadOctree(OctreeThreadParameters otp)
 {
     TrackedObjectStates = evaluateOctree(otp);
     IsDone = true; // TrackedObjectStates are defined - - eliminating race conditions
 }