Exemplo n.º 1
0
Arquivo: Fbx.cs Projeto: kkdevs/sb3u
            public static ImportedSampledAnimation ConvertAnimation(ImportedKeyframedAnimation keyframedAnim)
            {
                ImportedSampledAnimation destAnim = new ImportedSampledAnimation();

                destAnim.TrackList = new List <ImportedAnimationSampledTrack>(keyframedAnim.TrackList.Count);
                foreach (ImportedAnimationKeyframedTrack keyframedTrack in keyframedAnim.TrackList)
                {
                    ImportedAnimationSampledTrack sampledTrack = new ImportedAnimationSampledTrack();
                    sampledTrack.Name         = keyframedTrack.Name;
                    sampledTrack.Scalings     = new Vector3?[keyframedTrack.Keyframes.Length];
                    sampledTrack.Rotations    = new Quaternion?[keyframedTrack.Keyframes.Length];
                    sampledTrack.Translations = new Vector3?[keyframedTrack.Keyframes.Length];
                    for (int i = 0; i < keyframedTrack.Keyframes.Length; i++)
                    {
                        sampledTrack.Scalings[i]     = keyframedTrack.Keyframes[i].Scaling;
                        sampledTrack.Rotations[i]    = keyframedTrack.Keyframes[i].Rotation;
                        sampledTrack.Translations[i] = keyframedTrack.Keyframes[i].Translation;
                    }
                    destAnim.TrackList.Add(sampledTrack);
                }

                return(destAnim);
            }
Exemplo n.º 2
0
            private void ImportAnimation(Section section)
            {
                ImportedKeyframedAnimation workspaceAnimation = new ImportedKeyframedAnimation();
                workspaceAnimation.TrackList = new List<ImportedAnimationKeyframedTrack>(section.children.Count);

                foreach (Section animSection in section.children)
                {
                    if (animSection.type == "Animation")
                    {
                        string trackName = null;
                        float[][][] keyDataArray = new float[5][][];
                        int[][] keyIndexArray = new int[5][];
                        foreach (Section keySection in animSection.children)
                        {
                            if (keySection.type == "AnimationKey")
                            {
                                LinkedListNode<object> keyNode = keySection.data.First;
                                int keyType = ConvertInt32(keyNode.Value);
                                keyNode = keyNode.Next;
                                int numKeys = ConvertInt32(keyNode.Value);
                                keyNode = keyNode.Next;
                                float[][] keyData = new float[numKeys][];
                                int[] keyIndices = new int[numKeys];
                                for (int i = 0; i < numKeys; i++)
                                {
                                    int keyIdx = ConvertInt32(keyNode.Value);
                                    keyIndices[i] = keyIdx;
                                    keyNode = keyNode.Next;
                                    int numFloats = ConvertInt32(keyNode.Value);
                                    keyNode = keyNode.Next;
                                    keyData[i] = new float[numFloats];
                                    for (int j = 0; j < numFloats; j++)
                                    {
                                        keyData[i][j] = ConvertFloat(keyNode.Value);
                                        keyNode = keyNode.Next;
                                    }
                                }
                                keyDataArray[keyType] = keyData;
                                keyIndexArray[keyType] = keyIndices;
                            }
                            else if (keySection.type == "ref")
                            {
                                trackName = keySection.name;
                            }
                            else
                            {
                                Report.ReportLog("Warning: unexpected section " + animSection.type);
                            }
                        }

                        if (trackName == null)
                        {
                            throw new Exception("animation doesn't have a track name");
                        }
                        if ((keyDataArray[0] == null) || (keyDataArray[2] == null))
                        {
                            throw new Exception("animation " + trackName + " doesn't have the correct key types");
                        }
                        if (keyDataArray[1] == null)
                        {
                            keyDataArray[1] = new float[keyDataArray[0].Length][];
                            for (int i = 0; i < keyDataArray[1].Length; i++)
                            {
                                keyDataArray[1][i] = new float[] { 1, 1, 1 };
                            }
                        }
                        if ((keyDataArray[0].Length != keyDataArray[1].Length) || (keyDataArray[0].Length != keyDataArray[2].Length))
                        {
                            throw new Exception("animation " + trackName + " doesn't have the same number of keys for each type");
                        }

                        int length = keyIndexArray[0][keyIndexArray[0].Length - 1] + 1;
                        ImportedAnimationKeyframe[] keyframes = new ImportedAnimationKeyframe[length];
                        for (int i = 0; i < keyIndexArray[0].Length; i++)
                        {
                            int idx = keyIndexArray[0][i];
                            float[] rotation = keyDataArray[0][i];
                            float[] scaling = keyDataArray[1][i];
                            float[] translation = keyDataArray[2][i];
                            keyframes[idx] = new ImportedAnimationKeyframe();
                            keyframes[idx].Rotation = new Quaternion(rotation[1], rotation[2], -rotation[3], rotation[0]);
                            keyframes[idx].Scaling = new Vector3(scaling[0], scaling[1], scaling[2]);
                            keyframes[idx].Translation = new Vector3(translation[0], translation[1], -translation[2]);
                        }
                        if (keyframes.Length > 0)
                        {
                            ImportedAnimationKeyframedTrack track = new ImportedAnimationKeyframedTrack();
                            track.Name = trackName;
                            track.Keyframes = keyframes;
                            workspaceAnimation.TrackList.Add(track);
                        }
                    }
                    else
                    {
                        Report.ReportLog("Warning: unexpected section " + animSection.type);
                    }
                }

                if (workspaceAnimation.TrackList.Count > 0)
                {
                    AnimationList.Add(workspaceAnimation);
                }
            }
