Пример #1
0
Файл: Fbx.cs Проект: kkdevs/sb3u
        public static void animationNormalizeTrack(ImportedAnimationSampledTrack origSamples, ImportedAnimationSampledTrack destSamples, int count)
        {
            Vector3?   scaleKeyCopy;
            Quaternion?rotateKeyCopy;
            Vector3?   translateKeyCopy;
            float?     morphKeyCopy;

            if (origSamples.Scalings.Length > 0)
            {
                scaleKeyCopy     = origSamples.Scalings[origSamples.Scalings.Length - 1];
                rotateKeyCopy    = origSamples.Rotations[origSamples.Rotations.Length - 1];
                translateKeyCopy = origSamples.Translations[origSamples.Translations.Length - 1];
                morphKeyCopy     = origSamples.Curve[origSamples.Curve.Length - 1];
            }
            else
            {
                scaleKeyCopy     = new Vector3(1, 1, 1);
                rotateKeyCopy    = Quaternion.Identity;
                translateKeyCopy = new Vector3(0, 0, 0);
                morphKeyCopy     = 0;
            }
            for (int j = origSamples.Scalings.Length; j < count; j++)
            {
                destSamples.Scalings[j]     = scaleKeyCopy;
                destSamples.Rotations[j]    = rotateKeyCopy;
                destSamples.Translations[j] = translateKeyCopy;
                destSamples.Curve[j]        = morphKeyCopy;
            }
        }
Пример #2
0
Файл: Fbx.cs Проект: kkdevs/sb3u
        public static ImportedAnimationSampledTrack animationGetOriginalSamples(Dictionary <string, ImportedAnimationSampledTrack> animationNodeDic, string trackName, List <ImportedAnimationSampledTrack> animationNodeList)
        {
            ImportedAnimationSampledTrack animationNode;

            if (!animationNodeDic.TryGetValue(trackName, out animationNode))
            {
                animationNode = new ImportedAnimationSampledTrack();
                animationNodeList.Add(animationNode);
                animationNode.Name = trackName;
            }
            return(animationNode);
        }
Пример #3
0
 public static void animationCopySampleTransformArray(ImportedAnimationSampledTrack src, int srcIdx, ImportedAnimationSampledTrack dest, int destIdx, int count)
 {
     for (int i = 0; i < count; i++)
     {
         Vector3?scaleKey = src.Scalings[srcIdx + i];
         dest.Scalings[destIdx + i] = scaleKey;
         Quaternion?rotateKey = src.Rotations[srcIdx + i];
         dest.Rotations[destIdx + i] = rotateKey;
         Vector3?translateKey = src.Translations[srcIdx + i];
         dest.Translations[destIdx + i] = translateKey;
     }
 }
Пример #4
0
        public static ImportedAnimationSampledTrack animationGetOriginalSamples(Dictionary <string, ImportedAnimationSampledTrack> animationNodeDic, string trackName, ImportedSampledAnimation anim, out ImportedAnimationSampledTrack animationNode)
        {
            animationNode = animationGetOriginalSamples(animationNodeDic, trackName, anim.TrackList);
            ImportedAnimationSampledTrack origKeyframes;

            if (animationNode.Scalings != null)
            {
                origKeyframes = animationNode;
            }
            else
            {
                origKeyframes              = new ImportedAnimationSampledTrack();
                origKeyframes.Scalings     = new Vector3?[0];
                origKeyframes.Rotations    = new Quaternion?[0];
                origKeyframes.Translations = new Vector3?[0];
            }
            return(origKeyframes);
        }
Пример #5
0
 public static void animationCopySampleTransformArray(ImportedAnimationSampledTrack src, ImportedAnimationSampledTrack dest, int destOffset)
 {
     for (int i = 0; i < src.Scalings.Length; i++)
     {
         Vector3?scaleKey = src.Scalings[i];
         dest.Scalings[i + destOffset] = scaleKey;
     }
     for (int i = 0; i < src.Rotations.Length; i++)
     {
         Quaternion?rotateKey = src.Rotations[i];
         dest.Rotations[i + destOffset] = rotateKey;
     }
     for (int i = 0; i < src.Translations.Length; i++)
     {
         Vector3?translateKey = src.Translations[i];
         dest.Translations[i + destOffset] = translateKey;
     }
 }
