public void PlayDrawnHaptic(HardlightCollider clicked, RaycastHit hit)
        {
            //This could be done more efficiently. It is kept simple to make the code more readible.
            int index = suitObjects.IndexOf(clicked);

            //If the current duration is over.
            if (playingDurations[index] <= 0)
            {
                //We enforce a minimum duration mostly to ensure there is a good visual.
                playingDurations[index] = Mathf.Clamp(Duration, minDuration, float.MaxValue);

                //Color the suit (drawn haptic expiration handles decoloring.
                ColorSuitCollider(clicked, selectedColor);

                //Find where we drew on
                AreaFlag flag = clicked.regionID;

                //Play the last played sequence there.
                LibraryManager.Inst.LastSequence.CreateHandle(flag).Play();

                //When the effects expire, the decoloring is handled there.
                //StartCoroutine(ChangeColorDelayed(
                //	hit.collider.gameObject,
                //	unselectedColor,
                //	Duration));
            }
            else
            {
                //Don't do anything
            }
        }
Exemple #2
0
        /// <summary>
        /// Gets a random GameObject from the suit (which has a HapticLocation) that is within the set of potential areas.
        /// You can request 'AreaFlag.Right_All' to get any random right area.
        /// </summary>
        /// <param name="setOfPotentialAreas">Please </param>
        /// <returns>A game object within the random set. Can be null if you ask for AreaFlag.None or for spots that aren't on your configured body.</returns>
        public GameObject GetRandomLocationWithinSet(AreaFlag setOfPotentialAreas)
        {
            //TODO: Refactor this
            //Give me a random area flag within the set of area flag.
            //Apply filter to that set.
            //Then get the index of that area.


            var limitedAreas = DefinedAreas.Where(x => setOfPotentialAreas.HasFlag(x));
            int index        = Random.Range(0, limitedAreas.Count());

            if (limitedAreas.Count() > 0)
            {
                int sceneReferenceIndex = DefinedAreas.IndexOf(limitedAreas.ElementAt(index));

                //Debug.Log("Rand Loc: " + index + " of " + limitedAreas.Count() + "  " + limitedAreas.ElementAt(index).ToString() + "  " + DefinedAreas.IndexOf(limitedAreas.ElementAt(index)) + "\n" + SceneReferences[sceneReferenceIndex].name);
                //This is not possible.
                //if (index > regions.Count)
                //{
                //}
                //else
                if (SceneReferences[sceneReferenceIndex] == null)
                {
                    Debug.LogError("Attempted to get Random Location inside HardlightSuit's SuitDefinition.\n\tNo locations should be null. Check to make sure the fields in the Body Mimic prefab were assigned.");
                }
                else
                {
                    return(SceneReferences[sceneReferenceIndex].Representation);
                }
            }
            return(null);
        }
Exemple #3
0
        /// <summary>
        /// Begins an emanating impulse at the provided origin.
        /// Defaults to a simple 'hum' effect if you don't call WithEffect()
        /// Remember to call .Play() on the returned impulse.
        /// </summary>
        /// <param name="origin">The starting AreaFlag. Only provided a single AreaFlag pad.</param>
        /// <param name="depth">How many pads this will traverse before ending (will not reverb off 'end paths')</param>
        /// <returns>An Impulse object which can be given a HapticSequence, duration or Attenuation parameters
        /// Remember to call Play() on the returned object to begin the emanation
        /// <returns>The Impulse that you can call .Play() on to play a create a HapticHandle referencing that Haptic</returns>
        public static Impulse BeginEmanatingEffect(AreaFlag origin, int depth = 2)
        {
            if (depth < 0)
            {
                Debug.LogError("Depth for emanation is negative: " + depth + "\n\tThis will be clamped to 0 under the hood, negative numbers will likely do nothing");
            }

            CreateImpulse creation = delegate(float attenuation, float totalLength, HapticSequence seq)
            {
                HapticPattern emanation    = new HapticPattern();
                var           stages       = _grapher.BFS(origin, depth);
                float         baseStrength = 1.0f;
                float         timeStep     = totalLength / stages.Count;
                float         time         = 0.0f;
                for (int i = 0; i < stages.Count; i++)
                {
                    AreaFlag area = AreaFlag.None;
                    foreach (var item in stages[i])
                    {
                        area |= item.Location;
                    }
                    if (i > 0)
                    {
                        baseStrength *= (1.0f - attenuation);
                    }

                    emanation.AddSequence(time, area, Mathf.Clamp(baseStrength, 0f, 1f), seq);
                    time += timeStep;
                }

                return(emanation.CreateHandle().Play());
            };

            return(new Impulse(creation));
        }