Exemplo n.º 3
0
            private void ImportAnimationSet(List<Document.Animation> animations, ImportedKeyframedAnimation wsAnimation)
            {
                try
                {
                    if (animations == null)
                    {
                        return;
                    }

                    Document.Animation animation = animations[0];
                    if (animation.channel == null)
                    {
                        foreach (Document.Animation animationSet in animations)
                        {
                            ImportAnimationSet(animationSet.children, wsAnimation);
                        }
                    }
                    else
                    {
                        ImportAnimation(animations, wsAnimation);
                    }
                }
                catch (Exception e)
                {
                    Report.ReportLog("Error importing animations: " + e.Message);
                }
            }
Exemplo n.º 4
0
            private void ImportAnimation(List<Document.Animation> animations, ImportedKeyframedAnimation wsAnimation)
            {
                Dictionary<string, List<KeyValuePair<string, Document.Source>>> trackList = new Dictionary<string, List<KeyValuePair<string, Document.Source>>>();
                for (int i = 0; i < animations.Count; i++)
                {
                    int typeIdx = animations[i].channel.target.IndexOf('/');
                    if (typeIdx < 0)
                    {
                        throw new Exception("Couldn't find transform type for ANIMATION " + animations[i].id);
                    }
                    string frameName = DecodeName(animations[i].channel.target.Substring(0, typeIdx));
                    typeIdx++;
                    string type = animations[i].channel.target.Substring(typeIdx, animations[i].channel.target.Length - typeIdx);

                    for (int j = 0; j < animations[i].sampler.inputs.Count; j++)
                    {
                        if (animations[i].sampler.inputs[j].semantic == "OUTPUT")
                        {
                            Document.Source source = (Document.Source)animations[i].sampler.inputs[j].source;
                            List<KeyValuePair<string, Document.Source>> track;
                            if (!trackList.TryGetValue(frameName, out track))
                            {
                                track = new List<KeyValuePair<string, Document.Source>>();
                                trackList.Add(frameName, track);
                            }
                            track.Add(new KeyValuePair<string, Document.Source>(type, source));
                            break;
                        }
                    }
                }

                foreach (KeyValuePair<string, List<KeyValuePair<string, Document.Source>>> track in trackList)
                {
                    int numFrames = 0;
                    for (int i = 0; i < track.Value.Count; i++)
                    {
                        int count = track.Value[i].Value.accessor.count;
                        if (count > numFrames)
                        {
                            numFrames = count;
                        }
                    }

                    ImportedAnimationKeyframe[] keyframes = new ImportedAnimationKeyframe[numFrames];
                    for (int i = 0; i < numFrames; i++)
                    {
                        Vector3 translate = new Vector3(0, 0, 0);
                        Vector3 scale = new Vector3(1, 1, 1);
                        float rotX = 0;
                        float rotY = 0;
                        float rotZ = 0;

                        foreach (KeyValuePair<string, Document.Source> transform in track.Value)
                        {
                            Document.Source source = transform.Value;
                            Document.Array<float> array = (Document.Array<float>)source.array;
                            int arrayIdx = source.accessor.offset + (source.accessor.stride * i);
                            if (arrayIdx < array.Count)
                            {
                                float val = array[arrayIdx];

                                switch (transform.Key)
                                {
                                    case "translate.X":
                                        translate[0] = val;
                                        break;
                                    case "translate.Y":
                                        if (Z_UP)
                                        {
                                            translate[2] = -val;
                                        }
                                        else
                                        {
                                            translate[1] = val;
                                        }
                                        break;
                                    case "translate.Z":
                                        if (Z_UP)
                                        {
                                            translate[1] = val;
                                        }
                                        else
                                        {
                                            translate[2] = val;
                                        }
                                        break;
                                    case "rotateX.ANGLE":
                                        rotX = val;
                                        break;
                                    case "rotateY.ANGLE":
                                        rotY = val;
                                        break;
                                    case "rotateZ.ANGLE":
                                        rotZ = val;
                                        break;
                                    case "scale.X":
                                        scale[0] = val;
                                        break;
                                    case "scale.Y":
                                        if (Z_UP)
                                        {
                                            scale[2] = val;
                                        }
                                        else
                                        {
                                            scale[1] = val;
                                        }
                                        break;
                                    case "scale.Z":
                                        if (Z_UP)
                                        {
                                            scale[1] = val;
                                        }
                                        else
                                        {
                                            scale[2] = val;
                                        }
                                        break;
                                    default:
                                        throw new Exception("Unknown transform type " + transform.Key + " for ANIMATION " + animations[i].id);
                                }
                            }
                        }

                        Matrix rotMatrix = Matrix.Identity;
                        Matrix rotXMatrix = Matrix.RotationAxis(new Vector3(1, 0, 0), (float)(rotX * Math.PI / 180));
                        Matrix rotYMatrix = Matrix.RotationAxis(new Vector3(0, 1, 0), (float)(rotY * Math.PI / 180));
                        Matrix rotZMatrix = Matrix.RotationAxis(new Vector3(0, 0, 1), (float)(rotZ * Math.PI / 180));
                        rotMatrix = rotMatrix * rotZMatrix;
                        rotMatrix = rotMatrix * rotYMatrix;
                        rotMatrix = rotMatrix * rotXMatrix;
                        if (Z_UP)
                        {
                            rotMatrix = ZUpToYUpMatrix * rotMatrix;
                        }

                        Vector3 dummyScale;
                        Quaternion rotation;
                        Vector3 dummyTranslate;
                        if (!rotMatrix.Decompose(out dummyScale, out rotation, out dummyTranslate))
                        {
                            throw new Exception("Failed to decompose matrix");
                        }

                        keyframes[i] = new ImportedAnimationKeyframe();
                        keyframes[i].Rotation = rotation;
                        keyframes[i].Scaling = scale;
                        keyframes[i].Translation = translate;
                    }

                    ImportedAnimationKeyframedTrack importedTrack = new ImportedAnimationKeyframedTrack();
                    importedTrack.Name = track.Key;
                    importedTrack.Keyframes = keyframes;
                    wsAnimation.TrackList.Add(importedTrack);
                }
            }
