Beispiel #1
0
        public static void animationNormalizeTrack(xaAnimationKeyframe[] origKeyframes, xaAnimationKeyframe[] destKeyframes, int count)
        {
            xaAnimationKeyframe keyframeToCopy;

            if (origKeyframes.Length > 0)
            {
                keyframeToCopy = origKeyframes[origKeyframes.Length - 1];
            }
            else
            {
                keyframeToCopy             = new xaAnimationKeyframe();
                keyframeToCopy.Rotation    = Quaternion.Identity;
                keyframeToCopy.Scaling     = new Vector3(1, 1, 1);
                keyframeToCopy.Translation = new Vector3(0, 0, 0);
                CreateUnknowns(keyframeToCopy);
            }
            for (int j = origKeyframes.Length; j < count; j++)
            {
                xaAnimationKeyframe copy = new xaAnimationKeyframe();
                copy.Index       = j;
                copy.Rotation    = keyframeToCopy.Rotation;
                copy.Scaling     = keyframeToCopy.Scaling;
                copy.Translation = keyframeToCopy.Translation;
                CreateUnknowns(copy);
                destKeyframes[j] = copy;
            }
        }
Beispiel #2
0
        private xaAnimationKeyframe AddKeyframe(xaAnimationTrack track, int index, int i)
        {
            xaAnimationKeyframe keyframe = new xaAnimationKeyframe();

            keyframe.Index = index;
            xa.CreateUnknowns(keyframe);
            if (i < track.KeyframeList.Count)
            {
                if (i > 0)
                {
                    int   predIdx       = track.KeyframeList[i - 1].Index;
                    float indexPosition = (float)(index - predIdx) / (track.KeyframeList[i].Index - predIdx);
                    keyframe.Scaling     = track.KeyframeList[i - 1].Scaling + (track.KeyframeList[i].Scaling - track.KeyframeList[i - 1].Scaling) * indexPosition;
                    keyframe.Rotation    = track.KeyframeList[i - 1].Rotation + (track.KeyframeList[i].Rotation - track.KeyframeList[i - 1].Rotation) * indexPosition;
                    keyframe.Translation = track.KeyframeList[i - 1].Translation + (track.KeyframeList[i].Translation - track.KeyframeList[i - 1].Translation) * indexPosition;
                }
                else
                {
                    keyframe.Scaling     = track.KeyframeList[i].Scaling;
                    keyframe.Rotation    = track.KeyframeList[i].Rotation;
                    keyframe.Translation = track.KeyframeList[i].Translation;
                }
            }
            else
            {
                keyframe.Scaling     = track.KeyframeList[track.KeyframeList.Count - 1].Scaling;
                keyframe.Rotation    = track.KeyframeList[track.KeyframeList.Count - 1].Rotation;
                keyframe.Translation = track.KeyframeList[track.KeyframeList.Count - 1].Translation;
            }
            track.KeyframeList.Insert(i, keyframe);
            Changed = true;
            return(keyframe);
        }
Beispiel #3
0
        public void SetKeyframeScaling(xaAnimationTrack track, int keyframeIdx, object scaling)
        {
            xaAnimationKeyframe keyframe = track.KeyframeList[keyframeIdx];
            Vector3             scale    = new Vector3((float)(double)((object[])scaling)[0], (float)(double)((object[])scaling)[1], (float)(double)((object[])scaling)[2]);

            keyframe.Scaling = scale;
            Changed          = true;
        }
Beispiel #4
0
        public void SetKeyframeTranslation(xaAnimationTrack track, int keyframeIdx, object translation)
        {
            xaAnimationKeyframe keyframe = track.KeyframeList[keyframeIdx];
            Vector3             trans    = new Vector3((float)(double)((object[])translation)[0], (float)(double)((object[])translation)[1], (float)(double)((object[])translation)[2]);

            keyframe.Translation = trans;
            Changed = true;
        }
