Example #1
0
        private void WriteKeyframeFloats_Float32(IList <EAN_Keyframe> keyframes, bool hasFirstKeyframe, bool hasFinalKeyframe, EAN_Keyframe defaultKeyframe)
        {
            if (!hasFirstKeyframe)
            {
                EAN_Keyframe defaultFirstKeyframe = (keyframes.Count == 0) ? defaultKeyframe : keyframes[0];
                bytes.AddRange(BitConverter.GetBytes(defaultFirstKeyframe.X));
                bytes.AddRange(BitConverter.GetBytes(defaultFirstKeyframe.Y));
                bytes.AddRange(BitConverter.GetBytes(defaultFirstKeyframe.Z));
                bytes.AddRange(BitConverter.GetBytes(defaultFirstKeyframe.W));
            }

            for (int i = 0; i < keyframes.Count; i++)
            {
                bytes.AddRange(BitConverter.GetBytes(keyframes[i].X));
                bytes.AddRange(BitConverter.GetBytes(keyframes[i].Y));
                bytes.AddRange(BitConverter.GetBytes(keyframes[i].Z));
                bytes.AddRange(BitConverter.GetBytes(keyframes[i].W));
            }

            if (!hasFinalKeyframe)
            {
                EAN_Keyframe defaultFinalKeyframe = (keyframes.Count == 0) ? defaultKeyframe : keyframes[keyframes.Count - 1];
                bytes.AddRange(BitConverter.GetBytes(defaultFinalKeyframe.X));
                bytes.AddRange(BitConverter.GetBytes(defaultFinalKeyframe.Y));
                bytes.AddRange(BitConverter.GetBytes(defaultFinalKeyframe.Z));
                bytes.AddRange(BitConverter.GetBytes(defaultFinalKeyframe.W));
            }
        }