Exemple #4
0
        /// <summary>
        /// Begins a traversing impulse at the provided origin.
        /// Will play on pads that are the origin, destination or 'in-between' them.
        /// Defaults to a simple 'hum' effect if you don't call WithEffect()
        /// Remember to call .Play() on the returned impulse.
        /// </summary>
        /// <param name="origin">The starting AreaFlag. Only provided a single AreaFlag pad.</param>
        /// <param name="destination">The ending location for the traversing impulse.</param>
        /// <returns>The Impulse that you can call .Play() on to play a create a HapticHandle referencing that Haptic</returns>
        public static Impulse BeginTraversingImpulse(AreaFlag origin, AreaFlag destination)
        {
            CreateImpulse creation = delegate(float attenuation, float totalLength, HapticSequence seq)
            {
                HapticPattern emanation = new HapticPattern();
                var           stages    = _grapher.Dijkstras(origin, destination);

                float timeStep     = totalLength / stages.Count;
                float time         = 0.0f;
                float baseStrength = 1f;
                for (int i = 0; i < stages.Count; i++)
                {
                    if (i > 0)
                    {
                        baseStrength *= (1.0f - attenuation);
                    }
                    emanation.AddSequence(time, stages[i].Location, Mathf.Clamp(baseStrength, 0f, 1f), seq);
                    time += timeStep;
                }

                return(emanation.CreateHandle().Play());
            };

            return(new Impulse(creation));
        }
Exemple #5
0
        public AreaFlag GetActiveAreas()
        {
            AreaFlag flag = AreaFlag.None;

            //Safely proceed to avoid broken refs.
            if (selector != null)
            {
                for (int i = 0; i < selector.suitObjects.Count; i++)
                {
                    //If this selected element isn't null
                    if (selector.suitObjects[i] != null)
                    {
                        //Add that flag
                        flag = flag | selector.suitObjects[i].regionID;
                    }
                }
            }
            else
            {
                return(AreaFlag.All_Areas);
                //Debug.LogError("Selector is null. Check Library Manager in the inspector\n");
            }

            return(flag);
        }
Exemple #6
0
        /// <summary>
        /// Gets a random HapticLocation on the configured HardlightSuit.
        /// NOTE: Will remove DisabledRegions
        /// </summary>
        /// <param name="OnlyAreasWithinSet">The AreaFlags you want to randomly select from.</param>
        /// <param name="DisplayInEditor"></param>
        /// <returns>A valid HapticLocation on the body (defaults to null if none are configured or if it is configured incorrectly.</returns>
        public HapticLocation FindRandomLocation(AreaFlag OnlyAreasWithinSet = AreaFlag.All_Areas, bool RemoveDisabledRegions = false, bool DisplayInEditor = false)
        {
            if (RemoveDisabledRegions)
            {
                OnlyAreasWithinSet = OnlyAreasWithinSet.RemoveArea(DisabledRegions.InactiveRegions);
            }

            HapticLocation loc = Definition.GetRandomLocationWithinSet(OnlyAreasWithinSet).GetComponent <HapticLocation>();

            if (loc != null)
            {
                if (!loc.LocationActive)
                {
                    Debug.LogError("FindRandomLocation and GetRandomLocationWithinSet have returned a HapticLocation that is marked as inactive.\n\tThis is an expected bug but should be fixed in the future - try using DeactiveHapticLocation to turn regions off.\n");
                }
                if (DisplayInEditor)
                {
                    ColorHapticLocationInEditor(loc, Color.blue);
                }

                return(loc);
            }
            else
            {
                Debug.LogError("Failed to complete PlayerBody.FindRandomLocation(). The returned object did not have a HapticLocation component\n");
            }
            return(null);
        }