Beispiel #5
0
 public static void animationCopyKeyframeTransformArray(xaAnimationKeyframe[] src, xaAnimationKeyframe[] dest, int destOffset)
 {
     for (int i = 0; i < src.Length; i++)
     {
         xaAnimationKeyframe keyframe = src[i];
         keyframe.Index      += destOffset;
         dest[keyframe.Index] = keyframe;
     }
 }
Beispiel #6
0
 public static void animationCopyKeyframeTransformArray(xaAnimationKeyframe[] src, int srcIdx, xaAnimationKeyframe[] dest, int destIdx, int count)
 {
     for (int i = 0; i < count; i++)
     {
         xaAnimationKeyframe keyframe = src[srcIdx + i];
         keyframe.Index    = destIdx + i;
         dest[destIdx + i] = keyframe;
     }
 }
Beispiel #7
0
 public static xaAnimationKeyframe[] animationGetOriginalKeyframes(Dictionary <string, xaAnimationTrack> animationNodeDic, string trackName, List <xaAnimationTrack> animationNodeList, out xaAnimationTrack animationNode)
 {
     animationNode = animationGetOriginalKeyframes(animationNodeDic, trackName, animationNodeList);
     xaAnimationKeyframe[] origKeyframes;
     if (animationNode.KeyframeList != null)
     {
         origKeyframes = animationNode.KeyframeList.ToArray();
     }
     else
     {
         origKeyframes = new xaAnimationKeyframe[0];
     }
     return(origKeyframes);
 }
Beispiel #8
0
 public static xaAnimationKeyframe[] animationGetOriginalKeyframes(Dictionary <string, xaAnimationTrack> animationNodeDic, string trackName, List <xaAnimationTrack> animationNodeList, out xaAnimationTrack animationNode)
 {
     xaAnimationKeyframe[] origKeyframes;
     if (animationNodeDic.TryGetValue(trackName, out animationNode))
     {
         origKeyframes = animationNode.KeyframeList.ToArray();
     }
     else
     {
         animationNode = new xaAnimationTrack();
         animationNodeList.Add(animationNode);
         animationNode.Name = trackName;
         CreateUnknowns(animationNode);
         origKeyframes = new xaAnimationKeyframe[0];
     }
     return(origKeyframes);
 }
Beispiel #9
0
        public void SetKeyframeRotation(xaAnimationTrack track, int keyframeIdx, object rotation)
        {
            xaAnimationKeyframe keyframe = track.KeyframeList[keyframeIdx];

            if (((object[])rotation).Length == 3)
            {
                Vector3 rot = new Vector3((float)(double)((object[])rotation)[0], (float)(double)((object[])rotation)[1], (float)(double)((object[])rotation)[2]);
                keyframe.Rotation = FbxUtility.EulerToQuaternion(rot);
            }
            else if (((object[])rotation).Length == 4)
            {
                Quaternion rot = new Quaternion((float)(double)((object[])rotation)[0], (float)(double)((object[])rotation)[1], (float)(double)((object[])rotation)[2], (float)(double)((object[])rotation)[3]);
                keyframe.Rotation = rot;
            }
            else
            {
                throw new Exception("SetKeyframeRotation must be called with three or four arguments");
            }
            Changed = true;
        }
Beispiel #10
0
        public void CopyTrack(string track)
        {
            xaAnimationTrack src = xa.FindTrack(track, Parser);
            xaAnimationTrack cpy = new xaAnimationTrack();

            cpy.Name         = src.Name + "_copy";
            cpy.Unknown1     = (byte[])src.Unknown1.Clone();
            cpy.KeyframeList = new List <xaAnimationKeyframe>(src.KeyframeList.Count);
            foreach (xaAnimationKeyframe srcKeyframe in src.KeyframeList)
            {
                xaAnimationKeyframe cpyKeyframe = new xaAnimationKeyframe();
                cpyKeyframe.Index       = srcKeyframe.Index;
                cpyKeyframe.Rotation    = srcKeyframe.Rotation;
                cpyKeyframe.Unknown1    = (byte[])srcKeyframe.Unknown1.Clone();
                cpyKeyframe.Translation = srcKeyframe.Translation;
                cpyKeyframe.Scaling     = srcKeyframe.Scaling;
                cpy.KeyframeList.Add(cpyKeyframe);
            }
            Parser.AnimationSection.TrackList.Add(cpy);
            Changed = true;
        }