Пример #6
0
 private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
 {
     if (e.Node.Tag is ImportedSubmesh)
     {
         TreeNode        submeshNode = e.Node;
         ImportedSubmesh submesh     = (ImportedSubmesh)submeshNode.Tag;
         TreeNode        meshNode    = submeshNode.Parent;
         DragSource      dragSrc     = (DragSource)meshNode.Tag;
         var             srcEditor   = (ImportedEditor)Gui.Scripting.Variables[dragSrc.Variable];
         srcEditor.Meshes[(int)dragSrc.Id].setSubmeshEnabled(submesh, submeshNode.Checked);
     }
     else if (e.Node.Tag is ImportedMorphKeyframe)
     {
         TreeNode keyframeNode          = e.Node;
         ImportedMorphKeyframe keyframe = (ImportedMorphKeyframe)keyframeNode.Tag;
         TreeNode   morphNode           = keyframeNode.Parent;
         DragSource dragSrc             = (DragSource)morphNode.Tag;
         var        srcEditor           = (ImportedEditor)Gui.Scripting.Variables[dragSrc.Variable];
         srcEditor.Morphs[(int)dragSrc.Id].setMorphKeyframeEnabled(keyframe, keyframeNode.Checked);
     }
     else if (e.Node.Tag is ImportedAnimationKeyframedTrack)
     {
         TreeNode trackNode = e.Node;
         ImportedAnimationKeyframedTrack track = (ImportedAnimationKeyframedTrack)trackNode.Tag;
         TreeNode   animationNode = trackNode.Parent;
         DragSource dragSrc       = (DragSource)animationNode.Tag;
         var        srcEditor     = (ImportedEditor)Gui.Scripting.Variables[dragSrc.Variable];
         srcEditor.Animations[(int)dragSrc.Id].setTrackEnabled(track, trackNode.Checked);
     }
     else if (e.Node.Tag is ImportedAnimationSampledTrack)
     {
         TreeNode trackNode = e.Node;
         ImportedAnimationSampledTrack track = (ImportedAnimationSampledTrack)trackNode.Tag;
         TreeNode   animationNode            = trackNode.Parent;
         DragSource dragSrc   = (DragSource)animationNode.Tag;
         var        srcEditor = (ImportedEditor)Gui.Scripting.Variables[dragSrc.Variable];
         srcEditor.Animations[(int)dragSrc.Id].setTrackEnabled(track, trackNode.Checked);
     }
 }
Пример #7
0
        public static void UpdateAnimationNode(TreeNode node, WorkspaceAnimation animation)
        {
            int id = (int)((DragSource)node.Tag).Id;

            if (animation.importedAnimation is ImportedKeyframedAnimation)
            {
                node.Text = "Animation" + id;
                List <ImportedAnimationKeyframedTrack> trackList = ((ImportedKeyframedAnimation)animation.importedAnimation).TrackList;
                for (int i = 0; i < trackList.Count; i++)
                {
                    ImportedAnimationKeyframedTrack track = trackList[i];
                    TreeNode trackNode = node.Nodes[i];
                    trackNode.Tag = track;
                    int numKeyframes = 0;
                    foreach (ImportedAnimationKeyframe keyframe in track.Keyframes)
                    {
                        if (keyframe != null)
                        {
                            numKeyframes++;
                        }
                    }
                    trackNode.Text = "Track: " + track.Name + ", Keyframes: " + numKeyframes;
                }
            }
            else if (animation.importedAnimation is ImportedSampledAnimation)
            {
                node.Text = "Animation(Reduced Keys)" + id;
                List <ImportedAnimationSampledTrack> trackList = ((ImportedSampledAnimation)animation.importedAnimation).TrackList;
                for (int i = 0; i < trackList.Count; i++)
                {
                    ImportedAnimationSampledTrack track = trackList[i];
                    TreeNode trackNode = node.Nodes[i];
                    trackNode.Tag = track;
                    int numScalings = 0;
                    for (int k = 0; k < track.Scalings.Length; k++)
                    {
                        if (track.Scalings[k] != null)
                        {
                            numScalings++;
                        }
                    }
                    int numRotations = 0;
                    for (int k = 0; k < track.Rotations.Length; k++)
                    {
                        if (track.Rotations[k] != null)
                        {
                            numRotations++;
                        }
                    }
                    int numTranslations = 0;
                    for (int k = 0; k < track.Translations.Length; k++)
                    {
                        if (track.Translations[k] != null)
                        {
                            numTranslations++;
                        }
                    }
                    trackNode.Text = "Track: " + track.Name + ", Length: " + track.Scalings.Length + ", Scalings: " + numScalings + ", Rotations: " + numRotations + ", Translations: " + numTranslations;
                }
            }
        }
