/// <summary> /// Looks up the pattern to play the cube lights in given the trigger name /// </summary> /// <param name="triggerName">The animation trigger name</param> /// <returns>A sequence of light patterns to display</returns> public IReadOnlyList <LightsPattern> CubeLightsForTrigger(string triggerName) { // See if the description is already loaded var ret = CubeLightsCache(triggerName); if (null != ret) { return((IReadOnlyList <LightsPattern>)ret); } // look up name for the file if (!cubeTriggerName2Filename.TryGetValue(triggerName, out var partialName)) { return(null); } var path = CubeLightsPath(partialName); // Get the text for the file var text = File.ReadAllText(path); // Get it in a convenient form // Decode the JSON file. The format varies a little between Cozmo and Vector CubeLightSequence[] topLevel; if (AssetsType.Vector == AssetsType) { topLevel = JSONDeserializer.Deserialize <CubeLightSequence[]>(text); } else { // Cozmo has more level of indirection var tmp = JSONDeserializer.Deserialize <Dictionary <string, CubeLightSequence[]> >(text); // TODO: check the number of keys topLevel = tmp[partialName]; } // Convert it into the final internal form var sequences = new List <LightsPattern>(); foreach (var t in topLevel) { // Create something to hold info about this part of the sequence var s = new LightsPattern(); s.name = t.patternDebugName; s.canBeOverridden = t.canBeOverridden; s.duration_ms = t.duration_ms; var lightKeyFrames = new List <LightFrame> [4]; s.lightKeyFrames = lightKeyFrames; sequences.Add(s); // Convert the patterns for the lights var lights = t.pattern; for (var idx = 0; idx < 4; idx++) { // Start the trigger time with the offset for the light uint triggerTime = (uint)lights.offset[idx]; // Create the on frame first var rgba = lights.onColors[idx]; // Ignore alpha var color = Color.FromArgb(255, rgba[0], rgba[1], rgba[2]); var lightFrame = new LightFrame(triggerTime, (uint)lights.onPeriod_ms[idx], color); var a = new List <LightFrame> { lightFrame }; // Compute the trigger time of the off period triggerTime += (uint)(lights.onPeriod_ms[idx] + lights.transitionOnPeriod_ms[idx]); // Create the off frame next rgba = lights.offColors[idx]; // Ignore alpha color = Color.FromArgb(255, rgba[0], rgba[1], rgba[2]); lightFrame = new LightFrame(triggerTime, (uint)lights.offPeriod_ms[idx], color); triggerTime += (uint)(lights.offPeriod_ms[idx] + lights.transitionOffPeriod_ms[idx]); a.Add(lightFrame); var duration = triggerTime - lights.offset[idx]; // Put these key frames for the light in lightKeyFrames[idx] = a; } } var seq = sequences.ToArray(); // cache it CubeLightsCache(triggerName, seq); // return it return(seq); }
/// <summary> /// Looks up the pattern to play the backpack lights in given the trigger name /// </summary> /// <param name="triggerName">The animation trigger name</param> /// <returns>A sequence of light patterns to display</returns> public IReadOnlyList <LightsPattern> BackpackLightsForTrigger(string triggerName) { // See if the description is already loaded var ret = BackpackLightsCache(triggerName); if (null != ret) { return(ret); } // look up name for the file if (!backpackTriggerName2Filename.TryGetValue(triggerName, out var partialName)) { return(null); } var path = BackpackLightsPath(partialName); // Get the text for the file var text = File.ReadAllText(path); // Get it in a convenient form var JSONOptions = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true, IgnoreNullValues = true }; var lights = JsonSerializer.Deserialize <BackpackLights>(text, JSONOptions); var numLights = AssetsType.Cozmo == AssetsType?4:3; var lightKeyFrames = new List <LightFrame> [numLights]; // Convert it into the final internal form for (var idx = 0; idx < numLights; idx++) { // Start the trigger time with the offset for the light uint triggerTime = (uint)lights.offset[idx]; // Create the on frame first var rgba = lights.onColors[idx]; // Ignore alpha var color = Color.FromArgb(255, (byte)(255 * rgba[0]), (byte)(255 * rgba[1]), (byte)(255 * rgba[2])); var lightFrame = new LightFrame(triggerTime, (uint)lights.onPeriod_ms[idx], color); var a = new List <LightFrame> { lightFrame }; // Compute the trigger time of the off period triggerTime += (uint)(lights.onPeriod_ms[idx] + lights.transitionOnPeriod_ms[idx]); // Create the off frame next rgba = lights.offColors[idx]; // Ignore alpha color = Color.FromArgb(255, (byte)(255 * rgba[0]), (byte)(255 * rgba[1]), (byte)(255 * rgba[2])); lightFrame = new LightFrame(triggerTime, (uint)lights.offPeriod_ms[idx], color); triggerTime += (uint)(lights.offPeriod_ms[idx] + lights.transitionOffPeriod_ms[idx]); var duration = triggerTime - lights.offset[idx]; a.Add(lightFrame); // Put these key frames for the light in lightKeyFrames[idx] = a; } var s = new LightsPattern(); s.lightKeyFrames = lightKeyFrames; // Convert it back to an array var sequences = new LightsPattern[1] { s }; // cache it BackpackLightsCache(triggerName, sequences); // return it return(sequences); }