Beispiel #11
0
        protected xaAnimationSection ParseAnimationSection()
        {
            if (reader.ReadByte() == 0)
            {
                return(null);
            }

            xaAnimationSection section = new xaAnimationSection();

            int numClips;

            if (Format == 0x03)
            {
                numClips = 1024;
            }
            else
            {
                numClips = 512;
            }

            section.ClipList = new List <xaAnimationClip>(numClips);
            for (int i = 0; i < numClips; i++)
            {
                xaAnimationClip clip = new xaAnimationClip();
                section.ClipList.Add(clip);

                clip.Name     = reader.ReadName(64);
                clip.Speed    = reader.ReadSingle();
                clip.Unknown1 = reader.ReadBytes(4);
                clip.Start    = reader.ReadSingle();
                clip.End      = reader.ReadSingle();
                clip.Unknown2 = reader.ReadBytes(1);
                clip.Unknown3 = reader.ReadBytes(1);
                clip.Unknown4 = reader.ReadBytes(1);
                clip.Next     = reader.ReadInt32();
                clip.Unknown5 = reader.ReadBytes(1);
                clip.Unknown6 = reader.ReadBytes(4);
                clip.Unknown7 = reader.ReadBytes(16);
            }

            int numTracks = reader.ReadInt32();

            section.TrackList = new List <xaAnimationTrack>(numTracks);
            for (int i = 0; i < numTracks; i++)
            {
                xaAnimationTrack track = new xaAnimationTrack();
                section.TrackList.Add(track);

                track.Name = reader.ReadName();
                int numKeyframes = reader.ReadInt32();
                track.Unknown1 = reader.ReadBytes(4);

                track.KeyframeList = new List <xaAnimationKeyframe>(numKeyframes);
                for (int j = 0; j < numKeyframes; j++)
                {
                    xaAnimationKeyframe keyframe = new xaAnimationKeyframe();
                    track.KeyframeList.Add(keyframe);

                    keyframe.Index       = reader.ReadInt32();
                    keyframe.Rotation    = reader.ReadQuaternion();
                    keyframe.Unknown1    = reader.ReadBytes(8);
                    keyframe.Translation = reader.ReadVector3();
                    keyframe.Scaling     = reader.ReadVector3();
                }
            }

            return(section);
        }