Exemple #7
0
        /// <summary>
        /// Begins a traversing impulse at the provided origin.
        /// Will play on pads that are the origin, destination or 'in-between' them.
        /// Defaults to a simple 'hum' effect if you don't call WithEffect()
        /// Remember to call .Play() on the returned impulse.
        /// </summary>
        /// <param name="origin">The starting AreaFlag. Only provided a single AreaFlag pad.</param>
        /// <param name="destination">The ending location for the traversing impulse.</param>
        /// <returns>The Impulse that you can call .Play() on to play a create a HapticHandle referencing that Haptic</returns>
        public static Impulse BeginTraversingImpulse(AreaFlag origin, AreaFlag destination)
        {
            if (!origin.IsSingleArea() || !destination.IsSingleArea())
            {
                Debug.LogError("Invalid AreaFlag Provided: Origin is [" + origin.NumberOfAreas() + "] area(s) and Destination is [" + destination.NumberOfAreas() + "] area(s).\n\tImpulse Generator only supports single area flag values.\n");
                return(null);
            }
            CreateImpulse creation = delegate(float attenuation, float totalLength, HapticSequence seq)
            {
                HapticPattern emanation = new HapticPattern();
                var           stages    = _grapher.Dijkstras(origin, destination);

                float timeStep     = totalLength / stages.Count;
                float time         = 0.0f;
                float baseStrength = 1f;
                for (int i = 0; i < stages.Count; i++)
                {
                    if (i > 0)
                    {
                        baseStrength *= (attenuation);
                    }
                    //Debug.Log(timeStep + "\n" + baseStrength + "\n");
                    emanation.AddSequence(time, stages[i].Location, Mathf.Clamp(baseStrength, 0f, 1f), seq);
                    time += timeStep;
                }

                return(emanation.CreateHandle().Play());
            };

            return(new Impulse(creation));
        }
        IEnumerator StomacheRumble()
        {
            gulpSource.volume = .85f;

            List <AreaFlag> locs = new List <AreaFlag>();

            locs.Add(AreaFlag.Lower_Ab_Left);
            locs.Add(AreaFlag.Lower_Ab_Right);
            locs.Add(AreaFlag.Mid_Ab_Left);
            locs.Add(AreaFlag.Mid_Ab_Right);

            while (true)
            {
                AreaFlag loc  = locs[Random.Range(0, locs.Count)];
                string   file = Random.Range(0, 1.0f) > .8f ? "Haptics/StomachRumbleHeavy" : "Haptics/StomachRumble";

                HapticSequence seq = new HapticSequence();
                seq.LoadFromAsset(file);
                seq.CreateHandle(loc).Play();

                float waitDur = Random.Range(.05f, .15f);

                yield return(new WaitForSeconds(waitDur));
            }
        }
Exemple #9
0
        public List <SuitNode> DFS(AreaFlag beginNode, AreaFlag endNode)
        {
            var stages = new List <SuitNode>();
            var stack  = new Stack <SuitNode>();
            Dictionary <SuitNode, SuitNode> cameFrom = new Dictionary <SuitNode, SuitNode>();
            var source = _nodes[beginNode];
            //var sink = _nodes[endNode];
            Dictionary <SuitNode, bool> visited = new Dictionary <SuitNode, bool>();

            foreach (var n in _nodes)
            {
                visited[n.Value] = false;
            }
            stack.Push(source);
            while (stack.Count != 0)
            {
                var v = stack.Pop();
                if (!visited[v])
                {
                    visited[v] = true;
                    var neighbors = Neighbors(v);
                    foreach (var neigh in neighbors)
                    {
                        stack.Push(neigh);
                        cameFrom[neigh] = v;
                    }
                    stages.Add(v);
                }
            }

            return(stages);
        }