Пример #8
0
        private void AddList <T>(List <T> list, string rootName, string editorVar)
        {
            if ((list != null) && (list.Count > 0))
            {
                TreeNode root = new TreeNode(rootName);
                root.Checked = true;
                this.treeView.AddChild(root);

                for (int i = 0; i < list.Count; i++)
                {
                    dynamic  item = list[i];
                    TreeNode node = new TreeNode(item is WorkspaceAnimation
                                                ? ((WorkspaceAnimation)item).importedAnimation is ImportedKeyframedAnimation
                                                        ? "Animation" + i : "Animation(Reduced Keys)" + i
                                                : item.Name);
                    node.Checked = true;
                    node.Tag     = new DragSource(editorVar, typeof(T), i);
                    this.treeView.AddChild(root, node);
                    if (item is WorkspaceMesh)
                    {
                        WorkspaceMesh mesh = item;
                        for (int j = 0; j < mesh.SubmeshList.Count; j++)
                        {
                            ImportedSubmesh submesh     = mesh.SubmeshList[j];
                            TreeNode        submeshNode = new TreeNode();
                            submeshNode.Checked          = mesh.isSubmeshEnabled(submesh);
                            submeshNode.Tag              = submesh;
                            submeshNode.ContextMenuStrip = this.contextMenuStripSubmesh;
                            this.treeView.AddChild(node, submeshNode);
                            UpdateSubmeshNode(submeshNode);
                        }
                    }
                    else if (item is WorkspaceMorph)
                    {
                        WorkspaceMorph morph     = item;
                        string         extraInfo = morph.MorphedVertexIndices != null ? " (morphed vertices: " + morph.MorphedVertexIndices.Count : String.Empty;
                        extraInfo += (extraInfo.Length == 0 ? " (" : ", ") + "keyframes: " + morph.KeyframeList.Count + ")";
                        node.Text += extraInfo;
                        for (int j = 0; j < morph.KeyframeList.Count; j++)
                        {
                            ImportedMorphKeyframe keyframe = morph.KeyframeList[j];
                            TreeNode keyframeNode          = new TreeNode();
                            keyframeNode.Checked          = morph.isMorphKeyframeEnabled(keyframe);
                            keyframeNode.Tag              = keyframe;
                            keyframeNode.ContextMenuStrip = this.contextMenuStripMorphKeyframe;
                            this.treeView.AddChild(node, keyframeNode);
                            UpdateMorphKeyframeNode(keyframeNode);
                        }
                    }
                    else if (item is WorkspaceAnimation)
                    {
                        WorkspaceAnimation animation = item;
                        if (animation.importedAnimation is ImportedKeyframedAnimation)
                        {
                            List <ImportedAnimationKeyframedTrack> trackList = ((ImportedKeyframedAnimation)animation.importedAnimation).TrackList;
                            for (int j = 0; j < trackList.Count; j++)
                            {
                                ImportedAnimationKeyframedTrack track = trackList[j];
                                TreeNode trackNode = new TreeNode();
                                trackNode.Checked = animation.isTrackEnabled(track);
                                trackNode.Tag     = track;
                                int numKeyframes = 0;
                                foreach (ImportedAnimationKeyframe keyframe in track.Keyframes)
                                {
                                    if (keyframe != null)
                                    {
                                        numKeyframes++;
                                    }
                                }
                                trackNode.Text = "Track: " + track.Name + ", Keyframes: " + numKeyframes;
                                this.treeView.AddChild(node, trackNode);
                            }
                        }
                        else if (animation.importedAnimation is ImportedSampledAnimation)
                        {
                            List <ImportedAnimationSampledTrack> trackList = ((ImportedSampledAnimation)animation.importedAnimation).TrackList;
                            for (int j = 0; j < trackList.Count; j++)
                            {
                                ImportedAnimationSampledTrack track = trackList[j];
                                TreeNode trackNode = new TreeNode();
                                trackNode.Checked = animation.isTrackEnabled(track);
                                trackNode.Tag     = track;
                                int numScalings = 0;
                                for (int k = 0; k < track.Scalings.Length; k++)
                                {
                                    if (track.Scalings[k] != null)
                                    {
                                        numScalings++;
                                    }
                                }
                                int numRotations = 0;
                                for (int k = 0; k < track.Rotations.Length; k++)
                                {
                                    if (track.Rotations[k] != null)
                                    {
                                        numRotations++;
                                    }
                                }
                                int numTranslations = 0;
                                for (int k = 0; k < track.Translations.Length; k++)
                                {
                                    if (track.Translations[k] != null)
                                    {
                                        numTranslations++;
                                    }
                                }
                                trackNode.Text = "Track: " + track.Name + ", Length: " + track.Scalings.Length + ", Scalings: " + numScalings + ", Rotations: " + numRotations + ", Translations: " + numTranslations;
                                this.treeView.AddChild(node, trackNode);
                            }
                        }
                    }
                }
            }
        }
