Exemplo n.º 1
0
    IEnumerator PlayImpulsesInf(HapticPattern pattern, bool rightHand)
    {
        int i = 0;

        while (!pattern.stop)
        {
            pattern.loopFunc.Invoke(ref pattern, i);
            if (pattern.stop)
            {
                continue;
            }
            if (pattern.amplitude > 0)
            {
                Impulse(pattern.amplitude, pattern.duration, rightHand);
            }
            float waitDur = pattern.duration + pattern.waitDuration;
            if (waitDur <= 0)
            {
                waitDur = minWaitDur;
            }
            yield return(new WaitForSeconds(waitDur));

            i++;
        }
    }
Exemplo n.º 2
0
    IEnumerator PlayImpulsesRepeat(HapticPattern pattern, bool rightHand)
    {
        if (pattern.repeat <= 0)
        {
            yield break;
        }
        float repeatAmount = Mathf.Clamp(pattern.repeat, 0, 1000);

        for (int i = 0; i < repeatAmount; i++)
        {
            pattern.loopFunc.Invoke(ref pattern, i);
            if (pattern.stop)
            {
                yield break;
            }
            if (pattern.repeat <= 0)
            {
                yield break;
            }
            if (pattern.amplitude > 0)
            {
                Impulse(pattern.amplitude, pattern.duration, rightHand);
            }
            float waitDur = pattern.duration + pattern.waitDuration;
            if (waitDur <= 0)
            {
                waitDur = minWaitDur;
            }
            yield return(new WaitForSeconds(waitDur));
        }
    }
Exemplo n.º 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));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Attempts to create a haptic pattern from the provided json path
        /// It will create a HDF and then turn the hdf into a HapticPattern.
        /// </summary>
        /// <param name="jsonPath">Ex: StreamingAssets/Haptics/NS Demos/patterns/mech_stomp_left.pattern</param>
        public static HapticPattern CreatePattern(string jsonPath)
        {
            var fileName = Path.GetFileNameWithoutExtension(jsonPath);

            ////If we don't replace . with _, then Unity has serious trouble locating the file
            HapticPattern pat = null;

            bool isSeq = IsSequence(jsonPath);
            bool isPat = IsPattern(jsonPath);
            bool isExp = IsExperience(jsonPath);

            if (isPat)
            {
                pat      = LoadPatternFromJson(jsonPath);
                pat.name = CleanName(fileName);
            }
            else if (isSeq)
            {
                Debug.LogError("Attempted to run a HapticPattern.CreateAsset while providing a sequence at path: " + jsonPath + "\n\t");
            }
            else if (isExp)
            {
                Debug.LogError("Attempted to run a HapticPattern.CreateAsset while providing a experience at path: " + jsonPath + "\n\t");
            }

            return(pat);
        }
Exemplo n.º 5
0
        private HapticHandle CreateHandle(SideOfHaptic side)
        {
            HapticHandle handle = null;

            if (TypeOfPlayable == PlayableType.Sequence)
            {
                HapticSequence seq = new HapticSequence();
                seq.LoadFromAsset(PlayableResourceName);

                var areaFlag = side == SideOfHaptic.Left ? Where.Mirror() : Where;
                handle = seq.CreateHandle(areaFlag);
            }
            else if (TypeOfPlayable == PlayableType.Pattern)
            {
                HapticPattern pat = new HapticPattern();
                pat.LoadFromAsset(PlayableResourceName);
                handle = pat.CreateHandle();
            }
            else if (TypeOfPlayable == PlayableType.Experience)
            {
                HapticExperience exp = new HapticExperience();
                exp.LoadFromAsset(PlayableResourceName);
                handle = exp.CreateHandle();
            }
            else if (TypeOfPlayable == PlayableType.Impulse)
            {
                return(CreateImpulseHandle(side));
            }

            return(handle);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Create a HapticPattern from a HapticDefinitionFile
        /// </summary>
        /// <param name="key">Name of the root effect</param>
        /// <param name="hdf">A HapticDefinitionFile containing the root effect</param>
        /// <returns></returns>
        public static HapticPattern CreatePatternFromHDF(string key, HapticDefinitionFile hdf)
        {
            string cleanedKey = HapticResources.CleanName(key);

            if (LoadedPatterns.ContainsKey(cleanedKey))
            {
                //Debug.Log("Pattern: " + cleanedKey + " already exists, returning it instead of needless reconstruction\n");
                return(LoadedPatterns[cleanedKey].Pattern);
            }

            HapticPattern pat = ScriptableObject.CreateInstance <HapticPattern>();
            var           pattern_def_array = hdf.pattern_definitions[key];

            foreach (var element in pattern_def_array)
            {
                //Debug.Log("Pattern Def Array: " + key + "  " + element.sequence + "\n");
                HapticSequence thisSeq = CreateSequenceFromHDF(element.sequence, hdf);
                thisSeq.name = element.sequence;

                ParameterizedSequence paraSeq = new ParameterizedSequence(thisSeq, element.ParseAreaFlag(), element.time, element.strength);
                pat.AddSequence(paraSeq);
            }

            EnsurePatternIsRemembered(cleanedKey, pat);
            return(pat);
        }
Exemplo n.º 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));
        }
Exemplo n.º 8
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));
        }
Exemplo n.º 9
0
 /// <summary>
 /// Play the specified pattern repeatedly until StopPatternRepeat is called
 /// </summary>
 public static void PlayPatternRepeat(HapticPattern pattern, bool rightHand)
 {
     if (rightHand)
     {
         if (isRepeatingRight)
         {
             // Debug.Log("Already playing a repeating pattern on Right!");
             return;
         }
         isRepeatingRight = true;
     }
     else
     {
         if (isRepeatingLeft)
         {
             // Debug.Log("Already playing a repeating pattern on Left!");
             return;
         }
         isRepeatingLeft = true;
     }
     if (pattern.hapticType == HapticType.CONTINUOUS)
     {
         pattern.hapticType = HapticType.SINGLE;
     }
     Instance.PlayRepeat(pattern, rightHand);
 }