Exemple #10
0
        public List <List <SuitNode> > BFS(AreaFlag beginNode, int maxDepth)
        {
            maxDepth = Math.Max(0, maxDepth);
            List <List <SuitNode> > stages = new List <List <SuitNode> >();
            SuitNode source = _nodes[beginNode];
            Dictionary <SuitNode, bool> visited = new Dictionary <SuitNode, bool>();

            foreach (var n in _nodes)
            {
                visited[n.Value] = false;
            }
            Queue <SuitNode> queue          = new Queue <SuitNode>();
            int currentDepth                = 0;
            int elementsToDepthIncrease     = 1;
            int nextElementsToDepthIncrease = 0;

            visited[source] = true;
            queue.Enqueue(source);
            stages.Add(new List <SuitNode>()
            {
                source
            });
            List <SuitNode> potentialNextStage = new List <SuitNode>();

            while (queue.Count != 0)
            {
                source = queue.Dequeue();
                var neighbors = Neighbors(source);



                foreach (var neighbor in neighbors)
                {
                    if (!visited[neighbor])
                    {
                        visited[neighbor] = true;
                        queue.Enqueue(neighbor);
                        potentialNextStage.Add(neighbor);
                        nextElementsToDepthIncrease++;
                    }
                }

                if (--elementsToDepthIncrease == 0)
                {
                    if (potentialNextStage.Count > 0)
                    {
                        stages.Add(new List <SuitNode>(potentialNextStage));
                    }
                    if (++currentDepth == maxDepth)
                    {
                        return(stages);
                    }
                    elementsToDepthIncrease     = nextElementsToDepthIncrease;
                    nextElementsToDepthIncrease = 0;
                    potentialNextStage.Clear();
                }
            }

            return(stages);
        }
Exemple #11
0
        /// <summary>
        /// Desert of Danger - when the player is hit.
        /// This is not the best way to implement the following. We're still learning the best way to make reusable haptics.
        /// </summary>
        /// <param name="pos">This is used in tandem with the FindNearest() function that finds the AreaFlag that represents the closest point to the 'HitImpulse'</param>
        /// <param name="effect">This takes a different effect which can vary from projectile to projectile.
        /// You could also make a version that takes a CodeSequence for projectiles with varying characteristics</param>
        public void HitImpulse(Vector3 pos, string effect = "buzz")
        {
            //We have a function called FindNearestPos, which finds the closest AreaFlag on the player's body
            AreaFlag loc = AreaFlag.None;            //FindNearest(pos);

            //Then if we found something
            if (loc != AreaFlag.None)
            {
                //Then we begin an emanating effect on the player from that point.
                //We want the ENTIRE emanation to last .25 seconds, so we pass in that parameter.
                //Finally, we play the emanation.

                ImpulseGenerator.BeginEmanatingEffect(loc).WithEffect(effect, .1f).WithDuration(.25f).Play();

                //We let the HapticHandle Play returns go out of scope because the effect is short lived and we don't care about stopping it early.
                //If you had something like Daxter (the Weasel character from Jak and Daxter) climbing around on the player's body, you'd want to hold onto both the Impulse and the HapticHandle, that way you can restart the impulse (or change parameters) as well as being able to stop the haptic impulse when Daxter stops moving.

                //You could modify this function to return a HapticHandle or the created Impulse.
            }
            else
            {
                //We shouldn't ever be getting 'hit' without being able to find a valid nearby position.
                //An error is thrown inside of the FindNearest function (also provided)
                Debug.LogWarning("Invalid Hit at " + pos + "\n");
            }
        }
Exemple #12
0
 public JsonSequenceAtom(string sequenceName, AreaFlag where, float str, float offset)
 {
     sequence = sequenceName;
     area     = where.ToString();
     strength = str;
     time     = offset;
 }