Пример #9
0
Файл: Fbx.cs Проект: kkdevs/sb3u
        public static void ReplaceAnimation(ReplaceAnimationMethod replaceMethod, int insertPos, List <KeyValuePair <string, ImportedAnimationSampledTrack> > newTrackList, ImportedSampledAnimation iAnim, Dictionary <string, ImportedAnimationSampledTrack> animationNodeDic, bool negateQuaternions, float filterTolerance)
        {
            if (replaceMethod == ReplaceAnimationMethod.Replace)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack iTrack = new ImportedAnimationSampledTrack();
                    iAnim.TrackList.Add(iTrack);
                    iTrack.Name         = newTrack.Key;
                    iTrack.Scalings     = newTrack.Value.Scalings;
                    iTrack.Rotations    = newTrack.Value.Rotations;
                    iTrack.Translations = newTrack.Value.Translations;
                    iTrack.Curve        = newTrack.Value.Curve;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.ReplacePresent)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack animationNode = animationGetOriginalSamples(animationNodeDic, newTrack.Key, iAnim.TrackList);
                    animationNode.Scalings     = newTrack.Value.Scalings;
                    animationNode.Rotations    = newTrack.Value.Rotations;
                    animationNode.Translations = newTrack.Value.Translations;
                    animationNode.Curve        = newTrack.Value.Curve;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Merge)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack animationNode;
                    ImportedAnimationSampledTrack origSamples = animationGetOriginalSamples(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationSampledTrack destSamples;
                    int newEnd = insertPos + newTrack.Value.Scalings.Length;
                    if (origSamples.Scalings.Length < insertPos)
                    {
                        destSamples              = new ImportedAnimationSampledTrack();
                        destSamples.Scalings     = new Vector3?[newEnd];
                        destSamples.Rotations    = new Quaternion?[newEnd];
                        destSamples.Translations = new Vector3?[newEnd];
                        destSamples.Curve        = new float?[newEnd];
                        animationCopySampleTransformArray(origSamples, 0, destSamples, 0, origSamples.Scalings.Length);
                        animationNormalizeTrack(origSamples, destSamples, insertPos);
                    }
                    else
                    {
                        if (origSamples.Scalings.Length < newEnd)
                        {
                            destSamples              = new ImportedAnimationSampledTrack();
                            destSamples.Scalings     = new Vector3?[newEnd];
                            destSamples.Rotations    = new Quaternion?[newEnd];
                            destSamples.Translations = new Vector3?[newEnd];
                            destSamples.Curve        = new float?[newEnd];
                        }
                        else
                        {
                            destSamples              = new ImportedAnimationSampledTrack();
                            destSamples.Scalings     = new Vector3?[origSamples.Scalings.Length];
                            destSamples.Rotations    = new Quaternion?[origSamples.Rotations.Length];
                            destSamples.Translations = new Vector3?[origSamples.Translations.Length];
                            destSamples.Curve        = new float?[origSamples.Curve.Length];
                            animationCopySampleTransformArray(origSamples, newEnd, destSamples, newEnd, origSamples.Scalings.Length - newEnd);
                        }
                        animationCopySampleTransformArray(origSamples, 0, destSamples, 0, insertPos);
                    }

                    animationCopySampleTransformArray(newTrack.Value, 0, destSamples, insertPos, newTrack.Value.Scalings.Length);
                    animationNode.Scalings     = destSamples.Scalings;
                    animationNode.Rotations    = destSamples.Rotations;
                    animationNode.Translations = destSamples.Translations;
                    animationNode.Curve        = destSamples.Curve;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Insert)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack animationNode;
                    ImportedAnimationSampledTrack origSamples = animationGetOriginalSamples(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationSampledTrack destSamples;
                    int newEnd = insertPos + newTrack.Value.Scalings.Length;
                    if (origSamples.Scalings.Length < insertPos)
                    {
                        destSamples              = new ImportedAnimationSampledTrack();
                        destSamples.Scalings     = new Vector3?[newEnd];
                        destSamples.Rotations    = new Quaternion?[newEnd];
                        destSamples.Translations = new Vector3?[newEnd];
                        destSamples.Curve        = new float?[newEnd];
                        animationCopySampleTransformArray(origSamples, 0, destSamples, 0, origSamples.Scalings.Length);
                        animationNormalizeTrack(origSamples, destSamples, insertPos);
                    }
                    else
                    {
                        destSamples              = new ImportedAnimationSampledTrack();
                        destSamples.Scalings     = new Vector3?[origSamples.Scalings.Length + newTrack.Value.Scalings.Length];
                        destSamples.Rotations    = new Quaternion?[origSamples.Rotations.Length + newTrack.Value.Rotations.Length];
                        destSamples.Translations = new Vector3?[origSamples.Translations.Length + newTrack.Value.Translations.Length];
                        destSamples.Curve        = new float?[origSamples.Curve.Length + newTrack.Value.Curve.Length];
                        animationCopySampleTransformArray(origSamples, 0, destSamples, 0, insertPos);
                        animationCopySampleTransformArray(origSamples, insertPos, destSamples, newEnd, origSamples.Scalings.Length - insertPos);
                    }

                    animationCopySampleTransformArray(newTrack.Value, 0, destSamples, insertPos, newTrack.Value.Scalings.Length);
                    animationNode.Scalings     = destSamples.Scalings;
                    animationNode.Rotations    = destSamples.Rotations;
                    animationNode.Translations = destSamples.Translations;
                    animationNode.Curve        = destSamples.Curve;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Append)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack animationNode;
                    ImportedAnimationSampledTrack origSamples = animationGetOriginalSamples(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationSampledTrack destSamples = new ImportedAnimationSampledTrack();
                    destSamples.Scalings     = new Vector3?[origSamples.Scalings.Length + insertPos + newTrack.Value.Scalings.Length];
                    destSamples.Rotations    = new Quaternion?[origSamples.Rotations.Length + insertPos + newTrack.Value.Rotations.Length];
                    destSamples.Translations = new Vector3?[origSamples.Translations.Length + insertPos + newTrack.Value.Translations.Length];
                    destSamples.Curve        = new float?[origSamples.Curve.Length + insertPos + newTrack.Value.Curve.Length];
                    animationCopySampleTransformArray(origSamples, destSamples, 0);
                    bool reduced = false;
                    for (int i = 0; i < origSamples.Scalings.Length; i++)
                    {
                        if (origSamples.Scalings[i] == null)
                        {
                            reduced = true;
                            break;
                        }
                    }
                    if (origSamples.Scalings.Length > 0 && !reduced)
                    {
                        animationNormalizeTrack(origSamples, destSamples, origSamples.Scalings.Length + insertPos);
                    }
                    animationCopySampleTransformArray(newTrack.Value, destSamples, origSamples.Scalings.Length + insertPos);
                    animationNode.Scalings     = destSamples.Scalings;
                    animationNode.Rotations    = destSamples.Rotations;
                    animationNode.Translations = destSamples.Translations;
                    animationNode.Curve        = destSamples.Curve;
                }
            }
            else
            {
                Report.ReportLog("Error: Unexpected animation replace method " + replaceMethod + ". Skipping this animation");
                return;
            }

            if (negateQuaternions)
            {
                float thresholdPos = 180.0f - filterTolerance;
                float thresholdNeg = -180.0f + filterTolerance;
                foreach (var newTrack in iAnim.TrackList)
                {
                    if (newTrack.Rotations == null)
                    {
                        continue;
                    }
                    Quaternion lastQ = Quaternion.Identity;
                    Vector3    lastE = Vector3.Zero;
                    Vector3    diffE = Vector3.Zero;
                    bool       flip  = false;
                    for (int i = 0, lastUsed_keyIndex = -1; i < newTrack.Rotations.Length; i++)
                    {
                        if (newTrack.Rotations[i] == null)
                        {
                            continue;
                        }

                        Quaternion q = newTrack.Rotations[i].Value;
                        Vector3    e = FbxUtility.QuaternionToEuler(q);
                        if (lastUsed_keyIndex >= 0)
                        {
                            if (lastE.X - diffE.X > thresholdPos && e.X < thresholdNeg)
                            {
                                diffE.X += 360;
                                flip    ^= true;
                            }
                            else if (lastE.X - diffE.X < thresholdNeg && e.X > thresholdPos)
                            {
                                diffE.X -= 360;
                                flip    ^= true;
                            }
                            e.X += diffE.X;

                            if (lastE.Y - diffE.Y > thresholdPos && e.Y < thresholdNeg)
                            {
                                diffE.Y += 360;
                                flip    ^= true;
                            }
                            else if (lastE.Y - diffE.Y < thresholdNeg && e.Y > thresholdPos)
                            {
                                diffE.Y -= 360;
                                flip    ^= true;
                            }
                            e.Y += diffE.Y;

                            if (lastE.Z - diffE.Z > thresholdPos && e.Z < thresholdNeg)
                            {
                                diffE.Z += 360;
                                flip    ^= true;
                            }
                            else if (lastE.Z - diffE.Z < thresholdNeg && e.Z > thresholdPos)
                            {
                                diffE.Z -= 360;
                                flip    ^= true;
                            }
                            e.Z += diffE.Z;

                            if (flip)
                            {
                                q.X = -q.X;
                                q.Y = -q.Y;
                                q.Z = -q.Z;
                                q.W = -q.W;

                                newTrack.Rotations[i] = q;
                            }

                            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;

                                newTrack.Rotations[i] = q;
                            }
                        }
                        lastQ             = q;
                        lastE             = e;
                        lastUsed_keyIndex = i;
                    }
                }
            }
        }
