예제 #1
0
파일: xaOps.cs 프로젝트: hejob/SB3Utility
 public static xaAnimationTrack animationGetOriginalKeyframes(Dictionary<string, xaAnimationTrack> animationNodeDic, string trackName, List<xaAnimationTrack> animationNodeList)
 {
     xaAnimationTrack animationNode;
     if (!animationNodeDic.TryGetValue(trackName, out animationNode))
     {
         animationNode = new xaAnimationTrack();
         animationNodeList.Add(animationNode);
         animationNode.Name = trackName;
         CreateUnknowns(animationNode);
     }
     return animationNode;
 }
예제 #2
0
파일: xaOps.cs 프로젝트: hejob/SB3Utility
 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;
 }
예제 #3
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;
 }
예제 #4
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;
 }
예제 #5
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;
 }
예제 #6
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;
 }
예제 #7
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;
 }
예제 #8
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;
            }
        }
예제 #9
0
 public void RemoveKeyframe(xaAnimationTrack track, int index)
 {
     for (int i = 0; i < track.KeyframeList.Count; i++)
     {
         if (track.KeyframeList[i].Index == index)
         {
             track.KeyframeList.RemoveAt(i);
             Changed = true;
             return;
         }
     }
 }
예제 #10
0
 public xaAnimationKeyframe NewKeyframe(xaAnimationTrack track, int index)
 {
     for (int i = 0; i < track.KeyframeList.Count; i++)
     {
         if (track.KeyframeList[i].Index == index)
         {
             throw new Exception(track.Name + " already has a keyframe at " + index);
         }
         if (track.KeyframeList[i].Index > index)
         {
             return AddKeyframe(track, index, i);
         }
     }
     return AddKeyframe(track, index, track.KeyframeList.Count);
 }
예제 #11
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;
 }
예제 #12
0
 public static void CreateUnknowns(xaAnimationTrack track)
 {
     track.Unknown1 = new byte[4];
 }
예제 #13
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;
        }
예제 #14
0
파일: FormXA.cs 프로젝트: hejob/SB3Utility
 private void AddTrackToEditedTracks(xaAnimationTrack track)
 {
     if (!comboBoxAnimationEditedTracks.Items.Contains(track.Name))
     {
         comboBoxAnimationEditedTracks.Items.Add(track.Name);
         if (comboBoxAnimationEditedTracks.SelectedIndex == -1)
         {
             comboBoxAnimationEditedTracks.SelectedIndexChanged -= comboBoxAnimationEditedTracks_SelectedIndexChanged;
             comboBoxAnimationEditedTracks.SelectedIndex = 0;
             comboBoxAnimationEditedTracks.SelectedIndexChanged += comboBoxAnimationEditedTracks_SelectedIndexChanged;
         }
     }
 }
예제 #15
0
파일: FormXA.cs 프로젝트: hejob/SB3Utility
 private xaAnimationKeyframe FindAnimationKeyframe(xaAnimationTrack track, int index)
 {
     for (int i = 0; i < track.KeyframeList.Count; i++)
     {
         xaAnimationKeyframe keyframe = track.KeyframeList[i];
         if (keyframe.Index == index)
         {
             return keyframe;
         }
         else if (keyframe.Index > index)
         {
             return i > 0 ? track.KeyframeList[i - 1] : null;
         }
     }
     return track.KeyframeList[track.KeyframeList.Count - 1];
 }