Пример #1
0
        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);
            }
        }
Пример #3
0
 public Spiral(Color Colour, float Size = 1, PartAnimation a = null) : base(Colour, Size, a)
 {
     this.spawnfreq = 0;
 }