Пример #10
0
Файл: Fbx.cs Проект: kkdevs/sb3u
        public static List <KeyValuePair <string, ImportedAnimationSampledTrack> > CopySampledAnimation(WorkspaceAnimation wsAnimation, int resampleCount, bool linear, bool EulerFilter, float filterPrecision, bool forceInterpolation = false)
        {
            List <ImportedAnimationSampledTrack> trackList = ((ImportedSampledAnimation)wsAnimation.importedAnimation).TrackList;
            List <KeyValuePair <string, ImportedAnimationSampledTrack> >          newTrackList      = new List <KeyValuePair <string, ImportedAnimationSampledTrack> >(trackList.Count);
            List <Tuple <ImportedAnimationTrack, ImportedAnimationSampledTrack> > interpolateTracks = new List <Tuple <ImportedAnimationTrack, ImportedAnimationSampledTrack> >();

            foreach (var wsTrack in trackList)
            {
                if (!wsAnimation.isTrackEnabled(wsTrack))
                {
                    continue;
                }

                ImportedAnimationSampledTrack track = new ImportedAnimationSampledTrack();
                bool interpolateTrack = forceInterpolation;

                Vector3?[]    newScalings     = null;
                Quaternion?[] newRotations    = null;
                Vector3?[]    newTranslations = null;

                if (!interpolateTrack)
                {
                    Vector3?[] scalings = wsTrack.Scalings;
                    if (scalings != null)
                    {
                        if (resampleCount < 0 || scalings.Length == resampleCount)
                        {
                            newScalings = new Vector3?[scalings.Length];
                            for (int i = 0; i < scalings.Length; i++)
                            {
                                Vector3?scale = scalings[i];
                                if (scale == null)
                                {
                                    continue;
                                }

                                newScalings[i] = scale.Value;
                            }
                        }
                        else
                        {
                            if (scalings.Length < 1)
                            {
                                newScalings = new Vector3?[resampleCount];
                                for (int i = 0; i < newScalings.Length; i++)
                                {
                                    newScalings[i] = new Vector3(1, 1, 1);
                                }
                            }
                            else
                            {
                                interpolateTrack = true;
                            }
                        }
                    }

                    Quaternion?[] rotations = wsTrack.Rotations;
                    if (rotations != null)
                    {
                        if (resampleCount < 0 || rotations.Length == resampleCount)
                        {
                            newRotations = new Quaternion?[rotations.Length];
                            for (int i = 0; i < rotations.Length; i++)
                            {
                                Quaternion?rotate = rotations[i];
                                if (rotate == null)
                                {
                                    continue;
                                }

                                newRotations[i] = rotate.Value;
                            }
                        }
                        else
                        {
                            if (rotations.Length < 1)
                            {
                                newRotations = new Quaternion?[resampleCount];
                                for (int i = 0; i < newRotations.Length; i++)
                                {
                                    newRotations[i] = Quaternion.Identity;
                                }
                            }
                            else
                            {
                                interpolateTrack = true;
                            }
                        }
                    }

                    Vector3?[] translations = wsTrack.Translations;
                    if (translations != null)
                    {
                        if (resampleCount < 0 || translations.Length == resampleCount)
                        {
                            newTranslations = new Vector3?[translations.Length];
                            for (int i = 0; i < translations.Length; i++)
                            {
                                Vector3?translate = translations[i];
                                if (translate == null)
                                {
                                    continue;
                                }

                                newTranslations[i] = translate.Value;
                            }
                        }
                        else
                        {
                            if (translations.Length < 1)
                            {
                                newTranslations = new Vector3?[resampleCount];
                                for (int i = 0; i < newTranslations.Length; i++)
                                {
                                    newTranslations[i] = new Vector3(0, 0, 0);
                                }
                            }
                            else
                            {
                                interpolateTrack = true;
                            }
                        }
                    }
                }

                if (interpolateTrack)
                {
                    interpolateTracks.Add(new Tuple <ImportedAnimationTrack, ImportedAnimationSampledTrack>(wsTrack, track));
                }
                track.Scalings     = newScalings;
                track.Rotations    = newRotations;
                track.Translations = newTranslations;
                newTrackList.Add(new KeyValuePair <string, ImportedAnimationSampledTrack>(wsTrack.Name, track));
            }
            if (interpolateTracks.Count > 0)
            {
                Fbx.InterpolateSampledTracks(interpolateTracks, resampleCount, linear, EulerFilter, filterPrecision);
            }
            return(newTrackList);
        }