Example #2
0
        private void WriteAnimation(EAN_Animation animation, int offsetToReplace)
        {
            StartNewLine();

            if (animation.FrameCount <= 0)
            {
                throw new InvalidDataException("EAN Save: FrameCount cannot be 0 or less!");
            }

            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count()), offsetToReplace);
            int startOffset = bytes.Count();
            int nodeCount   = (animation.Nodes != null) ? animation.Nodes.Count() : 0;

            if (nodeCount > 0)
            {
                nodeCount = 0;
                for (int i = 0; i < animation.Nodes.Count(); i++)
                {
                    if (eanFile.Skeleton.Exists(animation.Nodes[i].BoneName))
                    {
                        nodeCount++;
                    }
                }
            }

            bytes.AddRange(new byte[2]);
            bytes.Add((byte)animation.I_02);
            bytes.Add((byte)animation.I_03);
            bytes.AddRange(BitConverter.GetBytes(animation.FrameCount));
            bytes.AddRange(BitConverter.GetBytes(nodeCount));
            bytes.AddRange(new byte[4]);

            //Nodes
            if (nodeCount > 0)
            {
                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count - startOffset), startOffset + 12);
                List <int> NodeTable = new List <int>();
                for (int i = 0; i < nodeCount; i++)
                {
                    NodeTable.Add(bytes.Count);
                    bytes.AddRange(new byte[4]);
                }

                for (int i = 0; i < nodeCount; i++)
                {
                    if (eanFile.Skeleton.Exists(animation.Nodes[i].BoneName))
                    {
                        bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count - startOffset), NodeTable[i]);
                        int        NodeOffset = bytes.Count;
                        List <int> AnimationComponentTable = new List <int>();

                        int AnimationComponentCount = (animation.Nodes[i].AnimationComponents != null) ? animation.Nodes[i].AnimationComponents.Count : 0;
                        bytes.AddRange(BitConverter.GetBytes(GetBoneIndex(animation.Nodes[i].BoneName, animation.Name)));
                        bytes.AddRange(BitConverter.GetBytes((short)AnimationComponentCount));
                        bytes.AddRange(BitConverter.GetBytes(8));

                        //Get ESK data for this bone as it will be needed for calculating default keyframes
                        ESK_RelativeTransform eskRelativeTransform = eanFile.Skeleton.GetBone(animation.Nodes[i].BoneName)?.RelativeTransform;

                        if (eskRelativeTransform == null)
                        {
                            throw new ArgumentNullException($"EAN Save: Could not find the RelativeTransform for bone {animation.Nodes[i].BoneName}");
                        }

                        //Table
                        for (int a = 0; a < AnimationComponentCount; a++)
                        {
                            AnimationComponentTable.Add(bytes.Count());
                            bytes.AddRange(new byte[4]);
                        }

                        //Data
                        for (int a = 0; a < AnimationComponentCount; a++)
                        {
                            bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count - NodeOffset), AnimationComponentTable[a]);

                            int KeyframeOffset = bytes.Count;

                            //Can happen if loaded from XML and no keyframes were declared.
                            if (animation.Nodes[i].AnimationComponents[a].Keyframes == null)
                            {
                                animation.Nodes[i].AnimationComponents[a].Keyframes = AsyncObservableCollection <EAN_Keyframe> .Create();
                            }

                            //Handle first and last keyframe
                            bool hasFirstKeyframe = animation.Nodes[i].AnimationComponents[a].Keyframes.Any(x => x.FrameIndex == 0);
                            bool hasFinalKeyframe = animation.Nodes[i].AnimationComponents[a].Keyframes.Any(x => x.FrameIndex == animation.FrameCount - 1);
                            int  KeyframeCount    = animation.Nodes[i].AnimationComponents[a].Keyframes.Count;

                            //If no first or final keyframes were found, increment count to include them
                            if (!hasFinalKeyframe)
                            {
                                KeyframeCount++;
                            }
                            if (!hasFirstKeyframe)
                            {
                                KeyframeCount++;
                            }

                            //Select default keyframe
                            EAN_Keyframe defaultKeyframe = null;

                            switch (animation.Nodes[i].AnimationComponents[a].I_00)
                            {
                            case EAN_AnimationComponent.ComponentType.Position:
                                defaultKeyframe = eskRelativeTransform.ToEanPosKeyframe();
                                break;

                            case EAN_AnimationComponent.ComponentType.Rotation:
                                defaultKeyframe = eskRelativeTransform.ToEanRotKeyframe();
                                break;

                            case EAN_AnimationComponent.ComponentType.Scale:
                                defaultKeyframe = eskRelativeTransform.ToEanScaleKeyframe();
                                break;
                            }

                            //Write
                            bytes.Add((byte)animation.Nodes[i].AnimationComponents[a].I_00);
                            bytes.Add(animation.Nodes[i].AnimationComponents[a].I_01);
                            bytes.AddRange(BitConverter.GetBytes(animation.Nodes[i].AnimationComponents[a].I_02));
                            bytes.AddRange(BitConverter.GetBytes(KeyframeCount));
                            bytes.AddRange(new byte[8]);

                            //Validate
                            if (animation.Nodes[i].AnimationComponents[a].Keyframes.Any(x => x.FrameIndex > (animation.FrameCount - 1)))
                            {
                                throw new Exception($"EAN Save: Keyframe FrameIndex must not exceed the animation duration. (Name: {animation.Name}, ID: {animation.ID_UShort}");
                            }

                            //Write Keyframes
                            if (KeyframeCount > 0)
                            {
                                Sorting.SortEntries2(animation.Nodes[i].AnimationComponents[a].Keyframes);

                                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count - KeyframeOffset), KeyframeOffset + 8);
                                switch (animation.I_02)
                                {
                                case EAN_Animation.IntPrecision._8Bit:
                                    WriteKeyframeIndex_Int8(animation.Nodes[i].AnimationComponents[a].Keyframes, hasFirstKeyframe, hasFinalKeyframe, animation.FrameCount - 1);
                                    break;

                                case EAN_Animation.IntPrecision._16Bit:
                                    WriteKeyframeIndex_Int16(animation.Nodes[i].AnimationComponents[a].Keyframes, hasFirstKeyframe, hasFinalKeyframe, animation.FrameCount - 1);
                                    break;
                                }

                                StartNewLine();
                                bytes = Utils.ReplaceRange(bytes, BitConverter.GetBytes(bytes.Count - KeyframeOffset), KeyframeOffset + 12);
                                switch (animation.I_03)
                                {
                                case EAN_Animation.FloatPrecision._16Bit:
                                    WriteKeyframeFloats_Float16(animation.Nodes[i].AnimationComponents[a].Keyframes, hasFirstKeyframe, hasFinalKeyframe, defaultKeyframe);
                                    break;

                                case EAN_Animation.FloatPrecision._32Bit:
                                    WriteKeyframeFloats_Float32(animation.Nodes[i].AnimationComponents[a].Keyframes, hasFirstKeyframe, hasFinalKeyframe, defaultKeyframe);
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            bytes.AddRange(new byte[12]);
        }