Exemplo n.º 10
0
 public static void EnsurePatternIsRemembered(string key, HapticPattern pattern)
 {
     key = HapticResources.CleanName(key);
     if (!LoadedPatterns.ContainsKey(key) && pattern != null)
     {
         LoadedPatterns.Add(key, new PatternImportData(pattern, key));
     }
 }
Exemplo n.º 11
0
        internal static HapticPattern LoadPatternFromJson(string jsonPath)
        {
            HapticDefinitionFile hdf = LoadHDFFromJson(jsonPath);

            if (hdf.root_effect.type == "pattern")
            {
                var pat = CodeHapticFactory.CreatePatternFromHDF(hdf.root_effect.name, hdf);
                return(pat);
            }
            else
            {
                Debug.LogError("Error in LoadPatternFromJson - likely an invalid path was provided\n\t" + hdf.root_effect.name + " is of type " + hdf.root_effect.type + "\n");
                return(HapticPattern.CreateNew());
                //throw new InvalidOperationException("Unable to load " + hdf.root_effect.name + " as a HapticPattern because it is a " + hdf.root_effect.type);
            }
        }
Exemplo n.º 12
0
    IEnumerator PlayRepeatCo(HapticPattern pattern, bool rightHand)
    {
        float waitS = pattern.duration + pattern.waitDuration;

        if (pattern.hapticType == HapticType.REPEAT)
        {
            waitS *= pattern.repeat;
        }
        WaitForSeconds waitDur = new WaitForSeconds(waitS);

        while (rightHand ? isRepeatingRight : isRepeatingLeft)
        {
            Play(pattern, rightHand);
            yield return(waitDur);
        }
    }
Exemplo n.º 13
0
        /// <summary>
        /// Create a HapticExperience from a HapticDefinitionFile
        /// </summary>
        /// <param name="key"></param>
        /// <param name="hdf"></param>
        /// <returns></returns>
        public static HapticExperience CreateExperienceFromHDF(string key, HapticDefinitionFile hdf)
        {
            string cleanedKey = HapticResources.CleanName(key);

            HapticExperience exp     = ScriptableObject.CreateInstance <HapticExperience>();
            var experience_def_array = hdf.experience_definitions[key];

            foreach (var element in experience_def_array)
            {
                HapticPattern thisPat = CreatePatternFromHDF(element.pattern, hdf);
                thisPat.name = element.pattern;

                ParameterizedPattern paraPat = new ParameterizedPattern(thisPat, element.time, element.strength);
                exp.AddPattern(paraPat);
            }

            return(exp);
        }
Exemplo n.º 14
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));
        }
Exemplo n.º 15
0
    /// <summary>
    /// Play a haptic pattern
    /// </summary>
    /// <param name="pattern"></param>
    /// <param name="rightHand"></param>
    public static void Play(HapticPattern pattern, bool rightHand)
    {
        switch (pattern.hapticType)
        {
        case HapticType.SINGLE:
            Impulse(pattern.amplitude, pattern.duration, rightHand);
            break;

        case HapticType.REPEAT:
            Instance.StartCoroutine(Instance.PlayImpulsesRepeat(pattern, rightHand));
            break;

        case HapticType.CONTINUOUS:
            Instance.StartCoroutine(Instance.PlayImpulsesInf(pattern, rightHand));
            break;

        default:
            break;
        }
    }
Exemplo n.º 16
0
        public HapticHandle CreateCodeHaptic()
        {
            //Debug.Log("Hit\n");
            HapticSequence seq = new HapticSequence();

            seq.AddEffect(0.0f, new HapticEffect(Effect.Buzz, .2f));
            seq.AddEffect(0.3f, new HapticEffect(Effect.Click, 0.0f));
            //seq.Play(AreaFlag.All_Areas);

            HapticPattern pat = new HapticPattern();

            pat.AddSequence(0.5f, AreaFlag.Lower_Ab_Both, seq);
            pat.AddSequence(1.0f, AreaFlag.Mid_Ab_Both, seq);
            pat.AddSequence(1.5f, AreaFlag.Upper_Ab_Both, seq);
            pat.AddSequence(2.0f, AreaFlag.Chest_Both, seq);
            pat.AddSequence(2.5f, AreaFlag.Shoulder_Both, seq);
            pat.AddSequence(2.5f, AreaFlag.Back_Both, seq);
            pat.AddSequence(3.0f, AreaFlag.Upper_Arm_Both, seq);
            pat.AddSequence(3.5f, AreaFlag.Forearm_Both, seq);
            return(pat.CreateHandle().Play());
        }
Exemplo n.º 17
0
 public PatternImportData(HapticPattern pat, string key)
 {
     Pattern    = pat;
     saved      = false;
     PatternKey = key;
 }
Exemplo n.º 18
0
 public static void PlayBothHands(HapticPattern pattern)
 {
     Play(pattern, true);
     Play(pattern, false);
 }
Exemplo n.º 19
0
 void PlayRepeat(HapticPattern pattern, bool rightHand)
 {
     StartCoroutine(PlayRepeatCo(pattern, rightHand));
 }
Exemplo n.º 20
0
 public static void PlayPatternRepeatBothHands(HapticPattern pattern)
 {
     PlayPatternRepeat(pattern, true);
     PlayPatternRepeat(pattern, false);
 }