public void Add(SceneNode node, uint duration, Vector3Df targetPosition, Vector3Df targetRotation, Vector3Df targetScale) { Remove(node); irrDevice.Timer.Tick(); AnimationItem a = new AnimationItem(); a.Node = node; a.Node.Grab(); a.Duration = duration; a.StartTime = irrDevice.Timer.Time; if (targetPosition != null) { a.TargetPosition = targetPosition; a.StartPosition = node.Position; } if (targetRotation != null) { a.TargetRotation = targetRotation; a.StartRotation = node.Rotation; } if (targetScale != null) { a.TargetScale = targetScale; a.StartScale = node.Scale; } lock (animationItems) { animationItems.Add(a); } }
private static void OnComplete(AnimationItem completedItem) { if (queue.Count == 0) { return; } AnimationItem item = queue[0]; if (item.id != completedItem.id) { completedItem.complete = true; } else { queue.RemoveAt(0); if (queue.Count > 0 && !queue[0].isRunning) { AnimationItem nextItem = queue[0]; nextItem.StartAnimation(); if (nextItem.complete) { AnimationQueue.OnComplete(nextItem); } } } }
public List <AnimationItem> Create(AssetPackage[] assetPackages) { if (_snapScrolling != null) { for (int ii = 0; ii < assetPackages.Length; ii++) { AssetPackage assetPackage = assetPackages[ii]; GameObject newPanel = _snapScrolling.CreateAPanel(); GifferManager newPanelGifferManager = newPanel.GetComponent <GifferManager>(); Sprite[] animationSprites = Array.ConvertAll(assetPackage.assets, sprites => sprites as Sprite); string animationName = assetPackage.GetAssetName(); newPanelGifferManager.AddAnimationEntity(animationName, animationSprites); AnimationItem animationItem = newPanel.AddComponent <AnimationItem>(); animationItem.Init(_targetAnim, animationName, repeatRate); animationItem.OnClicked += StopAllAnimationItems; animationItems.Add(animationItem); newPanelGifferManager.enabled = true; } } else { Debug.LogError("Snap Scrolling is null."); } return(animationItems); }
public AnimationItem Add(string animationBaseName, bool allowRandomAnimationNumber, bool loop) { //remove from removedItemsForBlending if (blendingTime != 0) { for (int n = 0; n < removedItemsForBlending.Count; n++) { AnimationItem removedItem = removedItemsForBlending[n]; if (removedItem.AnimationBaseName == animationBaseName) { removedItem.animationState.Enable = false; removedItemsForBlending.RemoveAt(n); n--; continue; } } } string animationName = animationBaseName; if (allowRandomAnimationNumber) { int number = GetRandomAnimationNumber(animationBaseName, true); if (number != 1) { animationName += number.ToString(); } } MeshObject.AnimationState animationState = meshObject.GetAnimationState(animationName); if (animationState == null) { return(null); } animationState.Loop = loop; animationState.TimePosition = 0; animationState.Enable = true; AnimationItem item = new AnimationItem(this, animationBaseName, allowRandomAnimationNumber, loop); if (blendingTime != 0) { item.blendingWeightCoefficient = .001f; } else { item.blendingWeightCoefficient = 1; } item.animationState = animationState; activeItems.Add(item); UpdateAnimationStatesWeights(); return(item); }
private IEnumerator AnimationDelay(AnimationItem item, float delayTime) { yield return(Yielders.GetWaitForSeconds(delayTime)); coroutines.Remove(item.obj); if (!animationItems.ContainsKey(item.obj)) { this.animationItems.Add(item.obj, item); } }
public void StopAllAnimationItems(AnimationItem item) { foreach (AnimationItem animationItem in animationItems) { if (item == animationItem) { continue; } animationItem.Stop(); } }
public void Play(string name, bool isReverseOrder = false, Action endCallBack = null) { AnimationItem anim = this._animMap[name]; anim.isReverseOrder = isReverseOrder; anim.AnimationAllEndCallBack = endCallBack; if (base.gameObject.activeInHierarchy) { base.StartCoroutine(this.PlayAnim(anim)); } }
//OnStateEnter is called when a transition starts and the state machine starts to evaluate this state override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { foreach (var animationItem in _animationManager.animationItems) { if (stateInfo.IsName(animationItem.animationName)) { _currentAnimationItem = animationItem; _currentAnimationItem.RadialProgressBar.SetMaxAmount(stateInfo.length); break; } } }
public bool Next() { if (isStart == false) { isStart = true; startTime = Time.time; InitializeAnimation(); } var elapsedTime = Time.time - startTime; var addTime = 0.0f; foreach (var item in CurrentAnimationItems) { addTime = item.Key + item.Value.Time; // すべてのアニメーションの時間+今のアニメーション時間 if (addTime >= elapsedTime) { // 経過時間がまだアニメーションの終了時間に届いていない間(アニメーション中) //Debug.Log($"AnimationTime:{elapsedTime}"); if (lastitem != null && EndLastItem != lastitem) { // 前回のアニメーションが終わりまで行ってない場合があるので100%で実行 lastitem.RunAction(lastitem.EndValue); EndLastItem = lastitem; } if (CurrentItem != item.Value) { if (lastitem != null) { // 前回のアニメーションが終わりまで行ってない場合があるので100%で実行 lastitem.RunAction(lastitem.EndValue); EndLastItem = lastitem; } // 新しいアニメーションになったときには時間にかかわらずきちんと最初の値を使う item.Value.RunAction(item.Value.StartValue); CurrentItem = item.Value; } else { var currentTime = item.Value.Time + (elapsedTime - addTime); var setvalue = item.Value.StartValue + (item.Value.EndValue - item.Value.StartValue) * (currentTime / item.Value.Time); item.Value.RunAction(setvalue); } lastitem = item.Value; return(true); } } // 最後までアニメーションしたとき if (lastitem != null) { // 最後のアニメーションが終わりまで行ってない場合があるので100%で実行 lastitem.RunAction(lastitem.EndValue); } isStart = false; return(false); }
private void UpdateAnimation(AnimationItem item) { bool isDone = true; if (item.parameter.isColor) { isDone &= (item.obj == null || AnimationColor.Color(item)); } if (item.parameter.isFading) { isDone &= (item.obj == null || AnimationFade.Fade(item)); } if (item.parameter.isResizing) { isDone &= (item.obj == null || AnimationSize.Resize(item)); } if (item.parameter.isRotating) { isDone &= (item.obj == null || AnimationRotate.Rotate(item)); } if (item.parameter.isScaling) { isDone &= (item.obj == null || AnimationScale.Scale(item)); } if (item.parameter.isMoving) { isDone &= (item.obj == null || AnimationMove.Move(item)); } item.frameCallback?.Invoke(); if (isDone) { if (item.callback != null) { if (!actions.Contains(item.callback)) { actions.Add(item.callback); } } removeList.Add(item.obj); } else { if (item.parameter.isRealTime) { item.time += Time.unscaledDeltaTime; } else { item.time += Time.deltaTime; } } }
public static Animation GetAnimation(string name) { AnimationItem item; if (!Animations.ContainsKey(name)) { item = new AnimationItem(SpriteBank.Game); item.AssetName = name; Animations.Add(name, item); } else item = Animations[name]; return item.Animation; }
private void InitializeAnimation() { CurrentAnimationItems.Clear(); EndLastItem = null; CurrentItem = null; var starttime = 0.0f; foreach (var item in AnimationItems) { item.Initialize(); CurrentAnimationItems.Add(starttime, item); starttime += item.Time == 0.0f ? 0.0001f : item.Time; } }
public void Run() { lock (animationItems) { uint t = irrDevice.Timer.Time; List <int> candidatesToBeRemoved = new List <int>(); for (int i = 0; i < animationItems.Count; i++) { AnimationItem a = animationItems[i]; if (t >= a.StartTime + a.Duration) { setFinalAnimationState(i); candidatesToBeRemoved.Add(i); } else { double d = (double)(t - a.StartTime) / a.Duration; if (a.TargetPosition != null) { Vector3Df v = a.Node.Position; v.Interpolate(a.TargetPosition, a.StartPosition, d); a.Node.Position = v; } if (a.TargetRotation != null) { Vector3Df v = a.Node.Rotation; v.Interpolate(a.TargetRotation, a.StartRotation, d); a.Node.Rotation = v; } if (a.TargetScale != null) { Vector3Df v = a.Node.Scale; v.Interpolate(a.TargetScale, a.StartScale, d); a.Node.Scale = v; } } } for (int i = candidatesToBeRemoved.Count - 1; i >= 0; i--) { animationItems[candidatesToBeRemoved[i]].Node.Drop(); animationItems.RemoveAt(candidatesToBeRemoved[i]); } } }
public static Animation GetAnimation(string name, int width, int height, int framePerLine, int numberOfFrame) { AnimationItem item = Animations[name]; if (item == null) { item = new AnimationItem(SpriteBank.Game); item.AssetName = name; Animations[name] = item; } item.FrameWidth = width; item.FrameHeight = height; item.FramePerLine = framePerLine; item.NumberOfFrames = numberOfFrame; return item.Animation; }
public void ShowAnimation(AnimationItem animator) { if (this.Items.Count > 0) { this.Items.Clear(); } this.Items.Add(animator); if (this.AutoAdjustPosition) { this.AdjustPosition(); } this.Invalidate(); }
private void changeState(AnimationItem currentAnimation) { if (currentAnimation.GetVector().y > 0) { state = State.climbing; } else if (currentAnimation.GetVector().y == 0) { if (animationQueue.Count != 0 && animationQueue.Peek().GetVector().y != 0) { state = State.falling; } else { state = State.moving; } } }
// Add wait time override for simultaneous animations? public static Action Add(Action StartAnimation, float wait = 0) { Action OnComplete = () => AnimationQueue.OnComplete(nextId); AnimationItem item = new AnimationItem(nextId, StartAnimation); queue.Add(item); nextId++; if (queue.Count == 1) { item.StartAnimation(); } if (wait != 0) { Timer.TimeoutAction(OnComplete, wait); } return(OnComplete); }
void setFinalAnimationState(int i) { AnimationItem a = animationItems[i]; if (a.TargetPosition != null) { a.Node.Position = a.TargetPosition; } if (a.TargetRotation != null) { a.Node.Rotation = a.TargetRotation; } if (a.TargetScale != null) { a.Node.Scale = a.TargetScale; } }
public static void PlayAnimation(GameObject obj, string name, float startTime = 0, UnityAction finishCallback = null, UnityAction frameCallback = null) { AnimationParam param = Instance.GetAnimationParam(obj, name); if (obj == null || param == null) { return; } AnimationItem item = new AnimationItem { obj = obj, time = startTime, parameter = param, callback = finishCallback, frameCallback = frameCallback }; if (param.delay != 0) { if (Instance.coroutines.ContainsKey(obj)) { Instance.StopCoroutine(Instance.coroutines[obj]); Instance.coroutines[obj] = Instance.StartCoroutine(Instance.AnimationDelay(item, param.delay)); } else { Instance.coroutines.Add(obj, Instance.StartCoroutine(Instance.AnimationDelay(item, param.delay))); } } else { if (Instance.animationItems.ContainsKey(obj)) { Instance.animationItems[obj] = item; } else { Instance.animationItems.Add(obj, item); } } }
private void HideAllObjectInAnim(AnimationItem anim) { foreach (StepItem item in anim.stepList) { foreach (FadeInItem item2 in item.fadeInList) { if (item2.gameObject.activeSelf) { CanvasGroup component = item2.gameObject.GetComponent <CanvasGroup>(); if (item2.type == FadeInItem.Type.FadeOut) { component.alpha = 1f; } else { component.alpha = 0f; } } } } }
void UpdateAnimationStatesWeights() { float totalWeight = 0; { for (int n = 0; n < activeItems.Count; n++) { AnimationItem item = activeItems[n]; totalWeight += item.Weight * item.blendingWeightCoefficient; } for (int n = 0; n < removedItemsForBlending.Count; n++) { AnimationItem item = removedItemsForBlending[n]; totalWeight += item.Weight * item.blendingWeightCoefficient; } } float multiplier = 1; if (totalWeight > 0 && totalWeight < 1) { multiplier = 1.0f / totalWeight; } //update animation states { for (int n = 0; n < activeItems.Count; n++) { AnimationItem item = activeItems[n]; item.animationState.Weight = item.Weight * item.blendingWeightCoefficient * multiplier; } for (int n = 0; n < removedItemsForBlending.Count; n++) { AnimationItem item = removedItemsForBlending[n]; item.animationState.Weight = item.Weight * item.blendingWeightCoefficient * multiplier; } } }
public void Remove(AnimationItem item) { if (item.removed) { return; } if (blendingTime == 0) { item.animationState.Enable = false; } item.removed = true; activeItems.Remove(item); if (blendingTime != 0) { removedItemsForBlending.Add(item); } UpdateAnimationStatesWeights(); }
public void SaveItemInfo(ItemInfo itemInfo, string basePath, string heroFileName, ICLIFlags flags, STUHero hero, string eventKey, Dictionary <string, ParsedArg> config, Dictionary <string, TagExpectedValue> tags, List <ItemInfo> weaponSkins) { if (itemInfo?.Unlock == null) { return; } if (itemInfo.Unlock.LeagueTeam != null) { STULeagueTeam team = GetInstance <STULeagueTeam>(itemInfo.Unlock.LeagueTeam); tags["leagueTeam"] = new TagExpectedValue(GetString(team.Abbreviation), // NXL GetString(team.Location), // New York GetString(team.Name), // Excelsior $"{GetString(team.Location)} {GetString(team.Name)}", // New York Excelsior "*"); // all eventKey = "League"; itemInfo.Rarity = ""; } else { tags["leagueTeam"] = new TagExpectedValue("none"); } if (eventKey == "Achievement" && itemInfo.Type == "Skin") { itemInfo.Rarity = ""; } tags["rarity"] = new TagExpectedValue(itemInfo.Rarity); if (itemInfo.Type == "Spray" && config.ContainsKey("spray") && config["spray"].ShouldDo(itemInfo.Name, tags)) { SprayAndIcon.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "PlayerIcon" && config.ContainsKey("icon") && config["icon"].ShouldDo(itemInfo.Name, tags)) { SprayAndIcon.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "Skin" && config.ContainsKey("skin") && config["skin"].ShouldDo(itemInfo.Name, tags)) { Skin.Save(flags, $"{basePath}\\{RootDir}", hero, $"{eventKey}\\{itemInfo.Rarity}", itemInfo.Unlock as STUUnlock_Skin, weaponSkins, null, false); } if (itemInfo.Type == "Pose" && config.ContainsKey("victorypose") && config["victorypose"].ShouldDo(itemInfo.Name, tags)) { AnimationItem.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "HighlightIntro" && config.ContainsKey("highlightintro") && config["highlightintro"].ShouldDo(itemInfo.Name, tags)) { AnimationItem.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "Emote" && config.ContainsKey("emote") && config["emote"].ShouldDo(itemInfo.Name, tags)) { AnimationItem.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo); } if (itemInfo.Type == "VoiceLine" && config.ContainsKey("voiceline") && config["voiceline"].ShouldDo(itemInfo.Name, tags)) { VoiceLine.SaveItem(basePath, heroFileName, RootDir, eventKey, flags, itemInfo, hero); } }
public void DoRenderFrame() { float delta = RendererWorld.Instance.FrameRenderTimeStep; for (int n = 0; n < activeItems.Count; n++) { AnimationItem item = activeItems[n]; MeshObject.AnimationState animationState = item.animationState; //time progress animationState.AddTime(item.Velocity * delta); //has ended? if (!item.Loop) { if (animationState.TimePosition + blendingTime * 2 + .001f >= item.animationState.Length) { Remove(item); n--; continue; } } //change random animation if (item.Loop && item.AllowRandomAnimationNumber) { //detect rewind if (animationState.TimePosition < item.lastTimePosition) { string animationName = item.AnimationBaseName; int number = GetRandomAnimationNumber(animationName, true); if (number != 1) { animationName += number.ToString(); } MeshObject.AnimationState newAnimationState = meshObject.GetAnimationState(animationName); if (newAnimationState == null) { Log.Fatal("MeshObjectAnimationController: DoRenderFrame: " + "newAnimationState == null."); } animationState.Enable = false; newAnimationState.Loop = animationState.Loop; newAnimationState.TimePosition = animationState.TimePosition; newAnimationState.Weight = animationState.Weight; newAnimationState.Enable = true; item.animationState = newAnimationState; } } //update weight for blending if (blendingTime != 0) { item.blendingWeightCoefficient += delta / blendingTime; if (item.blendingWeightCoefficient > 1) { item.blendingWeightCoefficient = 1; } } item.lastTimePosition = animationState.TimePosition; } for (int n = 0; n < removedItemsForBlending.Count; n++) { AnimationItem item = removedItemsForBlending[n]; item.blendingWeightCoefficient -= delta / blendingTime; if (item.blendingWeightCoefficient <= 0) { item.animationState.Enable = false; removedItemsForBlending.RemoveAt(n); n--; continue; } } UpdateAnimationStatesWeights(); }
public AnimationItem Add( string animationBaseName, bool allowRandomAnimationNumber, bool loop ) { //remove from removedItemsForBlending if( blendingTime != 0 ) { for( int n = 0; n < removedItemsForBlending.Count; n++ ) { AnimationItem removedItem = removedItemsForBlending[ n ]; if( removedItem.AnimationBaseName == animationBaseName ) { removedItem.animationState.Enable = false; removedItemsForBlending.RemoveAt( n ); n--; continue; } } } string animationName = animationBaseName; if( allowRandomAnimationNumber ) { int number = GetRandomAnimationNumber( animationBaseName, true ); if( number != 1 ) animationName += number.ToString(); } MeshObject.AnimationState animationState = meshObject.GetAnimationState( animationName ); if( animationState == null ) return null; animationState.Loop = loop; animationState.TimePosition = 0; animationState.Enable = true; AnimationItem item = new AnimationItem( this, animationBaseName, allowRandomAnimationNumber, loop ); if( blendingTime != 0 ) item.blendingWeightCoefficient = .001f; else item.blendingWeightCoefficient = 1; item.animationState = animationState; activeItems.Add( item ); UpdateAnimationStatesWeights(); return item; }
public void Remove( AnimationItem item ) { if( item.removed ) return; if( blendingTime == 0 ) item.animationState.Enable = false; item.removed = true; activeItems.Remove( item ); if( blendingTime != 0 ) removedItemsForBlending.Add( item ); UpdateAnimationStatesWeights(); }
public bool SaveAsGif(AnimationItem aniItem, string fileName, ImageHandlerConfig config, bool options) { var rec = new AnimationRecoder(this.GraphicsDevice); rec.Items.Add(aniItem); int length = rec.GetMaxLength(); int delay = Math.Max(10, config.MinDelay); var timeline = rec.GetGifTimeLine(delay, 655350); // calc available canvas area rec.ResetAll(); Microsoft.Xna.Framework.Rectangle bounds = aniItem.Measure(); if (length > 0) { IEnumerable <int> delays = timeline?.Take(timeline.Length - 1) ?? Enumerable.Range(0, (int)Math.Ceiling(1.0 * length / delay) - 1); foreach (var frameDelay in delays) { rec.Update(TimeSpan.FromMilliseconds(frameDelay)); var rect = aniItem.Measure(); bounds = Microsoft.Xna.Framework.Rectangle.Union(bounds, rect); } } bounds.Offset(aniItem.Position); // customize clip/scale options AnimationClipOptions clipOptions = new AnimationClipOptions() { StartTime = 0, StopTime = length, Left = bounds.Left, Top = bounds.Top, Right = bounds.Right, Bottom = bounds.Bottom, OutputWidth = bounds.Width, OutputHeight = bounds.Height, }; if (options) { var frmOptions = new FrmGifClipOptions() { ClipOptions = clipOptions, ClipOptionsNew = clipOptions, }; if (frmOptions.ShowDialog() == DialogResult.OK) { var clipOptionsNew = frmOptions.ClipOptionsNew; clipOptions.StartTime = clipOptionsNew.StartTime ?? clipOptions.StartTime; clipOptions.StopTime = clipOptionsNew.StopTime ?? clipOptions.StopTime; clipOptions.Left = clipOptionsNew.Left ?? clipOptions.Left; clipOptions.Top = clipOptionsNew.Top ?? clipOptions.Top; clipOptions.Right = clipOptionsNew.Right ?? clipOptions.Right; clipOptions.Bottom = clipOptionsNew.Bottom ?? clipOptions.Bottom; clipOptions.OutputWidth = clipOptionsNew.OutputWidth ?? (clipOptions.Right - clipOptions.Left); clipOptions.OutputHeight = clipOptionsNew.OutputHeight ?? (clipOptions.Bottom - clipOptions.Top); } else { return(false); } } // validate params bounds = new Rectangle( clipOptions.Left.Value, clipOptions.Top.Value, clipOptions.Right.Value - clipOptions.Left.Value, clipOptions.Bottom.Value - clipOptions.Top.Value ); var targetSize = new Point(clipOptions.OutputWidth.Value, clipOptions.OutputHeight.Value); var startTime = clipOptions.StartTime.Value; var stopTime = clipOptions.StopTime.Value; if (bounds.Width <= 0 || bounds.Height <= 0 || targetSize.X <= 0 || targetSize.Y <= 0 || startTime < 0 || stopTime > length || stopTime - startTime < 0) { return(false); } length = stopTime - startTime; // create output dir string framesDirName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".frames"); if (config.SavePngFramesEnabled && !Directory.Exists(framesDirName)) { Directory.CreateDirectory(framesDirName); } // pre-render rec.ResetAll(); switch (config.BackgroundType.Value) { default: case ImageBackgroundType.Transparent: rec.BackgroundColor = Color.TransparentBlack; break; case ImageBackgroundType.Color: rec.BackgroundColor = System.Drawing.Color.FromArgb(255, config.BackgroundColor.Value).ToXnaColor(); break; case ImageBackgroundType.Mosaic: rec.BackgroundImage = MonogameUtils.CreateMosaic(GraphicsDevice, config.MosaicInfo.Color0.ToXnaColor(), config.MosaicInfo.Color1.ToXnaColor(), Math.Max(1, config.MosaicInfo.BlockSize)); break; } // select encoder GifEncoder enc = AnimateEncoderFactory.CreateEncoder(fileName, targetSize.X, targetSize.Y, config); var encParams = AnimateEncoderFactory.GetEncoderParams(config.GifEncoder.Value); // pipeline functions IEnumerable <Tuple <byte[], int> > MergeFrames(IEnumerable <Tuple <byte[], int> > frames) { byte[] prevFrame = null; int prevDelay = 0; foreach (var frame in frames) { byte[] currentFrame = frame.Item1; int currentDelay = frame.Item2; if (prevFrame == null) { prevFrame = currentFrame; prevDelay = currentDelay; } else if (memcmp(prevFrame, currentFrame, (IntPtr)prevFrame.Length) == 0) { prevDelay += currentDelay; } else { yield return(Tuple.Create(prevFrame, prevDelay)); prevFrame = currentFrame; prevDelay = currentDelay; } } if (prevFrame != null) { yield return(Tuple.Create(prevFrame, prevDelay)); } } IEnumerable <int> RenderDelay() { int t = 0; while (t < length) { int frameDelay = Math.Min(length - t, delay); t += frameDelay; yield return(frameDelay); } } IEnumerable <int> ClipTimeline(int[] _timeline) { int t = 0; for (int i = 0; i < timeline.Length; i++) { var frameDelay = timeline[i]; if (t < startTime) { if (t + frameDelay > startTime) { frameDelay = t + frameDelay - startTime; t = startTime; } else { t += frameDelay; continue; } } if (t + frameDelay < stopTime) { yield return(frameDelay); t += frameDelay; } else { frameDelay = stopTime - t; yield return(frameDelay); break; } } } int prevTime = 0; async Task <int> ApplyFrame(byte[] frameData, int frameDelay) { byte[] gifData = null; if (!encParams.SupportAlphaChannel && config.BackgroundType.Value == ImageBackgroundType.Transparent) { using (var rt2 = rec.GetGifTexture(config.BackgroundColor.Value.ToXnaColor(), config.MinMixedAlpha)) { if (gifData == null) { gifData = new byte[frameData.Length]; } rt2.GetData(gifData); } } else { gifData = frameData; } var tasks = new List <Task>(); // save each frame as png if (config.SavePngFramesEnabled) { tasks.Add(Task.Run(() => { string pngFileName = Path.Combine(framesDirName, $"{prevTime}_{prevTime + frameDelay}.png"); unsafe { fixed(byte *pFrameBuffer = frameData) { using (var bmp = new System.Drawing.Bitmap(targetSize.X, targetSize.Y, targetSize.X * 4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, new IntPtr(pFrameBuffer))) { bmp.Save(pngFileName, System.Drawing.Imaging.ImageFormat.Png); } } } })); } // append frame data to gif stream tasks.Add(Task.Run(() => { // TODO: only for gif here? frameDelay = Math.Max(10, (int)(Math.Round(frameDelay / 10.0) * 10)); unsafe { fixed(byte *pGifBuffer = gifData) { enc.AppendFrame(new IntPtr(pGifBuffer), frameDelay); } } })); await Task.WhenAll(tasks); prevTime += frameDelay; return(prevTime); } async Task RenderJob(IProgressDialogContext context, CancellationToken cancellationToken) { bool isCompareAndMergeFrames = timeline == null; // build pipeline IEnumerable <int> delayEnumerator = timeline == null?RenderDelay() : ClipTimeline(timeline); var step1 = delayEnumerator.TakeWhile(_ => !cancellationToken.IsCancellationRequested); var frameRenderEnumerator = step1.Select(frameDelay => { rec.Draw(); rec.Update(TimeSpan.FromMilliseconds(frameDelay)); return(frameDelay); }); var step2 = frameRenderEnumerator.TakeWhile(_ => !cancellationToken.IsCancellationRequested); var getFrameData = step2.Select(frameDelay => { using (var t2d = rec.GetPngTexture()) { byte[] frameData = new byte[t2d.Width * t2d.Height * 4]; t2d.GetData(frameData); return(Tuple.Create(frameData, frameDelay)); } }); var step3 = getFrameData.TakeWhile(_ => !cancellationToken.IsCancellationRequested); if (isCompareAndMergeFrames) { var mergedFrameData = MergeFrames(step3); step3 = mergedFrameData.TakeWhile(_ => !cancellationToken.IsCancellationRequested); } var step4 = step3.Select(item => ApplyFrame(item.Item1, item.Item2)); // run pipeline bool isPlaying = this.IsPlaying; try { this.IsPlaying = false; rec.Begin(bounds, targetSize); if (startTime > 0) { rec.Update(TimeSpan.FromMilliseconds(startTime)); } context.ProgressMin = 0; context.ProgressMax = length; foreach (var task in step4) { int currentTime = await task; context.Progress = currentTime; } } catch (Exception ex) { context.Message = $"Error: {ex.Message}"; throw; } finally { rec.End(); enc.Dispose(); this.IsPlaying = isPlaying; } } var dialogResult = ProgressDialog.Show(this.FindForm(), "Exporting...", "Save animation file...", true, false, RenderJob); return(dialogResult == DialogResult.OK); }
public void SaveAsGif(AnimationItem aniItem, string fileName, ImageHandlerConfig config) { //保存动画 天坑代码 var rec = new AnimationRecoder(this.GraphicsDevice); rec.Items.Add(aniItem); int length = rec.GetMaxLength(); //rec.GetGifTimeLine(30); 放弃获取时间轴 //预判大小阶段 rec.ResetAll(); Microsoft.Xna.Framework.Rectangle?bounds = null; int delay = Math.Max(10, config.MinDelay); for (int d = 0; d <= length; d += delay) { rec.Update(TimeSpan.FromMilliseconds(delay)); var rect = aniItem.Measure(); rect.Offset(aniItem.Position); bounds = (bounds == null || bounds.Value.IsEmpty) ? rect : Microsoft.Xna.Framework.Rectangle.Union(rect, bounds.Value); } //绘制阶段 rec.ResetAll(); switch (config.BackgroundType.Value) { default: case ImageBackgroundType.Transparent: rec.BackgroundColor = Color.TransparentBlack; break; case ImageBackgroundType.Color: rec.BackgroundColor = System.Drawing.Color.FromArgb(255, config.BackgroundColor.Value).ToXnaColor(); break; case ImageBackgroundType.Mosaic: rec.BackgroundImage = MonogameUtils.CreateMosaic(GraphicsDevice, config.MosaicInfo.Color0.ToXnaColor(), config.MosaicInfo.Color1.ToXnaColor(), Math.Max(1, config.MosaicInfo.BlockSize)); break; } byte[] buffer = new byte[bounds.Value.Width * bounds.Value.Height * 4]; byte[] bufferPrev = null, bufferGif = null; int gifTime = 0, prevTime = 0; string dirName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".frames"); if (config.SavePngFramesEnabled && !Directory.Exists(dirName)) { Directory.CreateDirectory(dirName); } //选择encoder GifEncoder enc = AnimateEncoderFactory.CreateEncoder(fileName, bounds.Value.Width, bounds.Value.Height, config); var encParams = AnimateEncoderFactory.GetEncoderParams(config.GifEncoder.Value); Action <int> writeFrame = (curTime) => { unsafe { string pngFileName = Path.Combine(dirName, prevTime + ".png"); fixed(byte *pBuffer = bufferPrev, pBufferGif = bufferGif) { using (var bmp = new System.Drawing.Bitmap(bounds.Value.Width, bounds.Value.Height, bounds.Value.Width * 4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, new IntPtr(pBuffer))) { var tasks = new List <Task>(); if (config.SavePngFramesEnabled) //保存单帧图像 { tasks.Add(Task.Factory.StartNew( () => bmp.Save(pngFileName, System.Drawing.Imaging.ImageFormat.Png) )); } //保存gif帧 int frameDelay = curTime - gifTime; frameDelay = (int)(Math.Round(frameDelay / 10.0) * 10); if (frameDelay > 0) { gifTime += frameDelay; var pData = new IntPtr(pBufferGif); tasks.Add(Task.Factory.StartNew(() => enc.AppendFrame(pData, frameDelay) )); } Task.WaitAll(tasks.ToArray()); } } } }; rec.Begin(bounds.Value); //0长度补丁 for (int d = 0; d <= length; d += delay, rec.Update(TimeSpan.FromMilliseconds(delay))) { rec.Draw(); using (var rt = rec.GetPngTexture()) { rt.GetData(buffer); //比较上一帧 if (bufferPrev != null) { //跳过当前帧 if (memcmp(buffer, bufferPrev, (IntPtr)buffer.Length) == 0) { continue; } else //计算时间 输出 { writeFrame(d); } } else { bufferPrev = new byte[bounds.Value.Width * bounds.Value.Height * 4]; } //交换缓冲区 var temp = buffer; buffer = bufferPrev; bufferPrev = temp; prevTime = d; //透明 额外导出一份gif if (!encParams.SupportAlphaChannel && config.BackgroundType.Value == ImageBackgroundType.Transparent) { using (var rt2 = rec.GetGifTexture(config.BackgroundColor.Value.ToXnaColor(), config.MinMixedAlpha)) { if (bufferGif == null) { bufferGif = new byte[bufferPrev.Length]; } rt2.GetData(bufferGif); } } else { bufferGif = bufferPrev; } } } //输出最后一帧 if (prevTime < length) { writeFrame(length); } else if (length <= 0) //0长度补丁 { writeFrame(100); } //保存动画长度 if (config.SavePngFramesEnabled) { File.WriteAllText(Path.Combine(dirName, "delay.txt"), length.ToString()); } rec.End(); enc.Dispose(); }
// internal TransformItem( MapItem owner ) { this.owner = owner; animation = new AnimationItem( this ); }
private IEnumerator PlayAnim(AnimationItem anim) { return(new < PlayAnim > c__Iterator74 { anim = anim, <$> anim = anim, <> f__this = this });
public static void SaveUnlock(ICLIFlags flags, Unlock unlock, string path, string eventKey, Dictionary <string, ParsedArg> config, Dictionary <string, TagExpectedValue> tags, VoiceSet voiceSet, STUHero hero) { string rarity; if (tags != null) { if (unlock.STU.m_0B1BA7C1 == null) { rarity = unlock.Rarity.ToString(); tags["leagueTeam"] = new TagExpectedValue("none"); } else { TeamDefinition teamDef = new TeamDefinition(unlock.STU.m_0B1BA7C1); tags["leagueTeam"] = new TagExpectedValue(teamDef.Abbreviation, // NY teamDef.Location, // New York teamDef.Name, // Excelsior teamDef.FullName, // New York Excelsior (teamDef.Division == Enum_5A789F71.None && teamDef.Abbreviation == null) ? "none" : "*", "*"); // all // nice file structure rarity = ""; eventKey = "League"; } tags["rarity"] = new TagExpectedValue(unlock.Rarity.ToString()); tags["special"] = new TagExpectedValue(unlock.Tag ?? "none"); } else { rarity = ""; // for general unlocks } var eventMap = GetEventConfig(); if (unlock.STU.m_BEE9BCDA != null) { var formalEventKey = unlock.STU.m_BEE9BCDA.FirstOrDefault(x => eventMap.ContainsKey(x)); if (eventMap.ContainsKey(formalEventKey)) { eventKey = eventMap[formalEventKey]; } } string thisPath = Path.Combine(path, unlock.GetTypeNameEnum(), eventKey, rarity, GetValidFilename(unlock.GetName())); if (ShouldDo(unlock, config, tags, typeof(STUUnlock_SprayPaint))) { SprayAndIcon.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_AvatarPortrait))) { SprayAndIcon.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_POTGAnimation))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_Emote))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_Pose))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_VoiceLine))) { VoiceLine.Save(flags, thisPath, unlock, voiceSet); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_SkinTheme))) { SkinTheme.Save(flags, thisPath, unlock, hero); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_PortraitFrame))) { thisPath = Path.Combine(path, unlock.Type); PortraitFrame.Save(flags, thisPath, unlock); } }
void Parse(string animationSpec) { List <AnimationItem> parsedItems = new List <AnimationItem> (); string[] items = animationSpec.Split(';'); AnimationItem last = null; foreach (var item in items) { int i = item.IndexOf(':'); var tname = i != -1 ? item.Substring(0, i) : item; int pause; Type type; AnimationItem aitem = null; if (animationItems.TryGetValue(tname, out type)) { aitem = (AnimationItem)Activator.CreateInstance(type); aitem.Parse(item); } else if (int.TryParse(item, out pause)) { aitem = new PauseItem() { Pause = pause }; } else { // It must be an image var id = ImageService.GetStockId(addin, item, size); var img = ImageService.GetPixbuf(id, size); if (img == null) { continue; } aitem = new ImageItem() { Image = img }; } if (last != null) { last.NextItem = aitem; } aitem.PreviousItem = last; parsedItems.Add(aitem); last = aitem; } if (parsedItems.Count > 0) { // Close the chain parsedItems[0].PreviousItem = parsedItems [parsedItems.Count - 1]; parsedItems [parsedItems.Count - 1].NextItem = parsedItems [0]; } images = new List <Gdk.Pixbuf> (); pauses = new List <int> (); bool lastWasImage = false; foreach (var aitem in parsedItems) { foreach (var frame in aitem.GetFrames()) { if (frame is Gdk.Pixbuf) { if (lastWasImage) { pauses.Add(defaultPause); } images.Add((Gdk.Pixbuf)frame); lastWasImage = true; } else { if (!lastWasImage) { if (pauses.Count > 0) { pauses [pauses.Count - 1] = pauses [pauses.Count - 1] + (int)frame; } else { // Pause before any image. Add a dummy image images.Add(ImageService.GetPixbuf("md-empty")); pauses.Add((int)frame); } } else { pauses.Add((int)frame); } lastWasImage = false; } } } if (pauses.Count < images.Count) { pauses.Add(defaultPause); } }
public static void SetAnimationData(string name, int width, int height, int framePerLine, int numberOfFrame) { AnimationItem item; if (!Animations.ContainsKey(name)) { item = new AnimationItem(SpriteBank.Game); item.AssetName = name; Animations.Add(name, item); } else item = Animations[name]; item.FrameWidth = width; item.FrameHeight = height; item.FramePerLine = framePerLine; item.NumberOfFrames = numberOfFrame; }
public static void SaveUnlock(ICLIFlags flags, Unlock unlock, string path, string eventKey, Dictionary <string, ParsedArg> config, Dictionary <string, TagExpectedValue> tags, VoiceSet voiceSet, STUHero hero) { string rarity; if (tags != null) { if (unlock.STU.m_0B1BA7C1 == null) { rarity = unlock.Rarity.ToString(); tags["leagueTeam"] = new TagExpectedValue("none"); } else { TeamDefinition teamDef = new TeamDefinition(unlock.STU.m_0B1BA7C1); tags["leagueTeam"] = new TagExpectedValue(teamDef.Abbreviation, // NY teamDef.Location, // New York teamDef.Name, // Excelsior teamDef.FullName, // New York Excelsior "*"); // all // nice file structure rarity = ""; eventKey = "League"; } tags["rarity"] = new TagExpectedValue(unlock.Rarity.ToString()); //if (UnlockData.SummerGames2016.Contains(unlock.GUID)) { // tags["special"] = new TagExpectedValue("sg2016"); //} if (UnlockData.SummerGames2017.Contains(unlock.GUID)) { // tags["special"] = new TagExpectedValue("sg2017"); //} else if (UnlockData.SummerGames2018.Contains(unlock.GUID)) { tags["special"] = new TagExpectedValue("sg2018"); } else { tags["special"] = new TagExpectedValue("none"); } } else { rarity = ""; // for general unlocks } string thisPath = Path.Combine(path, unlock.Type, eventKey, rarity, GetValidFilename(unlock.GetName())); if (ShouldDo(unlock, config, tags, typeof(STUUnlock_SprayPaint))) { SprayAndIcon.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_AvatarPortrait))) { SprayAndIcon.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_POTGAnimation))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_Emote))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_Pose))) { AnimationItem.Save(flags, thisPath, unlock); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_VoiceLine))) { VoiceLine.Save(flags, thisPath, unlock, voiceSet); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_SkinTheme))) { SkinTheme.Save(flags, thisPath, unlock, hero); } if (ShouldDo(unlock, config, tags, typeof(STUUnlock_PortraitFrame))) { thisPath = Path.Combine(path, unlock.Type); PortraitFrame.Save(flags, thisPath, unlock); } }
internal void OnClone( AnimationItem source ) { scrollSpeed = source.scrollSpeed; scrollRound = source.scrollRound; rotateSpeed = source.rotateSpeed; }
public void HandleMovement() { if (movementPercentageElapsed >= 1) // If no animation is playing { foreach (GameObject member in party) { if (transform.tag == "Player" && member.GetComponent <PartyMovement>().isMoving) // Waits for all animations to end { return; } } if (animationQueue.Count == 0 && userInputQueue.Count == 0) { CheckHoldInput(); } if (animationQueue.Count == 0 && userInputQueue.Count != 0) // If there is no animation and an input Validates the input, it's up here so it starts in the same frame it validates { ValidateInput(userInputQueue.Dequeue()); } if (animationQueue.Count != 0) // If there is an animation queued { currentAnimation = animationQueue.Dequeue(); changeState(currentAnimation); updateDirection(currentAnimation.GetVector()); if (currentAnimation.SavePosition()) // if it's supposed to save its position, used for the next in party { SavePosition(); } if (currentAnimation.TriggerParty()) // Triggers next in party to start animation with new saved animations { TriggerNextInParty(currentAnimation.getPartySwap()); } movementPercentageElapsed = 0; isMoving = true; } } if (movementPercentageElapsed < 1) // Handles the actual animation frame by frame { float delta = Time.deltaTime * currentAnimation.GetSpeed(); float deltaPercentage = delta / currentAnimation.GetVector().magnitude; if (movementPercentageElapsed + deltaPercentage > 1) { deltaPercentage = (1 - movementPercentageElapsed); } transform.Translate(currentAnimation.GetVector() * deltaPercentage, Space.World); movementPercentageElapsed += deltaPercentage; if (movementPercentageElapsed == 1 && animationQueue.Count == 0 && userInputQueue.Count == 0) // if there is no more animations and it's the end toggles isMoving, saves a frame { isMoving = false; state = State.still; CheckIfDitched(); // At the end of an animation checks to see if party members were ditched } } }
public bool IsAnimationPlaying(string name) { AnimationItem item = this._animMap[name]; return(item.isPlaying); }