private xaAnimationKeyframe AddKeyframe(xaAnimationTrack track, int index, int i) { xaAnimationKeyframe keyframe = new xaAnimationKeyframe(); keyframe.Index = index; xa.CreateUnknowns(keyframe); if (i < track.KeyframeList.Count) { if (i > 0) { int predIdx = track.KeyframeList[i - 1].Index; float indexPosition = (float)(index - predIdx) / (track.KeyframeList[i].Index - predIdx); keyframe.Scaling = track.KeyframeList[i - 1].Scaling + (track.KeyframeList[i].Scaling - track.KeyframeList[i - 1].Scaling) * indexPosition; keyframe.Rotation = track.KeyframeList[i - 1].Rotation + (track.KeyframeList[i].Rotation - track.KeyframeList[i - 1].Rotation) * indexPosition; keyframe.Translation = track.KeyframeList[i - 1].Translation + (track.KeyframeList[i].Translation - track.KeyframeList[i - 1].Translation) * indexPosition; } else { keyframe.Scaling = track.KeyframeList[i].Scaling; keyframe.Rotation = track.KeyframeList[i].Rotation; keyframe.Translation = track.KeyframeList[i].Translation; } } else { keyframe.Scaling = track.KeyframeList[track.KeyframeList.Count - 1].Scaling; keyframe.Rotation = track.KeyframeList[track.KeyframeList.Count - 1].Rotation; keyframe.Translation = track.KeyframeList[track.KeyframeList.Count - 1].Translation; } track.KeyframeList.Insert(i, keyframe); Changed = true; return(keyframe); }
public void RenameTrack(string track, string newName) { xaAnimationTrack xaTrack = xa.FindTrack(track, Parser); xaTrack.Name = newName; Changed = true; }
public void RemoveTrack(string track) { xaAnimationTrack xaTrack = xa.FindTrack(track, Parser); Parser.AnimationSection.TrackList.Remove(xaTrack); Changed = true; }
public void SetKeyframeTranslation(xaAnimationTrack track, int keyframeIdx, object translation) { xaAnimationKeyframe keyframe = track.KeyframeList[keyframeIdx]; Vector3 trans = new Vector3((float)(double)((object[])translation)[0], (float)(double)((object[])translation)[1], (float)(double)((object[])translation)[2]); keyframe.Translation = trans; Changed = true; }
public void SetKeyframeScaling(xaAnimationTrack track, int keyframeIdx, object scaling) { xaAnimationKeyframe keyframe = track.KeyframeList[keyframeIdx]; Vector3 scale = new Vector3((float)(double)((object[])scaling)[0], (float)(double)((object[])scaling)[1], (float)(double)((object[])scaling)[2]); keyframe.Scaling = scale; Changed = true; }
public int GetTrackId(string name) { for (int i = 0; i < Parser.AnimationSection.TrackList.Count; i++) { xaAnimationTrack track = Parser.AnimationSection.TrackList[i]; if (track.Name == name) { return(i); } } return(-1); }
public void RemoveKeyframe(xaAnimationTrack track, int index) { for (int i = 0; i < track.KeyframeList.Count; i++) { if (track.KeyframeList[i].Index == index) { track.KeyframeList.RemoveAt(i); Changed = true; return; } } }
public static xaAnimationTrack animationGetOriginalKeyframes(Dictionary <string, xaAnimationTrack> animationNodeDic, string trackName, List <xaAnimationTrack> animationNodeList) { xaAnimationTrack animationNode; if (!animationNodeDic.TryGetValue(trackName, out animationNode)) { animationNode = new xaAnimationTrack(); animationNodeList.Add(animationNode); animationNode.Name = trackName; CreateUnknowns(animationNode); } return(animationNode); }
public xaAnimationKeyframe NewKeyframe(xaAnimationTrack track, int index) { for (int i = 0; i < track.KeyframeList.Count; i++) { if (track.KeyframeList[i].Index == index) { throw new Exception(track.Name + " already has a keyframe at " + index); } if (track.KeyframeList[i].Index > index) { return(AddKeyframe(track, index, i)); } } return(AddKeyframe(track, index, track.KeyframeList.Count)); }
public bool RenameTrackProfile(string pattern, string replacement) { bool anyRenaming = false; for (int i = 0; i < Parser.AnimationSection.TrackList.Count; i++) { xaAnimationTrack keyframeList = Parser.AnimationSection.TrackList[i]; string name = System.Text.RegularExpressions.Regex.Replace(keyframeList.Name, pattern, replacement, System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (name != keyframeList.Name) { RenameTrack(keyframeList.Name, name); Changed = true; anyRenaming = true; } } return(anyRenaming); }
public static xaAnimationKeyframe[] animationGetOriginalKeyframes(Dictionary <string, xaAnimationTrack> animationNodeDic, string trackName, List <xaAnimationTrack> animationNodeList, out xaAnimationTrack animationNode) { xaAnimationKeyframe[] origKeyframes; if (animationNodeDic.TryGetValue(trackName, out animationNode)) { origKeyframes = animationNode.KeyframeList.ToArray(); } else { animationNode = new xaAnimationTrack(); animationNodeList.Add(animationNode); animationNode.Name = trackName; CreateUnknowns(animationNode); origKeyframes = new xaAnimationKeyframe[0]; } return(origKeyframes); }
public void SetKeyframeRotation(xaAnimationTrack track, int keyframeIdx, object rotation) { xaAnimationKeyframe keyframe = track.KeyframeList[keyframeIdx]; if (((object[])rotation).Length == 3) { Vector3 rot = new Vector3((float)(double)((object[])rotation)[0], (float)(double)((object[])rotation)[1], (float)(double)((object[])rotation)[2]); keyframe.Rotation = FbxUtility.EulerToQuaternion(rot); } else if (((object[])rotation).Length == 4) { Quaternion rot = new Quaternion((float)(double)((object[])rotation)[0], (float)(double)((object[])rotation)[1], (float)(double)((object[])rotation)[2], (float)(double)((object[])rotation)[3]); keyframe.Rotation = rot; } else { throw new Exception("SetKeyframeRotation must be called with three or four arguments"); } Changed = true; }
public void CopyTrack(string track) { xaAnimationTrack src = xa.FindTrack(track, Parser); xaAnimationTrack cpy = new xaAnimationTrack(); cpy.Name = src.Name + "_copy"; cpy.Unknown1 = (byte[])src.Unknown1.Clone(); cpy.KeyframeList = new List <xaAnimationKeyframe>(src.KeyframeList.Count); foreach (xaAnimationKeyframe srcKeyframe in src.KeyframeList) { xaAnimationKeyframe cpyKeyframe = new xaAnimationKeyframe(); cpyKeyframe.Index = srcKeyframe.Index; cpyKeyframe.Rotation = srcKeyframe.Rotation; cpyKeyframe.Unknown1 = (byte[])srcKeyframe.Unknown1.Clone(); cpyKeyframe.Translation = srcKeyframe.Translation; cpyKeyframe.Scaling = srcKeyframe.Scaling; cpy.KeyframeList.Add(cpyKeyframe); } Parser.AnimationSection.TrackList.Add(cpy); Changed = true; }
protected xaAnimationSection ParseAnimationSection() { if (reader.ReadByte() == 0) { return(null); } xaAnimationSection section = new xaAnimationSection(); int numClips; if (Format == 0x03) { numClips = 1024; } else { numClips = 512; } section.ClipList = new List <xaAnimationClip>(numClips); for (int i = 0; i < numClips; i++) { xaAnimationClip clip = new xaAnimationClip(); section.ClipList.Add(clip); clip.Name = reader.ReadName(64); clip.Speed = reader.ReadSingle(); clip.Unknown1 = reader.ReadBytes(4); clip.Start = reader.ReadSingle(); clip.End = reader.ReadSingle(); clip.Unknown2 = reader.ReadBytes(1); clip.Unknown3 = reader.ReadBytes(1); clip.Unknown4 = reader.ReadBytes(1); clip.Next = reader.ReadInt32(); clip.Unknown5 = reader.ReadBytes(1); clip.Unknown6 = reader.ReadBytes(4); clip.Unknown7 = reader.ReadBytes(16); } int numTracks = reader.ReadInt32(); section.TrackList = new List <xaAnimationTrack>(numTracks); for (int i = 0; i < numTracks; i++) { xaAnimationTrack track = new xaAnimationTrack(); section.TrackList.Add(track); track.Name = reader.ReadName(); int numKeyframes = reader.ReadInt32(); track.Unknown1 = reader.ReadBytes(4); track.KeyframeList = new List <xaAnimationKeyframe>(numKeyframes); for (int j = 0; j < numKeyframes; j++) { xaAnimationKeyframe keyframe = new xaAnimationKeyframe(); track.KeyframeList.Add(keyframe); keyframe.Index = reader.ReadInt32(); keyframe.Rotation = reader.ReadQuaternion(); keyframe.Unknown1 = reader.ReadBytes(8); keyframe.Translation = reader.ReadVector3(); keyframe.Scaling = reader.ReadVector3(); } } return(section); }
public void SetKeyframeScaling(string trackName, int keyframeIdx, object scaling) { xaAnimationTrack track = Parser.AnimationSection.TrackList[GetTrackId(trackName)]; SetKeyframeScaling(track, keyframeIdx, scaling); }
public static xaAnimationKeyframe[] animationGetOriginalKeyframes(Dictionary <string, xaAnimationTrack> animationNodeDic, string trackName, List <xaAnimationTrack> animationNodeList, out xaAnimationTrack animationNode) { animationNode = animationGetOriginalKeyframes(animationNodeDic, trackName, animationNodeList); xaAnimationKeyframe[] origKeyframes; if (animationNode.KeyframeList != null) { origKeyframes = animationNode.KeyframeList.ToArray(); } else { origKeyframes = new xaAnimationKeyframe[0]; } return(origKeyframes); }
public void SetKeyframeRotation(string trackName, int keyframeIdx, object rotation) { xaAnimationTrack track = Parser.AnimationSection.TrackList[GetTrackId(trackName)]; SetKeyframeRotation(track, keyframeIdx, rotation); }
public static void ReplaceAnimation(WorkspaceAnimation wsAnimation, xaParser parser, int resampleCount, ReplaceAnimationMethod replaceMethod, int insertPos) { if (parser.AnimationSection == null) { Report.ReportLog("The .xa file doesn't have an animation section. Skipping this animation"); return; } if (!(wsAnimation.importedAnimation is ImportedKeyframedAnimation)) { Report.ReportLog("The animation has incompatible keyframes."); return; } Report.ReportLog("Replacing animation ..."); List <ImportedAnimationKeyframedTrack> trackList = ((ImportedKeyframedAnimation)wsAnimation.importedAnimation).TrackList; List <KeyValuePair <string, xaAnimationKeyframe[]> > newTrackList = new List <KeyValuePair <string, xaAnimationKeyframe[]> >(trackList.Count); List <Tuple <ImportedAnimationTrack, xaAnimationKeyframe[]> > interpolateTracks = new List <Tuple <ImportedAnimationTrack, xaAnimationKeyframe[]> >(); foreach (var wsTrack in trackList) { if (!wsAnimation.isTrackEnabled(wsTrack)) { continue; } ImportedAnimationKeyframe[] keyframes = ((ImportedAnimationKeyframedTrack)wsTrack).Keyframes; xaAnimationKeyframe[] newKeyframes = null; int wsTrackKeyframesLength = 0; for (int i = 0; i < keyframes.Length; i++) { if (keyframes[i] != null) { wsTrackKeyframesLength++; } } if (resampleCount < 0 || wsTrackKeyframesLength == resampleCount) { newKeyframes = new xaAnimationKeyframe[wsTrackKeyframesLength]; int keyframeIdx = 0; for (int i = 0; i < keyframes.Length; i++) { ImportedAnimationKeyframe keyframe = keyframes[i]; if (keyframe == null) { continue; } newKeyframes[keyframeIdx] = new xaAnimationKeyframe(); newKeyframes[keyframeIdx].Index = i; newKeyframes[keyframeIdx].Rotation = keyframe.Rotation; xa.CreateUnknowns(newKeyframes[keyframeIdx]); newKeyframes[keyframeIdx].Translation = keyframe.Translation; newKeyframes[keyframeIdx].Scaling = keyframe.Scaling; keyframeIdx++; } } else { newKeyframes = new xaAnimationKeyframe[resampleCount]; if (wsTrackKeyframesLength < 1) { xaAnimationKeyframe keyframe = new xaAnimationKeyframe(); keyframe.Rotation = Quaternion.Identity; keyframe.Scaling = new Vector3(1, 1, 1); keyframe.Translation = new Vector3(0, 0, 0); xa.CreateUnknowns(keyframe); for (int i = 0; i < newKeyframes.Length; i++) { keyframe.Index = i; newKeyframes[i] = keyframe; } } else { interpolateTracks.Add(new Tuple <ImportedAnimationTrack, xaAnimationKeyframe[]>(wsTrack, newKeyframes)); } } newTrackList.Add(new KeyValuePair <string, xaAnimationKeyframe[]>(wsTrack.Name, newKeyframes)); } if (interpolateTracks.Count > 0) { Fbx.InterpolateKeyframes(interpolateTracks, resampleCount); } List <xaAnimationTrack> animationNodeList = parser.AnimationSection.TrackList; Dictionary <string, xaAnimationTrack> animationNodeDic = null; if (replaceMethod != ReplaceAnimationMethod.Replace) { animationNodeDic = new Dictionary <string, xaAnimationTrack>(); foreach (xaAnimationTrack animationNode in animationNodeList) { animationNodeDic.Add(animationNode.Name, animationNode); } } if (replaceMethod == ReplaceAnimationMethod.Replace) { animationNodeList.Clear(); foreach (var newTrack in newTrackList) { xaAnimationTrack animationNode = new xaAnimationTrack(); animationNodeList.Add(animationNode); animationNode.KeyframeList = new List <xaAnimationKeyframe>(newTrack.Value); animationNode.Name = newTrack.Key; xa.CreateUnknowns(animationNode); } } else if (replaceMethod == ReplaceAnimationMethod.ReplacePresent) { foreach (var newTrack in newTrackList) { xaAnimationTrack animationNode = xa.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, animationNodeList); animationNode.KeyframeList = new List <xaAnimationKeyframe>(newTrack.Value); } } else if (replaceMethod == ReplaceAnimationMethod.Merge) { foreach (var newTrack in newTrackList) { xaAnimationTrack animationNode; xaAnimationKeyframe[] origKeyframes = xa.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, animationNodeList, out animationNode); xaAnimationKeyframe[] destKeyframes; int newEnd = insertPos + newTrack.Value.Length; if (origKeyframes.Length < insertPos) { destKeyframes = new xaAnimationKeyframe[newEnd]; xa.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, origKeyframes.Length); xa.animationNormalizeTrack(origKeyframes, destKeyframes, insertPos); } else { if (origKeyframes.Length < newEnd) { destKeyframes = new xaAnimationKeyframe[newEnd]; } else { destKeyframes = new xaAnimationKeyframe[origKeyframes.Length]; xa.animationCopyKeyframeTransformArray(origKeyframes, newEnd, destKeyframes, newEnd, origKeyframes.Length - newEnd); } xa.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, insertPos); } xa.animationCopyKeyframeTransformArray(newTrack.Value, 0, destKeyframes, insertPos, newTrack.Value.Length); animationNode.KeyframeList = new List <xaAnimationKeyframe>(destKeyframes); } } else if (replaceMethod == ReplaceAnimationMethod.Insert) { foreach (var newTrack in newTrackList) { xaAnimationTrack animationNode; xaAnimationKeyframe[] origKeyframes = xa.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, animationNodeList, out animationNode);; xaAnimationKeyframe[] destKeyframes; int newEnd = insertPos + newTrack.Value.Length; if (origKeyframes.Length < insertPos) { destKeyframes = new xaAnimationKeyframe[newEnd]; xa.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, origKeyframes.Length); xa.animationNormalizeTrack(origKeyframes, destKeyframes, insertPos); } else { destKeyframes = new xaAnimationKeyframe[origKeyframes.Length + newTrack.Value.Length]; xa.animationCopyKeyframeTransformArray(origKeyframes, 0, destKeyframes, 0, insertPos); xa.animationCopyKeyframeTransformArray(origKeyframes, insertPos, destKeyframes, newEnd, origKeyframes.Length - insertPos); } xa.animationCopyKeyframeTransformArray(newTrack.Value, 0, destKeyframes, insertPos, newTrack.Value.Length); animationNode.KeyframeList = new List <xaAnimationKeyframe>(destKeyframes); } } else if (replaceMethod == ReplaceAnimationMethod.Append) { int maxKeyframes = 0; foreach (xaAnimationTrack animationNode in animationNodeList) { int numKeyframes = animationNode.KeyframeList[animationNode.KeyframeList.Count - 1].Index; if (numKeyframes > maxKeyframes) { maxKeyframes = numKeyframes; } } foreach (var newTrack in newTrackList) { xaAnimationTrack animationNode; xaAnimationKeyframe[] origKeyframes = xa.animationGetOriginalKeyframes(animationNodeDic, newTrack.Key, animationNodeList, out animationNode); xaAnimationKeyframe[] destKeyframes = new xaAnimationKeyframe[maxKeyframes + insertPos + newTrack.Value[newTrack.Value.Length - 1].Index + 1]; xa.animationCopyKeyframeTransformArray(origKeyframes, destKeyframes, 0); if (origKeyframes.Length > 0 && origKeyframes.Length == origKeyframes[origKeyframes.Length - 1].Index + 1) { xa.animationNormalizeTrack(origKeyframes, destKeyframes, origKeyframes.Length + insertPos); } xa.animationCopyKeyframeTransformArray(newTrack.Value, destKeyframes, maxKeyframes + insertPos); animationNode.KeyframeList = new List <xaAnimationKeyframe>(origKeyframes.Length + insertPos + newTrack.Value.Length); for (int i = 0; i < destKeyframes.Length; i++) { if (destKeyframes[i] == null) { continue; } animationNode.KeyframeList.Add(destKeyframes[i]); } } } else { Report.ReportLog("Error: Unexpected animation replace method " + replaceMethod + ". Skipping this animation"); return; } }
public static void CreateUnknowns(xaAnimationTrack track) { track.Unknown1 = new byte[4]; }