Exemple #13
0
        private void TestAreaFlagExtensions()
        {
            //This section digs into some of the AreaFlagExtension methods.

            string   Report = "[AreaFlag Tests]\n" + "\t[Number of Areas/Single Area Tests]\n\n";
            AreaFlag flag   = AreaFlag.Mid_Ab_Left;

            Report += "How many flags in Mid Ab Left [1]:" + flag.NumberOfAreas() + " - is single area? [T] " + flag.IsSingleArea() + "\n";

            flag    = AreaFlag.Back_Both;
            Report += "How many flags in Mid Ab Left [2]: " + flag.NumberOfAreas() + " - is single area? [F] " + flag.IsSingleArea() + "\n";

            flag    = (AreaFlag.All_Areas).RemoveArea(AreaFlag.Back_Both);
            Report += "How many flags in All but Back Both [14]: " + flag.NumberOfAreas() + " - is single area? [T] " + flag.IsSingleArea() + "\n";

            flag    = AreaFlag.Right_All;
            Report += "How many flags in Right All [8]: " + flag.NumberOfAreas() + " - is single area? [T] " + flag.IsSingleArea() + "\n\n";

            flag    = AreaFlag.All_Areas;
            Report += "AreaFlag HasFlag Tests:\nDoes All_Areas contain Lower Left Ab? (T): " + flag.HasFlag(AreaFlag.Lower_Ab_Left) +
                      "\nDoes All_Areas contain Right_All? (T):  " + flag.HasFlag(AreaFlag.Right_All) +
                      "\nDoes Right_All contain Back_Both? (F): " + AreaFlag.Right_All.HasFlag(AreaFlag.Back_Both) + "\n";

            Debug.Log(Report);
        }
Exemple #14
0
 /// <summary>
 /// Plays the current haptic sequence on the specified area
 /// </summary>
 /// <param name="Where"></param>
 public void PlayHapticSequence(AreaFlag Where)
 {
     if (TypeOfFile == HapticFileType.Sequence)
     {
         Sequence seq = new Sequence(HapticNamespace + "." + HapticFileName);
         seq.CreateHandle(Where).Play();
     }
 }
