Exemplo n.º 1
0
 public static void animationCopyKeyframeTransformArray(ImportedAnimationKeyframe[] src, int srcIdx, ImportedAnimationKeyframe[] dest, int destIdx, int count)
 {
     for (int i = 0; i < count; i++)
     {
         ImportedAnimationKeyframe keyframe = src[srcIdx + i];
         dest[destIdx + i] = keyframe;
     }
 }
Exemplo n.º 2
0
        public static List <KeyValuePair <string, ImportedAnimationKeyframe[]> > CopyAnimation(WorkspaceAnimation wsAnimation, int resampleCount, bool linear)
        {
            List <KeyValuePair <string, ImportedAnimationKeyframe[]> >          newTrackList      = new List <KeyValuePair <string, ImportedAnimationKeyframe[]> >(wsAnimation.TrackList.Count);
            List <Tuple <ImportedAnimationTrack, ImportedAnimationKeyframe[]> > interpolateTracks = new List <Tuple <ImportedAnimationTrack, ImportedAnimationKeyframe[]> >();

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

                        newKeyframes[i]             = new ImportedAnimationKeyframe();
                        newKeyframes[i].Rotation    = keyframe.Rotation;
                        newKeyframes[i].Translation = keyframe.Translation;
                        newKeyframes[i].Scaling     = keyframe.Scaling;
                    }
                }
                else
                {
                    newKeyframes = new ImportedAnimationKeyframe[resampleCount];
                    if (wsTrack.Keyframes.Length < 1)
                    {
                        ImportedAnimationKeyframe keyframe = new ImportedAnimationKeyframe();
                        keyframe.Rotation    = Quaternion.Identity;
                        keyframe.Scaling     = new Vector3(1, 1, 1);
                        keyframe.Translation = new Vector3(0, 0, 0);

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

                newTrackList.Add(new KeyValuePair <string, ImportedAnimationKeyframe[]>(wsTrack.Name, newKeyframes));
            }
            if (resampleCount >= 0)
            {
                Fbx.InterpolateKeyframes(interpolateTracks, resampleCount, linear);
            }
            return(newTrackList);
        }
Exemplo n.º 3
0
 public static ImportedAnimationKeyframe[] animationGetOriginalKeyframes(Dictionary <string, ImportedAnimationTrack> animationNodeDic, string trackName, ImportedAnimation anim, out ImportedAnimationTrack animationNode)
 {
     ImportedAnimationKeyframe[] origKeyframes;
     if (animationNodeDic.TryGetValue(trackName, out animationNode))
     {
         origKeyframes = animationNode.Keyframes;
     }
     else
     {
         animationNode = new ImportedAnimationTrack();
         anim.TrackList.Add(animationNode);
         animationNode.Name = trackName;
         origKeyframes      = new ImportedAnimationKeyframe[0];
     }
     return(origKeyframes);
 }
Exemplo n.º 4
0
        public static void animationNormalizeTrack(ImportedAnimationKeyframe[] origKeyframes, ImportedAnimationKeyframe[] destKeyframes, int count)
        {
            ImportedAnimationKeyframe keyframeCopy;

            if (origKeyframes.Length > 0)
            {
                keyframeCopy = origKeyframes[origKeyframes.Length - 1];
            }
            else
            {
                keyframeCopy             = new ImportedAnimationKeyframe();
                keyframeCopy.Rotation    = Quaternion.Identity;
                keyframeCopy.Scaling     = new Vector3(1, 1, 1);
                keyframeCopy.Translation = new Vector3(0, 0, 0);
            }
            for (int j = origKeyframes.Length; j < count; j++)
            {
                destKeyframes[j] = keyframeCopy;
            }
        }