Пример #11
0
        public static void ReplaceAnimation(ReplaceAnimationMethod replaceMethod, int insertPos, List <KeyValuePair <string, ImportedAnimationSampledTrack> > newTrackList, ImportedSampledAnimation iAnim, Dictionary <string, ImportedAnimationSampledTrack> animationNodeDic, bool negateQuaternionFlips)
        {
            if (replaceMethod == ReplaceAnimationMethod.Replace)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack iTrack = new ImportedAnimationSampledTrack();
                    iAnim.TrackList.Add(iTrack);
                    iTrack.Name         = newTrack.Key;
                    iTrack.Scalings     = newTrack.Value.Scalings;
                    iTrack.Rotations    = newTrack.Value.Rotations;
                    iTrack.Translations = newTrack.Value.Translations;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.ReplacePresent)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack animationNode = animationGetOriginalSamples(animationNodeDic, newTrack.Key, iAnim.TrackList);
                    animationNode.Scalings     = newTrack.Value.Scalings;
                    animationNode.Rotations    = newTrack.Value.Rotations;
                    animationNode.Translations = newTrack.Value.Translations;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Merge)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack animationNode;
                    ImportedAnimationSampledTrack origSamples = animationGetOriginalSamples(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationSampledTrack destSamples;
                    int newEnd = insertPos + newTrack.Value.Scalings.Length;
                    if (origSamples.Scalings.Length < insertPos)
                    {
                        destSamples              = new ImportedAnimationSampledTrack();
                        destSamples.Scalings     = new Vector3?[newEnd];
                        destSamples.Rotations    = new Quaternion?[newEnd];
                        destSamples.Translations = new Vector3?[newEnd];
                        animationCopySampleTransformArray(origSamples, 0, destSamples, 0, origSamples.Scalings.Length);
                        animationNormalizeTrack(origSamples, destSamples, insertPos);
                    }
                    else
                    {
                        if (origSamples.Scalings.Length < newEnd)
                        {
                            destSamples              = new ImportedAnimationSampledTrack();
                            destSamples.Scalings     = new Vector3?[newEnd];
                            destSamples.Rotations    = new Quaternion?[newEnd];
                            destSamples.Translations = new Vector3?[newEnd];
                        }
                        else
                        {
                            destSamples              = new ImportedAnimationSampledTrack();
                            destSamples.Scalings     = new Vector3?[origSamples.Scalings.Length];
                            destSamples.Rotations    = new Quaternion?[origSamples.Rotations.Length];
                            destSamples.Translations = new Vector3?[origSamples.Translations.Length];
                            animationCopySampleTransformArray(origSamples, newEnd, destSamples, newEnd, origSamples.Scalings.Length - newEnd);
                        }
                        animationCopySampleTransformArray(origSamples, 0, destSamples, 0, insertPos);
                    }

                    animationCopySampleTransformArray(newTrack.Value, 0, destSamples, insertPos, newTrack.Value.Scalings.Length);
                    animationNode.Scalings     = destSamples.Scalings;
                    animationNode.Rotations    = destSamples.Rotations;
                    animationNode.Translations = destSamples.Translations;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Insert)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack animationNode;
                    ImportedAnimationSampledTrack origSamples = animationGetOriginalSamples(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationSampledTrack destSamples;
                    int newEnd = insertPos + newTrack.Value.Scalings.Length;
                    if (origSamples.Scalings.Length < insertPos)
                    {
                        destSamples              = new ImportedAnimationSampledTrack();
                        destSamples.Scalings     = new Vector3?[newEnd];
                        destSamples.Rotations    = new Quaternion?[newEnd];
                        destSamples.Translations = new Vector3?[newEnd];
                        animationCopySampleTransformArray(origSamples, 0, destSamples, 0, origSamples.Scalings.Length);
                        animationNormalizeTrack(origSamples, destSamples, insertPos);
                    }
                    else
                    {
                        destSamples              = new ImportedAnimationSampledTrack();
                        destSamples.Scalings     = new Vector3?[origSamples.Scalings.Length + newTrack.Value.Scalings.Length];
                        destSamples.Rotations    = new Quaternion?[origSamples.Rotations.Length + newTrack.Value.Rotations.Length];
                        destSamples.Translations = new Vector3?[origSamples.Translations.Length + newTrack.Value.Translations.Length];
                        animationCopySampleTransformArray(origSamples, 0, destSamples, 0, insertPos);
                        animationCopySampleTransformArray(origSamples, insertPos, destSamples, newEnd, origSamples.Scalings.Length - insertPos);
                    }

                    animationCopySampleTransformArray(newTrack.Value, 0, destSamples, insertPos, newTrack.Value.Scalings.Length);
                    animationNode.Scalings     = destSamples.Scalings;
                    animationNode.Rotations    = destSamples.Rotations;
                    animationNode.Translations = destSamples.Translations;
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Append)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationSampledTrack animationNode;
                    ImportedAnimationSampledTrack origSamples = animationGetOriginalSamples(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    ImportedAnimationSampledTrack destSamples = new ImportedAnimationSampledTrack();
                    destSamples.Scalings     = new Vector3?[origSamples.Scalings.Length + insertPos + newTrack.Value.Scalings.Length];
                    destSamples.Rotations    = new Quaternion?[origSamples.Rotations.Length + insertPos + newTrack.Value.Rotations.Length];
                    destSamples.Translations = new Vector3?[origSamples.Translations.Length + insertPos + newTrack.Value.Translations.Length];
                    animationCopySampleTransformArray(origSamples, destSamples, 0);
                    bool reduced = false;
                    for (int i = 0; i < origSamples.Scalings.Length; i++)
                    {
                        if (origSamples.Scalings[i] == null)
                        {
                            reduced = true;
                            break;
                        }
                    }
                    if (origSamples.Scalings.Length > 0 && !reduced)
                    {
                        animationNormalizeTrack(origSamples, destSamples, origSamples.Scalings.Length + insertPos);
                    }
                    animationCopySampleTransformArray(newTrack.Value, destSamples, origSamples.Scalings.Length + insertPos);
                    animationNode.Scalings     = destSamples.Scalings;
                    animationNode.Rotations    = destSamples.Rotations;
                    animationNode.Translations = destSamples.Translations;
                }
            }
            else
            {
                Report.ReportLog("Error: Unexpected animation replace method " + replaceMethod + ". Skipping this animation");
                return;
            }

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

                        Quaternion q = keyframes.Rotations[i].Value;
                        if (lastUsed_keyIndex >= 0)
                        {
                            bool diffZ = Math.Sign(lastQ.Z) != Math.Sign(q.Z);
                            bool diffW = Math.Sign(lastQ.W) != Math.Sign(q.W);
                            if (diffZ && diffW)
                            {
                                q.X = -q.X;
                                q.Y = -q.Y;
                                q.Z = -q.Z;
                                q.W = -q.W;

                                keyframes.Rotations[i] = q;
                            }
                        }
                        lastQ             = q;
                        lastUsed_keyIndex = i;
                    }
                }
            }
        }