Exemple #15
0
 //		//public static AreaFlag ConvertFlag(string flagName)
 //		//{
 //		//	return (AreaFlag)System.Enum.Parse(typeof(AreaFlag), flagName, true); ;
 //		//}
 //		//public static bool HasFlag(int baseFlag, int flag)
 //		//{
 //		//	if ((baseFlag & flag) == flag)
 //		//	{
 //		//		return true;
 //		//	}
 //		//	return false;
 //		//}
 public static bool HasFlag(this AreaFlag baseFlag, int flag)
 {
     if (((int)baseFlag & (flag)) == flag)
     {
         return(true);
     }
     return(false);
 }
 /// <summary>
 /// Checks if an AreaFlag contains another AreaFlag
 /// </summary>
 /// <param name="lhs"></param>
 /// <param name="rhs"></param>
 /// <returns>True of the AreaFlag contains the other, else false</returns>
 public static bool ContainsArea(this AreaFlag lhs, AreaFlag rhs)
 {
     if ((lhs & rhs) == rhs)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Exemple #17
0
        void OnTriggerEnter(Collider collider)
        {
            SuitBodyCollider hit = collider.GetComponent <SuitBodyCollider>();

            if (hit != null)
            {
                AreaFlag flag = hit.regionID;
                //Debug.Log(flag.ToString() + "  " + (int)flag + "\n");
                onTriggerEnterSequence.CreateHandle(collider.GetComponent <SuitBodyCollider>().regionID).Play();
            }
        }
        /// <summary>
        /// Create a HapticHandle for this HapticSequence, specifying an AreaFlag and a strength.
        /// </summary>
        /// <param name="area">The AreaFlag where this HapticSequence should play</param>
        /// <param name="strength">The strength of this HapticSequence (0.0-1.0)</param>
        /// <returns>A new HapticHandle bound to this effect playing on the given area</returns>
        public unsafe HapticHandle CreateHandle(AreaFlag area, double strength)
        {
            EventList e = new ParameterizedSequence(this, area).Generate((float)strength, 0f);

            //Debug.Log("Event List: " + e.ToString() + "\n");
            HapticHandle.CommandWithHandle creator = delegate(HLVR_Effect * handle)
            {
                e.Transmit(handle);
            };

            return(new HapticHandle(creator));
        }
Exemple #19
0
        private AreaFlag FindAreaFlagFromHardlightCollider(HardlightCollider[] hit)
        {
            AreaFlag hitAreas = AreaFlag.None;

            for (int i = 0; i < hit.Length; i++)
            {
                hitAreas = hitAreas.AddArea(hit[i].regionID);
                ColorHapticLocationInEditor(hit[i].MyLocation);
            }

            return(hitAreas);
        }
            void DisplayAreaFlag(int index, GUILayoutOption[] options)
            {
                //GUILayout.Label("Area Flag Display");
                if (DefaultOptions != null && DefaultOptions.Count > index)
                {
                    AreaFlag o     = DefaultOptions[index];
                    string   label = o.ToString();

                    //Remove the underscores?

                    GUILayout.Label(label, options);
                }
            }
Exemple #21
0
        /// <summary>
        /// Begins an emanation at the nearest flag from the point.
        /// Assigns a strength of 1.0f to the effect. (no attenuation support yet)
        /// </summary>
        /// <param name="point">A point near the player's body</param>
        /// <param name="eff">The effect to use in the emanation.</param>
        /// <param name="effectDuration">How long the impulse's effect is</param>
        /// <param name="impulseDuration">How long the entire impulse takes to visit each step of the depth</param>
        /// <param name="strength">How strong the individual effect is (no support for attenuation yet)</param>
        /// <param name="depth">The depth of the emanating impulse</param>
        /// <param name="maxDistance">Will not return locations further than the max distance.</param>
        public void HitImpulse(Vector3 point, Effect eff = Effect.Pulse, float effectDuration = .2f, float impulseDuration = .5f, float strength = 1.0f, int depth = 1, float maxDistance = 5.0f)
        {
            AreaFlag loc = FindNearestFlag(point, maxDistance);

            if (loc != AreaFlag.None)
            {
                ImpulseGenerator.BeginEmanatingEffect(loc, depth).WithEffect(Effect.Pulse, effectDuration, strength).WithDuration(impulseDuration).Play();
            }
            else
            {
                Debug.LogWarning("Invalid Hit at " + point + "\n");
            }
        }
Exemple #22
0
        /// <summary>
        /// Plays the sequence on the single nearest HapticLocation
        /// Note: A HapticLocation can have an AreaFlag with multiple pads selected.
        /// </summary>
        /// <param name="point">A point in world space to compare</param>
        /// <param name="sequence">The sequence to play on the nearest location</param>
        /// <param name="maxDistance">The max distance the point can be from any HapticLocations</param>
        public AreaFlag HitNearest(Vector3 point, HapticSequence sequence, float maxDistance = 5.0f)
        {
            AreaFlag Where = FindNearestFlag(point, maxDistance);

            if (Where != AreaFlag.None)
            {
                sequence.CreateHandle(Where).Play();
            }
            else
            {
                Debug.Log("Projectile hit the HardlightSuit but found no objects hit. Perhaps the maxDistance (" + maxDistance + ") is too small?\n\tOr the suit/prefab wasn't configured correctly.\n");
            }
            return(Where);
        }
        //Make this return a bool and it'll mark the LibraryElement as broken.
        public bool ExecuteLibraryElement()
        {
            if (FileHasBeenModified())
            {
                MarkElementChanged();
            }

            //Debug.Log("File has been modified since load: [" + FileHasBeenModified() + "]\n");
            try
            {
                HapticHandle newHandle = null;
                if (LibraryManager.Inst.LastPlayed != null && LibraryManager.Inst.StopLastPlaying)
                {
                    LibraryManager.Inst.LastPlayed.Pause();
                    LibraryManager.Inst.LastPlayed.Dispose();
                }

                //Get the file path
                //Debug.Log("[" + myNamespace + "] [" + fileName + "]\n" + myNamespace + "" + fileName);
                if (myType == LibraryElementType.Sequence)
                {
                    //If sequence, use the specific pads selected (unsupported atm)
                    AreaFlag flag = LibraryManager.Inst.GetActiveAreas();
                    newHandle = new Sequence(myNamespace + fileName).CreateHandle(flag);
                    LibraryManager.Inst.SetTriggerSequence(myNamespace + fileName);
                }
                if (myType == LibraryElementType.Pattern)
                {
                    newHandle = new Pattern(myNamespace + fileName).CreateHandle();
                }
                if (myType == LibraryElementType.Experience)
                {
                    newHandle = new Experience(myNamespace + fileName).CreateHandle();
                }

                LibraryManager.Inst.LastPlayed = newHandle;

                if (LibraryManager.Inst.LastPlayed != null)
                {
                    LibraryManager.Inst.LastPlayed.Play();
                }
            }
            catch (Exception e)
            {
                Debug.LogError("Failed to play haptic [" + fullFilePath + "]" + "\n" + e.Message);
                return(false);
            }
            return(true);
        }
Exemple #24
0
        public List <SuitNode> Dijkstras(AreaFlag beginNode, AreaFlag endNode)
        {
            Dictionary <SuitNode, float>    dist = new Dictionary <SuitNode, float>();
            Dictionary <SuitNode, SuitNode> prev = new Dictionary <SuitNode, SuitNode>();

            var stack = new List <SuitNode>();

            foreach (var n in _nodes)
            {
                dist[n.Value] = float.PositiveInfinity;
                prev[n.Value] = null;
                stack.Add(n.Value);
            }
            var source = _nodes[beginNode];
            var sink   = _nodes[endNode];

            dist[source] = 0;

            while (stack.Count > 0)
            {
                var u = minDist(stack, dist);
                if (u.Location == endNode)
                {
                    break;
                }
                stack.Remove(u);
                foreach (var neighbor in Neighbors(u))
                {
                    var alt = dist[u] + _weights[u][neighbor];
                    if (alt < dist[neighbor])
                    {
                        dist[neighbor] = alt;
                        prev[neighbor] = u;
                    }
                }
            }

            List <SuitNode> s  = new List <SuitNode>();
            var             u2 = sink;

            while (prev[u2] != null)
            {
                s.Add(u2);
                u2 = prev[u2];
            }
            s.Add(source);
            s.Reverse();
            return(s);
        }
Exemple #25
0
        /// <summary>
        /// Plays the sequence on all HapticLocations within a certain radius of the provided point.
        /// </summary>
        /// <param name="point">A point in world space to compare</param>
        /// <param name="sequence">The sequence to play on the nearby locations</param>
        /// <param name="impactRadius">The body is about .6 wide, .72 tall and .25 deep</param>
        public AreaFlag HitNearby(Vector3 point, HapticSequence sequence, float impactRadius = .35f)
        {
            AreaFlag Where = FindAllFlagsWithinRange(point, impactRadius, true);

            if (Where != AreaFlag.None)
            {
                sequence.CreateHandle(Where).Play();
            }
            else
            {
                Debug.Log("Projectile hit the HardlightSuit but found no objects hit. Perhaps the impactRadius (" + impactRadius + ") is too small?\n\tOr the suit/prefab wasn't configured correctly.\n");
            }

            return(Where);
        }
        /// <summary>
        /// For getting the number of set AreaFlags contained in the flag it is called on.
        /// </summary>
        /// <param name="baseFlag">I wonder how many flags are in this. Let's find out!</param>
        /// <returns>0 to 16 pads (depending on how many are in baseFlag)</returns>
        public static int NumberOfAreas(this AreaFlag baseFlag)
        {
            //This is credited as the Hamming Weight, Popcount or Sideways Addition.
            //Source: Stack Overflow
            //https://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer

            //Really cool way to count the number of flags.

            int i = (int)baseFlag;

            // Java: use >>> instead of >>
            // C or C++: use uint32_t
            i = i - ((i >> 1) & 0x55555555);
            i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
            return((((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24);
        }
Exemple #27
0
 private void parse(string areaString)
 {
     string[] tokens = areaString.Split('|');
     foreach (var possibleArea in tokens)
     {
         var cleanedUpArea = possibleArea.Trim();
         try
         {
             var a = (AreaFlag)Enum.Parse(typeof(AreaFlag), cleanedUpArea);
             _area |= a;
         }
         catch (ArgumentException)
         {
             //do not add this unrecognized area flag
         }
     }
 }
Exemple #28
0
        public void Dig()
        {
            //Debug.Log("Attempted Dig\n", this);
            //Are we held.
            //if (IsGrabbed())
            //{
            HapticSequence seq = new HapticSequence();

            seq.AddEffect(.25f, new HapticEffect(Effect.Buzz));
            AreaFlag Where = PrimaryLeft ? AreaFlag.Forearm_Left : AreaFlag.Forearm_Right;

            seq.Play(Where);
            //}
            Digged = true;

            leftActions.TriggerDecayingHapticPulse(1f, .5f, .02f, .8f);
            rightActions.TriggerDecayingHapticPulse(1f, .5f, .02f, .8f);
        }
Exemple #29
0
        /// <summary>
        /// Shoots the player body somewhere with a simple buzz emanation impulse.
        /// </summary>
        /// <param name="ShotWhere">Self explanator. DO NOT PROVIDE MULTIPLE AREAS.</param>
        /// <returns>Don't forget to call .Play() on the returned Impulse to create an instance of the haptic effect it defines.</returns>
        public static ImpulseGenerator.Impulse DesertOfDangerShot(AreaFlag ShotWhere = AreaFlag.Chest_Right)
        {
            CodeSequence seq = new CodeSequence();

            //This will be slightly different then the default "buzz" effect Impulse. If you ask for an effect with a duration of 0, it'll play the natural duration.
            //Natural durations range from .05s (click, buzz, etc) to .25s (the multiple click families)
            //So by providing a duration of .1, this will be slightly different than the line:
            //		CodeEffect eff = new CodeEffect("buzz", 0.00f, 1.0f);

            CodeEffect eff = new CodeEffect("buzz", 0.10f, 1.0f);

            seq.AddEffect(0, eff);

            //The Desert of Danger demo set the entire impulse duration to .25s,
            //this means that it emanated out from where the playerwas hit.
            return(ImpulseGenerator.BeginEmanatingEffect(ShotWhere)
                   .WithEffect(seq)
                   .WithDuration(.25f));
        }
Exemple #30
0
        //public static NewGraphEngine _newGrapher = new NewGraphEngine();

        /// <summary>
        /// Begins an emanating impulse at the provided origin.
        /// Defaults to a simple 'hum' effect if you don't call WithEffect()
        /// Remember to call .Play() on the returned impulse.
        /// </summary>
        /// <param name="origin">The starting AreaFlag. Only provided a single AreaFlag pad.</param>
        /// <param name="depth">How many pads this will traverse before ending (will not reverb off 'end paths')</param>
        /// <returns>An Impulse object which can be given a HapticSequence, duration or Attenuation parameters
        /// Remember to call Play() on the returned object to begin the emanation
        /// <returns>The Impulse that you can call .Play() on to play a create a HapticHandle referencing that Haptic</returns>
        public static Impulse BeginEmanatingEffect(AreaFlag origin, int depth = 2)
        {
            if (!origin.IsSingleArea())
            {
                Debug.LogError("Invalid AreaFlag Provided: Origin is [" + origin.NumberOfAreas() + "] area(s).\n\tImpulse Generator only supports single area flag values.\n");
                return(null);
            }

            if (depth < 0)
            {
                Debug.LogError("Depth for emanation is negative: " + depth + "\n\tThis will be clamped to 0 under the hood, negative numbers will likely do nothing");
            }

            CreateImpulse creation = delegate(float attenuation, float totalLength, HapticSequence seq)
            {
                HapticPattern emanation = new HapticPattern();
                var           stages    = _grapher.BFS(origin, depth);
                //var stages = _newGrapher.BFS(origin, depth);
                float baseStrength = 1.0f;
                float timeStep     = totalLength / stages.Count;
                float time         = 0.0f;
                for (int i = 0; i < stages.Count; i++)
                {
                    AreaFlag area = AreaFlag.None;
                    foreach (var item in stages[i])
                    {
                        area |= item.Location;
                        //area |= item.ConvertToAreaFlag();
                    }
                    if (i > 0)
                    {
                        baseStrength *= (attenuation);
                    }

                    emanation.AddSequence(time, area, Mathf.Clamp(baseStrength, 0f, 1f), seq);
                    time += timeStep;
                }

                return(emanation.CreateHandle().Play());
            };

            return(new Impulse(creation));
        }