Exemplo n.º 5
0
            public Importer(string path)
            {
                try
                {
                    FrameList = new List<ImportedFrame>();
                    MeshList = new List<ImportedMesh>();
                    MaterialList = new List<ImportedMaterial>();
                    TextureList = new List<ImportedTexture>();
                    AnimationList = new List<ImportedAnimation>();
                    MorphList = new List<ImportedMorph>();

                    colladaDoc = new Document(path);
                    if (colladaDoc.asset != null)
                    {
                        if (colladaDoc.asset.up_axis == "Z_UP")
                        {
                            Z_UP = true;
                            ZUpToYUpMatrix[0, 0] = 1;
                            ZUpToYUpMatrix[1, 2] = 1;
                            ZUpToYUpMatrix[2, 1] = -1;
                        }
                        if ((colladaDoc.asset.contributors != null) && colladaDoc.asset.contributors[0].authoring_tool.Contains("Blender"))
                        {
                            IsBlender = true;
                        }
                    }

                    Dictionary<string, ImportedTexture> textureIdDic = new Dictionary<string, ImportedTexture>();
                    if (colladaDoc.images != null)
                    {
                        for (int i = 0; i < colladaDoc.images.Count; i++)
                        {
                            ImportedTexture tex = ImportImage(colladaDoc.images[i]);
                            if (tex != null)
                            {
                                ImportedTexture prevTex;
                                if (textureDic.TryGetValue(tex.Name, out prevTex))
                                {
                                    tex = prevTex;
                                }
                                else
                                {
                                    textureDic.Add(tex.Name, tex);
                                    TextureList.Add(tex);
                                }

                                textureIdDic.Add(colladaDoc.images[i].id, tex);
                            }
                        }
                    }

                    if (colladaDoc.materials != null)
                    {
                        for (int i = 0; i < colladaDoc.materials.Count; i++)
                        {
                            ImportedMaterial mat = ImportMaterial(colladaDoc.materials[i], textureIdDic);
                            if ((mat != null) && !materialDic.ContainsKey(mat.Name))
                            {
                                materialDic.Add(mat.Name, mat);
                                MaterialList.Add(mat);
                            }
                        }
                    }

                    if (colladaDoc.instanceVisualScene != null)
                    {
                        Document.VisualScene scene = (Document.VisualScene)colladaDoc.dic[colladaDoc.instanceVisualScene.url.Fragment];
                        if (scene != null)
                        {
                            Conditioner.ConvexTriangulator(colladaDoc);
                            for (int i = 0; i < scene.nodes.Count; i++)
                            {
                                ImportedFrame frame = ImportNode(scene.nodes[i]);
                                if (frame != null)
                                {
                                    FrameList.Add(frame);
                                }
                            }
                        }
                    }

                    ImportedKeyframedAnimation wsAnimation = new ImportedKeyframedAnimation();
                    wsAnimation.TrackList = new List<ImportedAnimationKeyframedTrack>();
                    ImportAnimationSet(colladaDoc.animations, wsAnimation);
                    if (wsAnimation.TrackList.Count > 0)
                    {
                        AnimationList.Add(wsAnimation);
                    }
                }
                catch (Exception e)
                {
                    Report.ReportLog("Error importing Collada: " + e.Message);
                }
            }
