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); } }
public static void ReplaceAnimation(WorkspaceAnimation wsAnimation, odfParser parser, int resampleCount, bool linear, ReplaceAnimationMethod replaceMethod, string clip, int insertPos, bool negateQuaternionFlips) { if (parser.AnimSection == null) { Report.ReportLog(Path.GetFileName(parser.ODFPath) + " doesn't have an animation section. Skipping this animation"); return; } if (!(wsAnimation.importedAnimation is ImportedKeyframedAnimation)) { Report.ReportLog("The animation has incompatible keyframes."); return; } Report.ReportLog("Replacing animation ..."); List <KeyValuePair <string, ImportedAnimationKeyframe[]> > newTrackList = FbxUtility.CopyKeyframedAnimation(wsAnimation, resampleCount, linear); List <odfTrack> animationNodeList = odf.FindClip(clip, parser).ChildList; ImportedKeyframedAnimation iAnim = new ImportedKeyframedAnimation(); iAnim.TrackList = new List <ImportedAnimationKeyframedTrack>(animationNodeList.Count); Dictionary <string, ImportedAnimationKeyframedTrack> animationNodeDic = null; if (replaceMethod != ReplaceAnimationMethod.Replace) { animationNodeDic = new Dictionary <string, ImportedAnimationKeyframedTrack>(); foreach (odfTrack animationNode in animationNodeList) { ImportedAnimationKeyframedTrack iTrack = new ImportedAnimationKeyframedTrack(); iTrack.Name = odf.FindFrame(animationNode.BoneFrameId, parser.FrameSection.RootFrame).Name; iTrack.Keyframes = Plugins.ODFConverter.ConvertTrack(animationNode.KeyframeList); animationNodeDic.Add(odf.FindFrame(animationNode.BoneFrameId, parser.FrameSection.RootFrame).Name, iTrack); iAnim.TrackList.Add(iTrack); } } foreach (var newTrack in newTrackList) { ImportedAnimationKeyframe[] keyframes = newTrack.Value; Quaternion q = keyframes[0].Rotation; keyframes[0].Rotation *= -1; /* if (keyframes[0].Rotation.Angle == 0 || q.Angle == 0) * { * Report.ReportLog("track " + newTrack.Key + " r=" + keyframes[0].Rotation.Angle + " q=" + q.Angle); * }*/ } FbxUtility.ReplaceAnimation(replaceMethod, insertPos, newTrackList, iAnim, animationNodeDic, negateQuaternionFlips); animationNodeList.Clear(); foreach (var newTrack in iAnim.TrackList) { ImportedAnimationKeyframe[] keyframes = ((ImportedAnimationKeyframedTrack)newTrack).Keyframes; odfTrack animationNode = new odfTrack(keyframes.Length); odf.CreateUnknowns(animationNode); animationNodeList.Add(animationNode); animationNode.KeyframeList = Plugins.ODFConverter.ConvertTrack(keyframes); animationNode.BoneFrameId = odf.FindFrame(newTrack.Name, parser.FrameSection.RootFrame).Id; } }
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); } }
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); } }
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); } }