Пример #1
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;
                    }
                }
            }
        }
Пример #2
0
Файл: Fbx.cs Проект: kkdevs/sb3u
        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];
                origKeyframes.Curve        = new float?[0];
            }
            return(origKeyframes);
        }
Пример #3
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;
                    }
                }
            }
        }