Exemplo n.º 6
0
            public void ConvertAnimation(odfANIMSection anim, odfParser odaParser, bool odaSkeleton)
            {
                if (odaSkeleton)
                {
                    FrameList.Clear();
                    ConvertFrames(odaParser.FrameSection.RootFrame);
                }

                ImportedKeyframedAnimation iAnim = new ImportedKeyframedAnimation();
                AnimationList.Add(iAnim);
                iAnim.TrackList = new List<ImportedAnimationKeyframedTrack>(anim.Count);
                string notFound = String.Empty;
                foreach (odfTrack track in anim)
                {
                    odfFrame boneFrame = odf.FindFrame(track.BoneFrameId, odaParser.FrameSection.RootFrame);
                    if (boneFrame == null)
                    {
                        notFound += (notFound.Length > 0 ? ", " : "") + track.BoneFrameId;
                        continue;
                    }

                    ImportedAnimationKeyframedTrack iTrack = new ImportedAnimationKeyframedTrack();
                    iAnim.TrackList.Add(iTrack);
                    iTrack.Name = boneFrame.Name;
                    iTrack.Keyframes = ConvertTrack(track.KeyframeList);
                }
                if (notFound.Length > 0)
                {
                    Report.ReportLog("Warning: Animations weren't converted for the following missing frame IDs: " + notFound);
                }
            }
