/// <summary> /// Handles addition of new tracked object if user is using Unity triggers. /// </summary> private void handleTriggerAddition(GameObject trackedObject, WorldMonitors owner, string objectAffiliation, float threshold) { if (!trackedObject.GetComponent <TrackedObjectTriggers>()) { trackedObject.AddComponent <TrackedObjectTriggers>(); } TrackedObjectTriggers tot = trackedObject.GetComponent <TrackedObjectTriggers>(); GameObjectIDReference.Add(trackedObject, AllocationSpace); gameObjectReference.Add(AllocationSpace, trackedObject); TrackedObjectData TOData = new TrackedObjectData { Object = trackedObject, Threshold = TriggersMimicOctree ? 0.75f * threshold : threshold, ObjectOwners = new List <WorldMonitors>() }; if (owner) { TOData.ObjectOwners.Add(owner); tot.AcceptOwner(owner); } TrackedObjectDataRef.Add(AllocationSpace, TOData); TrackedObjectAffiliations.Add(AllocationSpace, objectAffiliation); TotalTrackedObjects++; AllocationSpace++; tot.Initialize(); }
/// <summary> /// Runtime objects should be inserted into the tracking system here. /// </summary> /// <param name="trackedObject">The object to be tracked.</param> /// <param name="owner">Provide the WorldMonitors component from the agent tracking this object.</param> /// <param name="objectAffiliation">The class of objects this item is in (e.g. "A", "B", etc.)</param> /// <param name="threshold">Regardless of class type, this object can be inserted with its own threshold size.</param> /// <remarks>Due to the cost associated with this operation, perform minimal additions per frame or run from coroutine</remarks> public void InsertNewTrackedObject(GameObject trackedObject, WorldMonitors owner, string objectAffiliation, float threshold) { if (!FreeSpace) { return; } if (usingTriggers) { handleTriggerAddition(trackedObject, owner, objectAffiliation, threshold); FreeSpace = MaximumObjectsAllowed - AllocationSpace > 0; return; } /* * Do not need to add directly into Octree * Happens in the first update saving time from main thread */ int id; if (GameObjectIDReference.TryGetValue(trackedObject, out id)) { // allow for user to add new trackers to one object TrackedObjectData TOData; TrackedObjectDataRef.TryGetValue(id, out TOData); if (owner) // else the user has tried to add a non-owned object more than once { TOData.ObjectOwners.Add(owner); } } else { GameObjectIDReference.Add(trackedObject, AllocationSpace); gameObjectReference.Add(AllocationSpace, trackedObject); TrackedObjectData TOData = new TrackedObjectData { Object = trackedObject, Threshold = OctreeMimicTriggerInteraction ? 3 / 2 * threshold : threshold, ObjectOwners = new List <WorldMonitors>() }; if (owner) { TOData.ObjectOwners.Add(owner); } Octree.MasterList.Add(AllocationSpace, new List <int>()); TrackedObjectDataRef.Add(AllocationSpace, TOData); TrackedObjectAffiliations.Add(AllocationSpace, objectAffiliation); TotalTrackedObjects++; AllocationSpace++; Octree.TrackedObjectStates = TrackedObjectStates; FreeSpace = MaximumObjectsAllowed - AllocationSpace >= 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>(); } }