AnimationDef FindOrNull(Dictionary <string, AnimationDef> dict, string key) { AnimationDef val = null; dict.TryGetValue(key, out val); return(val); }
private static Dictionary <string, AnimationDef> ReadAnimation(XmlDocument doc) { XmlNodeList animations = doc.SelectNodes("//animation"); Dictionary <string, AnimationDef> animationDefinitions = new Dictionary <string, AnimationDef>(); foreach (XmlNode n in animations) { AnimationDef a = new AnimationDef() { Name = n.Attributes["name"].Value, Sequence = n.Attributes["sequence"].Value.Split(','), }; if (n.Attributes["randomSeqStart"] == null) { a.RandomSeqStart = false; } else { a.RandomSeqStart = n.Attributes["randomSeqStart"].Value.Equals("true", StringComparison.InvariantCultureIgnoreCase); } XmlNodeList frames = n.SelectNodes("frame"); foreach (XmlNode f in frames) { FrameDef fd = new FrameDef() { X = int.Parse(f.Attributes["x"].Value), Y = int.Parse(f.Attributes["y"].Value), Image = f.Attributes["img"].Value, Width = int.Parse(f.Attributes["width"].Value), Height = int.Parse(f.Attributes["height"].Value), Delay = int.Parse(f.Attributes["delay"].Value), }; if (f.Attributes["basex"] == null) { fd.BaseX = 0; } else { fd.BaseX = int.Parse(f.Attributes["basex"].Value); } if (f.Attributes["basey"] == null) { fd.BaseY = 0; } else { fd.BaseY = int.Parse(f.Attributes["basey"].Value); } a.Frames.Add(fd); } animationDefinitions.Add(a.Name, a); } return(animationDefinitions); }
public void AddAnimation(string name, bool looping, Sprite[] sprites) { runtimeAnims[name] = new AnimationDef { name = name, looping = looping, sprites = sprites }; }
void UpdateAnimDict() { if (nameToAnim == null) { return; } nameToAnim.Clear(); for (int i = 0; i < anims.Length; ++i) { AnimationDef anim = anims[i]; nameToAnim[anim.name] = anim; } }
public AnimSet(MpqFile file) { var stream = file.Open(); this.Header = new Header(stream); stream.Position = 352; this.NumberOfAnimations = stream.ReadValueS32(); for (int i = 0; i < this.NumberOfAnimations; i++) { stream.Position += 4; var animation = new AnimationDef { TagID = stream.ReadValueS32(), AnimationSNO = stream.ReadValueS32() }; this.Animations.Add(animation); } stream.Close(); }
RuntimeAnim?GetAnim(string name) { AnimationDef def = nameToAnim.FindOrNull(name); if (def == null) { def = runtimeAnims.FindOrNull(name); } if (def == null) { return(null); } return(new RuntimeAnim { def = def }); }
internal void CreateAnimationSets(AnimationDef animations, WeaponSystem system, out Dictionary <EventTriggers, PartAnimation[]> weaponAnimationSets, out Dictionary <string, EmissiveState> weaponEmissivesSet, out Dictionary <string, Matrix[]> weaponLinearMoveSet, out HashSet <string> animationIdLookup, out Dictionary <EventTriggers, uint> animationLengths, out string[] heatingSubpartNames) { var allAnimationSet = new Dictionary <EventTriggers, HashSet <PartAnimation> >(); weaponAnimationSets = new Dictionary <EventTriggers, PartAnimation[]>(); weaponEmissivesSet = new Dictionary <string, EmissiveState>(); animationIdLookup = new HashSet <string>(); animationLengths = new Dictionary <EventTriggers, uint>(); var wepAnimationSets = animations.WeaponAnimationSets; var wepEmissivesSet = animations.Emissives; weaponLinearMoveSet = new Dictionary <string, Matrix[]>(); var emissiveLookup = new Dictionary <string, WeaponEmissive>(); if (animations.HeatingEmissiveParts != null && animations.HeatingEmissiveParts.Length > 0) { heatingSubpartNames = animations.HeatingEmissiveParts; } else { heatingSubpartNames = new string[0]; } if (wepEmissivesSet != null) { foreach (var emissive in wepEmissivesSet) { emissiveLookup.Add(emissive.EmissiveName, emissive); } } if (wepAnimationSets == null) { return; } foreach (var animationSet in wepAnimationSets) { for (int t = 0; t < animationSet.SubpartId.Length; t++) { foreach (var moves in animationSet.EventMoveSets) { if (!allAnimationSet.ContainsKey(moves.Key)) { allAnimationSet[moves.Key] = new HashSet <PartAnimation>(); animationLengths[moves.Key] = 0; } List <Matrix> moveSet = new List <Matrix>(); List <Matrix> rotationSet = new List <Matrix>(); List <Matrix> rotCenterSet = new List <Matrix>(); List <string> rotCenterNameSet = new List <string>(); List <string> emissiveIdSet = new List <string>(); Guid guid = Guid.NewGuid(); var id = Convert.ToBase64String(guid.ToByteArray()); animationIdLookup.Add(id); AnimationType[] typeSet = new[] { AnimationType.Movement, AnimationType.ShowInstant, AnimationType.HideInstant, AnimationType.ShowFade, AnimationType.HideFade, AnimationType.Delay, AnimationType.EmissiveOnly }; var moveIndexer = new List <int[]>(); var currentEmissivePart = new List <int>(); uint totalPlayLength = animationSet.AnimationDelays[moves.Key]; for (int i = 0; i < moves.Value.Length; i++) { var move = moves.Value[i]; totalPlayLength += move.TicksToMove; var hasEmissive = !string.IsNullOrEmpty(move.EmissiveName); if (move.MovementType == RelMove.MoveType.Delay || move.MovementType == RelMove.MoveType.Show || move.MovementType == RelMove.MoveType.Hide) { moveSet.Add(Matrix.Zero); rotationSet.Add(Matrix.Zero); rotCenterSet.Add(Matrix.Zero); for (var j = 0; j < move.TicksToMove; j++) { var type = 5; switch (move.MovementType) { case RelMove.MoveType.Delay: break; case RelMove.MoveType.Show: type = move.Fade ? 3 : 1; break; case RelMove.MoveType.Hide: type = move.Fade ? 4 : 2; break; } WeaponEmissive emissive; if (hasEmissive && emissiveLookup.TryGetValue(move.EmissiveName, out emissive)) { var progress = 0f; if (move.TicksToMove == 1) { progress = 1; } else { progress = (float)j / (move.TicksToMove - 1); } CreateEmissiveStep(emissive, id + moveIndexer.Count, progress, ref weaponEmissivesSet, ref currentEmissivePart); } else { weaponEmissivesSet[id + moveIndexer.Count] = new EmissiveState(); currentEmissivePart.Add(-1); } emissiveIdSet.Add(id + moveIndexer.Count); moveIndexer.Add(new[] { moveSet.Count - 1, rotationSet.Count - 1, rotCenterSet.Count - 1, type, emissiveIdSet.Count - 1, currentEmissivePart.Count - 1 }); } } else { var type = 6; if (move.LinearPoints != null && move.LinearPoints.Length > 0) { double distance = 0; var tmpDirVec = new double[move.LinearPoints.Length][]; for (int j = 0; j < move.LinearPoints.Length; j++) { var point = move.LinearPoints[j]; var d = Math.Sqrt((point.x * point.x) + (point.y * point.y) + (point.z * point.z)); distance += d; var dv = new[] { d, point.x / d, point.y / d, point.z / d }; tmpDirVec[j] = dv; } if (move.MovementType == RelMove.MoveType.ExpoDecay) { var traveled = 0d; var check = 1d; var rate = 0d; while (check > 0) { rate += 0.001; check = distance * Math.Pow(1 - rate, move.TicksToMove); if (check < 0.001) { check = 0; } } var vectorCount = 0; var remaining = 0d; var vecTotalMoved = 0d; rate = 1 - rate; for (int j = 0; j < move.TicksToMove; j++) { var step = distance * Math.Pow(rate, j + 1); if (step < 0.001) { step = 0; } var lastTraveled = traveled; traveled = distance - step; var changed = traveled - lastTraveled; var progress = 0f; if (move.TicksToMove == 1 || j == move.TicksToMove - 1) { progress = 1; } else { progress = (float)(traveled / distance); } changed += remaining; if (changed > tmpDirVec[vectorCount][0] - vecTotalMoved) { var origMove = changed; changed = changed - (tmpDirVec[vectorCount][0] - vecTotalMoved); remaining = origMove - changed; vecTotalMoved = 0; } else { vecTotalMoved += changed; remaining = 0; } var vector = new Vector3(tmpDirVec[vectorCount][1] * changed, tmpDirVec[vectorCount][2] * changed, tmpDirVec[vectorCount][3] * changed); var matrix = Matrix.CreateTranslation(vector); moveSet.Add(matrix); WeaponEmissive emissive; if (hasEmissive && emissiveLookup.TryGetValue(move.EmissiveName, out emissive)) { CreateEmissiveStep(emissive, id + moveIndexer.Count, progress, ref weaponEmissivesSet, ref currentEmissivePart); } else { weaponEmissivesSet[id + moveIndexer.Count] = new EmissiveState(); currentEmissivePart.Add(-1); } emissiveIdSet.Add(id + moveIndexer.Count); CreateRotationSets(move, progress, ref type, ref rotCenterNameSet, ref rotCenterSet, ref rotationSet); moveIndexer.Add(new[] { moveSet.Count - 1, rotationSet.Count - 1, rotCenterSet.Count - 1, 0, emissiveIdSet.Count - 1, currentEmissivePart.Count - 1 }); if (remaining > 0) { vectorCount++; } } } else if (move.MovementType == RelMove.MoveType.ExpoGrowth) { var traveled = 0d; var rate = 0d; var check = 0d; while (check < distance) { rate += 0.001; check = 0.001 * Math.Pow(1 + rate, move.TicksToMove); } var vectorCount = 0; var remaining = 0d; var vecTotalMoved = 0d; rate += 1; for (int j = 0; j < move.TicksToMove; j++) { var step = 0.001 * Math.Pow(rate, j + 1); if (step > distance) { step = distance; } var lastTraveled = traveled; traveled = step; var changed = traveled - lastTraveled; var progress = 0f; if (move.TicksToMove == 1 || j == move.TicksToMove - 1) { progress = 1; } else { progress = (float)(traveled / distance); } changed += remaining; if (changed > tmpDirVec[vectorCount][0] - vecTotalMoved) { var origMove = changed; changed = changed - (tmpDirVec[vectorCount][0] - vecTotalMoved); remaining = origMove - changed; vecTotalMoved = 0; } else { vecTotalMoved += changed; remaining = 0; } var vector = new Vector3(tmpDirVec[vectorCount][1] * changed, tmpDirVec[vectorCount][2] * changed, tmpDirVec[vectorCount][3] * changed); var matrix = Matrix.CreateTranslation(vector); moveSet.Add(matrix); WeaponEmissive emissive; if (hasEmissive && emissiveLookup.TryGetValue(move.EmissiveName, out emissive)) { CreateEmissiveStep(emissive, id + moveIndexer.Count, progress, ref weaponEmissivesSet, ref currentEmissivePart); } else { weaponEmissivesSet[id + moveIndexer.Count] = new EmissiveState(); currentEmissivePart.Add(-1); } emissiveIdSet.Add(id + moveIndexer.Count); CreateRotationSets(move, progress, ref type, ref rotCenterNameSet, ref rotCenterSet, ref rotationSet); moveIndexer.Add(new[] { moveSet.Count - 1, rotationSet.Count - 1, rotCenterSet.Count - 1, 0, emissiveIdSet.Count - 1, currentEmissivePart.Count - 1 }); if (remaining > 0) { vectorCount++; } } } else if (move.MovementType == RelMove.MoveType.Linear) { var distancePerTick = distance / move.TicksToMove; var vectorCount = 0; var remaining = 0d; var vecTotalMoved = 0d; CreateRotationSets(move, 1, ref type, ref rotCenterNameSet, ref rotCenterSet, ref rotationSet); for (int j = 0; j < move.TicksToMove; j++) { var changed = distancePerTick + remaining; if (changed > tmpDirVec[vectorCount][0] - vecTotalMoved) { var origMove = changed; changed = changed - (tmpDirVec[vectorCount][0] - vecTotalMoved); remaining = origMove - changed; vecTotalMoved = 0; } else { vecTotalMoved += changed; remaining = 0; } var vector = new Vector3(tmpDirVec[vectorCount][1] * changed, tmpDirVec[vectorCount][2] * changed, tmpDirVec[vectorCount][3] * changed); var matrix = Matrix.CreateTranslation(vector); moveSet.Add(matrix); WeaponEmissive emissive; if (hasEmissive && emissiveLookup.TryGetValue(move.EmissiveName, out emissive)) { var progress = 0f; if (move.TicksToMove == 1) { progress = 1; } else { progress = (float)j / (move.TicksToMove - 1); } CreateEmissiveStep(emissive, id + moveIndexer.Count, progress, ref weaponEmissivesSet, ref currentEmissivePart); } else { weaponEmissivesSet[id + moveIndexer.Count] = new EmissiveState(); currentEmissivePart.Add(-1); } emissiveIdSet.Add(id + moveIndexer.Count); moveIndexer.Add(new[] { moveSet.Count - 1, rotationSet.Count - 1, rotCenterSet.Count - 1, 0, emissiveIdSet.Count - 1, currentEmissivePart.Count - 1 }); if (remaining > 0) { vectorCount++; } } } } else { moveSet.Add(Matrix.Zero); var rate = GetRate(move.MovementType, move.TicksToMove); if (move.MovementType == RelMove.MoveType.Linear) { CreateRotationSets(move, 1, ref type, ref rotCenterNameSet, ref rotCenterSet, ref rotationSet); } for (int j = 0; j < move.TicksToMove; j++) { var progress = 0d; if (move.MovementType == RelMove.MoveType.ExpoGrowth) { progress = (0.001 * Math.Pow(rate, j)) / (double)move.TicksToMove; } if (move.MovementType == RelMove.MoveType.ExpoDecay) { var perc = ((double)move.TicksToMove * Math.Pow(rate, j)) / (double)move.TicksToMove; progress = MathHelper.Lerp(1d, 0d, perc); } else { progress = (double)j / (double)(move.TicksToMove - 1); } if (move.TicksToMove == 1 || j == move.TicksToMove - 1) { progress = 1; } WeaponEmissive emissive; if (hasEmissive && emissiveLookup.TryGetValue(move.EmissiveName, out emissive)) { CreateEmissiveStep(emissive, id + moveIndexer.Count, (float)progress, ref weaponEmissivesSet, ref currentEmissivePart); } else { weaponEmissivesSet[id + moveIndexer.Count] = new EmissiveState(); currentEmissivePart.Add(-1); } emissiveIdSet.Add(id + moveIndexer.Count); if (move.MovementType != RelMove.MoveType.Linear) { CreateRotationSets(move, progress, ref type, ref rotCenterNameSet, ref rotCenterSet, ref rotationSet); } //Log.Line($"type: {type}"); moveIndexer.Add(new[] { moveSet.Count - 1, rotationSet.Count - 1, rotCenterSet.Count - 1, type, emissiveIdSet.Count - 1, currentEmissivePart.Count - 1 }); } } } } if (animationLengths[moves.Key] < totalPlayLength) { animationLengths[moves.Key] = totalPlayLength; } var loop = false; var reverse = false; var triggerOnce = false; var resetEmissives = false; if (animationSet.Loop != null && animationSet.Loop.Contains(moves.Key)) { loop = true; } if (animationSet.Reverse != null && animationSet.Reverse.Contains(moves.Key)) { reverse = true; } if (animationSet.TriggerOnce != null && animationSet.TriggerOnce.Contains(moves.Key)) { triggerOnce = true; } if (animationSet.ResetEmissives != null && animationSet.ResetEmissives.Contains(moves.Key)) { resetEmissives = true; } var partAnim = new PartAnimation(moves.Key, id, rotationSet.ToArray(), rotCenterSet.ToArray(), typeSet, emissiveIdSet.ToArray(), currentEmissivePart.ToArray(), moveIndexer.ToArray(), animationSet.SubpartId[t], null, null, animationSet.BarrelId, animationSet.AnimationDelays[moves.Key], system, loop, reverse, triggerOnce, resetEmissives); weaponLinearMoveSet.Add(id, moveSet.ToArray()); partAnim.RotCenterNameSet = rotCenterNameSet.ToArray(); allAnimationSet[moves.Key].Add(partAnim); } } } foreach (var animationsKv in allAnimationSet) { weaponAnimationSets[animationsKv.Key] = new PartAnimation[animationsKv.Value.Count]; animationsKv.Value.CopyTo(weaponAnimationSets[animationsKv.Key], 0); } }