Exemplo n.º 7
0
Arquivo: Fbx.cs Projeto: kkdevs/sb3u
 public static ImportedAnimationKeyframe[] animationGetOriginalKeyframes(Dictionary <string, ImportedAnimationKeyframedTrack> animationNodeDic, string trackName, ImportedKeyframedAnimation anim, out ImportedAnimationKeyframedTrack animationNode)
 {
     ImportedAnimationKeyframe[] origKeyframes;
     if (animationNodeDic.TryGetValue(trackName, out animationNode))
     {
         origKeyframes = animationNode.Keyframes;
     }
     else
     {
         animationNode = new ImportedAnimationKeyframedTrack();
         anim.TrackList.Add(animationNode);
         animationNode.Name = trackName;
         origKeyframes      = new ImportedAnimationKeyframe[0];
     }
     return(origKeyframes);
 }
Exemplo n.º 8
0
Arquivo: Fbx.cs Projeto: kkdevs/sb3u
        public static void ReplaceAnimation(ReplaceAnimationMethod replaceMethod, int insertPos, List <KeyValuePair <string, ImportedAnimationKeyframe[]> > newTrackList, ImportedKeyframedAnimation iAnim, Dictionary <string, ImportedAnimationKeyframedTrack> animationNodeDic, bool negateQuaternionFlips)
        {
            if (replaceMethod == ReplaceAnimationMethod.Replace)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationKeyframedTrack iTrack = new ImportedAnimationKeyframedTrack();
                    iAnim.TrackList.Add(iTrack);
                    iTrack.Name = newTrack.Key;
                    if (insertPos == 0)
                    {
                        iTrack.Keyframes = newTrack.Value;
                    }
                    else
                    {
                        iTrack.Keyframes = new ImportedAnimationKeyframe[insertPos + newTrack.Value.Length];
                        newTrack.Value.CopyTo(iTrack.Keyframes, insertPos);
                    }
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.ReplacePresent)
            {
                if (insertPos > 0)
                {
                    foreach (var oldTrack in iAnim.TrackList)
                    {
                        ImportedAnimationKeyframe[] keyframes = new ImportedAnimationKeyframe[insertPos + oldTrack.Keyframes.Length];
                        oldTrack.Keyframes.CopyTo(keyframes, insertPos);
                        oldTrack.Keyframes = keyframes;
                    }
                }
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationKeyframedTrack animationNode;
                    FbxUtility.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, iAnim, out animationNode);
                    if (insertPos == 0)
                    {
                        animationNode.Keyframes = newTrack.Value;
                    }
                    else
                    {
                        animationNode.Keyframes = new ImportedAnimationKeyframe[insertPos + newTrack.Value.Length];
                        newTrack.Value.CopyTo(animationNode.Keyframes, insertPos);
                    }
                }
            }
            else if (replaceMethod == ReplaceAnimationMethod.Merge)
            {
                foreach (var newTrack in newTrackList)
                {
                    ImportedAnimationKeyframedTrack 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)
                {
                    ImportedAnimationKeyframedTrack 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)
                {
                    ImportedAnimationKeyframedTrack 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)
                {
                    ImportedAnimationKeyframe[] keyframes = ((ImportedAnimationKeyframedTrack)newTrack).Keyframes;
                    Quaternion lastQ = Quaternion.Identity;
                    for (int i = 0, lastUsed_keyIndex = -1; i < keyframes.Length; i++)
                    {
                        ImportedAnimationKeyframe iKeyframe = 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;
                    }
                }
            }
        }