public void PlayEmissives(PartAnimation animation) { EmissiveState LastEmissive = new EmissiveState(); for (int i = 0; i < animation.MoveToSetIndexer.Length; i++) { EmissiveState currentEmissive; if (System.WeaponEmissiveSet.TryGetValue(animation.EmissiveIds[animation.MoveToSetIndexer[i][(int)Indexer.EmissiveIndex]], out currentEmissive)) { currentEmissive.CurrentPart = animation.CurrentEmissivePart[animation.MoveToSetIndexer[i][(int)Indexer.EmissivePartIndex]]; if (currentEmissive.EmissiveParts != null && LastEmissive.EmissiveParts != null && currentEmissive.CurrentPart == LastEmissive.CurrentPart && currentEmissive.CurrentColor == LastEmissive.CurrentColor && Math.Abs(currentEmissive.CurrentIntensity - LastEmissive.CurrentIntensity) < 0.001) { currentEmissive = new EmissiveState(); } LastEmissive = currentEmissive; if (currentEmissive.EmissiveParts != null && currentEmissive.EmissiveParts.Length > 0) { if (currentEmissive.CycleParts) { animation.Part.SetEmissiveParts(currentEmissive.EmissiveParts[currentEmissive.CurrentPart], currentEmissive.CurrentColor, currentEmissive.CurrentIntensity); if (!currentEmissive.LeavePreviousOn) { var prev = currentEmissive.CurrentPart - 1 >= 0 ? currentEmissive.CurrentPart - 1 : currentEmissive.EmissiveParts .Length - 1; animation.Part.SetEmissiveParts(currentEmissive.EmissiveParts[prev], Color.Transparent, 0); } } else { for (int j = 0; j < currentEmissive.EmissiveParts.Length; j++) { animation.Part.SetEmissiveParts(currentEmissive.EmissiveParts[j], currentEmissive.CurrentColor, currentEmissive.CurrentIntensity); } } } } } }
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); } }
public Spiral(Color Colour, float Size = 1, PartAnimation a = null) : base(Colour, Size, a) { this.spawnfreq = 0; }