Beispiel #12
0
        public static void ReplaceAnimation(WorkspaceAnimation wsAnimation, xaParser parser, int resampleCount, ReplaceAnimationMethod replaceMethod, int insertPos)
        {
            if (parser.AnimationSection == null)
            {
                Report.ReportLog("The .xa file doesn't have an animation section. Skipping this animation");
                return;
            }
            if (!(wsAnimation.importedAnimation is ImportedKeyframedAnimation))
            {
                Report.ReportLog("The animation has incompatible keyframes.");
                return;
            }

            Report.ReportLog("Replacing animation ...");
            List <ImportedAnimationKeyframedTrack> trackList = ((ImportedKeyframedAnimation)wsAnimation.importedAnimation).TrackList;
            List <KeyValuePair <string, xaAnimationKeyframe[]> >          newTrackList      = new List <KeyValuePair <string, xaAnimationKeyframe[]> >(trackList.Count);
            List <Tuple <ImportedAnimationTrack, xaAnimationKeyframe[]> > interpolateTracks = new List <Tuple <ImportedAnimationTrack, xaAnimationKeyframe[]> >();

            foreach (var wsTrack in trackList)
            {
                if (!wsAnimation.isTrackEnabled(wsTrack))
                {
                    continue;
                }
                ImportedAnimationKeyframe[] keyframes    = ((ImportedAnimationKeyframedTrack)wsTrack).Keyframes;
                xaAnimationKeyframe[]       newKeyframes = null;
                int wsTrackKeyframesLength = 0;
                for (int i = 0; i < keyframes.Length; i++)
                {
                    if (keyframes[i] != null)
                    {
                        wsTrackKeyframesLength++;
                    }
                }
                if (resampleCount < 0 || wsTrackKeyframesLength == resampleCount)
                {
                    newKeyframes = new xaAnimationKeyframe[wsTrackKeyframesLength];
                    int keyframeIdx = 0;
                    for (int i = 0; i < keyframes.Length; i++)
                    {
                        ImportedAnimationKeyframe keyframe = keyframes[i];
                        if (keyframe == null)
                        {
                            continue;
                        }

                        newKeyframes[keyframeIdx]          = new xaAnimationKeyframe();
                        newKeyframes[keyframeIdx].Index    = i;
                        newKeyframes[keyframeIdx].Rotation = keyframe.Rotation;
                        xa.CreateUnknowns(newKeyframes[keyframeIdx]);
                        newKeyframes[keyframeIdx].Translation = keyframe.Translation;
                        newKeyframes[keyframeIdx].Scaling     = keyframe.Scaling;
                        keyframeIdx++;
                    }
                }
                else
                {
                    newKeyframes = new xaAnimationKeyframe[resampleCount];
                    if (wsTrackKeyframesLength < 1)
                    {
                        xaAnimationKeyframe keyframe = new xaAnimationKeyframe();
                        keyframe.Rotation    = Quaternion.Identity;
                        keyframe.Scaling     = new Vector3(1, 1, 1);
                        keyframe.Translation = new Vector3(0, 0, 0);
                        xa.CreateUnknowns(keyframe);

                        for (int i = 0; i < newKeyframes.Length; i++)
                        {
                            keyframe.Index  = i;
                            newKeyframes[i] = keyframe;
                        }
                    }
                    else
                    {
                        interpolateTracks.Add(new Tuple <ImportedAnimationTrack, xaAnimationKeyframe[]>(wsTrack, newKeyframes));
                    }
                }

                newTrackList.Add(new KeyValuePair <string, xaAnimationKeyframe[]>(wsTrack.Name, newKeyframes));
            }
            if (interpolateTracks.Count > 0)
            {
                Fbx.InterpolateKeyframes(interpolateTracks, resampleCount);
            }

            List <xaAnimationTrack> animationNodeList = parser.AnimationSection.TrackList;
            Dictionary <string, xaAnimationTrack> animationNodeDic = null;

            if (replaceMethod != ReplaceAnimationMethod.Replace)
            {
                animationNodeDic = new Dictionary <string, xaAnimationTrack>();
                foreach (xaAnimationTrack animationNode in animationNodeList)
                {
                    animationNodeDic.Add(animationNode.Name, animationNode);
                }
            }

            if (replaceMethod == ReplaceAnimationMethod.Replace)
            {
                animationNodeList.Clear();
                foreach (var newTrack in newTrackList)
                {
                    xaAnimationTrack animationNode = new xaAnimationTrack();
                    animationNodeList.Add(animationNode);
                    animationNode.KeyframeList = new List <xaAnimationKeyframe>(newTrack.Value);
                    animationNode.Name         = newTrack.Key;
                    xa.CreateUnknowns(animationNode);
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.ReplacePresent)
            {
                foreach (var newTrack in newTrackList)
                {
                    xaAnimationTrack animationNode = xa.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, animationNodeList);
                    animationNode.KeyframeList = new List <xaAnimationKeyframe>(newTrack.Value);
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Merge)
            {
                foreach (var newTrack in newTrackList)
                {
                    xaAnimationTrack      animationNode;
                    xaAnimationKeyframe[] origKeyframes = xa.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, animationNodeList, out animationNode);
                    xaAnimationKeyframe[] destKeyframes;
                    int newEnd = insertPos + newTrack.Value.Length;
                    if (origKeyframes.Length < insertPos)
                    {
                        destKeyframes = new xaAnimationKeyframe[newEnd];
                        xa.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, origKeyframes.Length);
                        xa.animationNormalizeTrack(origKeyframes, destKeyframes, insertPos);
                    }
                    else
                    {
                        if (origKeyframes.Length < newEnd)
                        {
                            destKeyframes = new xaAnimationKeyframe[newEnd];
                        }
                        else
                        {
                            destKeyframes = new xaAnimationKeyframe[origKeyframes.Length];
                            xa.animationCopyKeyframeTransformArray(origKeyframes, newEnd, destKeyframes, newEnd, origKeyframes.Length - newEnd);
                        }
                        xa.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, insertPos);
                    }

                    xa.animationCopyKeyframeTransformArray(newTrack.Value, 0, destKeyframes, insertPos, newTrack.Value.Length);
                    animationNode.KeyframeList = new List <xaAnimationKeyframe>(destKeyframes);
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Insert)
            {
                foreach (var newTrack in newTrackList)
                {
                    xaAnimationTrack      animationNode;
                    xaAnimationKeyframe[] origKeyframes = xa.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, animationNodeList, out animationNode);;
                    xaAnimationKeyframe[] destKeyframes;
                    int newEnd = insertPos + newTrack.Value.Length;
                    if (origKeyframes.Length < insertPos)
                    {
                        destKeyframes = new xaAnimationKeyframe[newEnd];
                        xa.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, origKeyframes.Length);
                        xa.animationNormalizeTrack(origKeyframes, destKeyframes, insertPos);
                    }
                    else
                    {
                        destKeyframes = new xaAnimationKeyframe[origKeyframes.Length + newTrack.Value.Length];
                        xa.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, insertPos);
                        xa.animationCopyKeyframeTransformArray(origKeyframes, insertPos, destKeyframes, newEnd, origKeyframes.Length - insertPos);
                    }

                    xa.animationCopyKeyframeTransformArray(newTrack.Value, 0, destKeyframes, insertPos, newTrack.Value.Length);
                    animationNode.KeyframeList = new List <xaAnimationKeyframe>(destKeyframes);
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Append)
            {
                int maxKeyframes = 0;
                foreach (xaAnimationTrack animationNode in animationNodeList)
                {
                    int numKeyframes = animationNode.KeyframeList[animationNode.KeyframeList.Count - 1].Index;
                    if (numKeyframes > maxKeyframes)
                    {
                        maxKeyframes = numKeyframes;
                    }
                }

                foreach (var newTrack in newTrackList)
                {
                    xaAnimationTrack      animationNode;
                    xaAnimationKeyframe[] origKeyframes = xa.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, animationNodeList, out animationNode);
                    xaAnimationKeyframe[] destKeyframes = new xaAnimationKeyframe[maxKeyframes + insertPos + newTrack.Value[newTrack.Value.Length - 1].Index + 1];
                    xa.animationCopyKeyframeTransformArray(origKeyframes, destKeyframes, 0);
                    if (origKeyframes.Length > 0 && origKeyframes.Length == origKeyframes[origKeyframes.Length - 1].Index + 1)
                    {
                        xa.animationNormalizeTrack(origKeyframes, destKeyframes, origKeyframes.Length + insertPos);
                    }
                    xa.animationCopyKeyframeTransformArray(newTrack.Value, destKeyframes, maxKeyframes + insertPos);
                    animationNode.KeyframeList = new List <xaAnimationKeyframe>(origKeyframes.Length + insertPos + newTrack.Value.Length);
                    for (int i = 0; i < destKeyframes.Length; i++)
                    {
                        if (destKeyframes[i] == null)
                        {
                            continue;
                        }

                        animationNode.KeyframeList.Add(destKeyframes[i]);
                    }
                }
            }
            else
            {
                Report.ReportLog("Error: Unexpected animation replace method " + replaceMethod + ". Skipping this animation");
                return;
            }
        }
Beispiel #13
0
 public static void CreateUnknowns(xaAnimationKeyframe keyframe)
 {
     keyframe.Unknown1 = new byte[8];
 }