Exemplo n.º 5
0
        public static void ReplaceAnimation(ReplaceAnimationMethod replaceMethod, int insertPos, List <KeyValuePair <string, ImportedAnimationKeyframe[]> > newTrackList, ImportedAnimation iAnim, Dictionary <string, ImportedAnimationTrack> animationNodeDic, bool negateQuaternionFlips)
        {
            if (replaceMethod == ReplaceAnimationMethod.Replace)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationTrack iTrack = new ImportedAnimationTrack();
                    iAnim.TrackList.Add(iTrack);
                    iTrack.Name      = newTrack.Key;
                    iTrack.Keyframes = newTrack.Value;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Merge)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationTrack      animationNode;
                    ImportedAnimationKeyframe[] origKeyframes = FbxUtility.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationKeyframe[] destKeyframes;
                    int newEnd = insertPos + newTrack.Value.Length;
                    if (origKeyframes.Length < insertPos)
                    {
                        destKeyframes = new ImportedAnimationKeyframe[newEnd];
                        FbxUtility.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, origKeyframes.Length);
                        FbxUtility.animationNormalizeTrack(origKeyframes, destKeyframes, insertPos);
                    }
                    else
                    {
                        if (origKeyframes.Length < newEnd)
                        {
                            destKeyframes = new ImportedAnimationKeyframe[newEnd];
                        }
                        else
                        {
                            destKeyframes = new ImportedAnimationKeyframe[origKeyframes.Length];
                            FbxUtility.animationCopyKeyframeTransformArray(origKeyframes, newEnd, destKeyframes, newEnd, origKeyframes.Length - newEnd);
                        }
                        FbxUtility.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, insertPos);
                    }

                    FbxUtility.animationCopyKeyframeTransformArray(newTrack.Value, 0, destKeyframes, insertPos, newTrack.Value.Length);
                    animationNode.Keyframes = destKeyframes;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Insert)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationTrack      animationNode;
                    ImportedAnimationKeyframe[] origKeyframes = FbxUtility.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationKeyframe[] destKeyframes;
                    int newEnd = insertPos + newTrack.Value.Length;
                    if (origKeyframes.Length < insertPos)
                    {
                        destKeyframes = new ImportedAnimationKeyframe[newEnd];
                        FbxUtility.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, origKeyframes.Length);
                        FbxUtility.animationNormalizeTrack(origKeyframes, destKeyframes, insertPos);
                    }
                    else
                    {
                        destKeyframes = new ImportedAnimationKeyframe[origKeyframes.Length + newTrack.Value.Length];
                        FbxUtility.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, insertPos);
                        FbxUtility.animationCopyKeyframeTransformArray(origKeyframes, insertPos, destKeyframes, newEnd, origKeyframes.Length - insertPos);
                    }

                    FbxUtility.animationCopyKeyframeTransformArray(newTrack.Value, 0, destKeyframes, insertPos, newTrack.Value.Length);
                    animationNode.Keyframes = destKeyframes;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Append)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationTrack      animationNode;
                    ImportedAnimationKeyframe[] origKeyframes = FbxUtility.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationKeyframe[] destKeyframes = new ImportedAnimationKeyframe[origKeyframes.Length + newTrack.Value.Length];
                    FbxUtility.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, origKeyframes.Length);
                    FbxUtility.animationCopyKeyframeTransformArray(newTrack.Value, 0, destKeyframes, origKeyframes.Length, newTrack.Value.Length);
                    animationNode.Keyframes = destKeyframes;
                }
            }
            else
            {
                Report.ReportLog("Error: Unexpected animation replace method " + replaceMethod + ". Skipping this animation");
            }

            if (negateQuaternionFlips)
            {
                foreach (var newTrack in iAnim.TrackList)
                {
                    Quaternion lastQ = Quaternion.Identity;
                    for (int i = 0, lastUsed_keyIndex = -1; i < newTrack.Keyframes.Length; i++)
                    {
                        ImportedAnimationKeyframe iKeyframe = newTrack.Keyframes[i];
                        if (iKeyframe == null)
                        {
                            continue;
                        }

                        Quaternion q = iKeyframe.Rotation;
                        if (lastUsed_keyIndex >= 0)
                        {
                            bool diffX = Math.Sign(lastQ.X) != Math.Sign(q.X);
                            bool diffY = Math.Sign(lastQ.Y) != Math.Sign(q.Y);
                            bool diffZ = Math.Sign(lastQ.Z) != Math.Sign(q.Z);
                            bool diffW = Math.Sign(lastQ.W) != Math.Sign(q.W);
                            if (diffX && diffY && diffZ && diffW)
                            {
                                q.X = -q.X;
                                q.Y = -q.Y;
                                q.Z = -q.Z;
                                q.W = -q.W;

                                iKeyframe.Rotation = q;
                            }
                        }
                        lastQ             = q;
                        lastUsed_keyIndex = i;
                    }
                }
            }
        }
Exemplo n.º 6
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;
            }
        }