public static void LoadMatrix(Vector3 localScale, Quaternion localRotation, Vector3 localTranslation, DataGridView viewSRT, DataGridView viewMatrix) { if (viewSRT != null) { Vector3 rot = FbxUtility.QuaternionToEuler(localRotation); DataTable tableSRT = (DataTable)viewSRT.DataSource; for (int i = 0; i < 3; i++) { tableSRT.Rows[0][i + 1] = localTranslation[i]; tableSRT.Rows[1][i + 1] = rot[i]; tableSRT.Rows[2][i + 1] = localScale[i]; } } if (viewMatrix != null) { Matrix matrix = Matrix.Scaling(localScale) * Matrix.RotationQuaternion(localRotation) * Matrix.Translation(localTranslation); DataTable tableMatrix = (DataTable)viewMatrix.DataSource; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { tableMatrix.Rows[i][j] = matrix[i, j]; } } } }
public static void LoadMatrix(Matrix matrix, DataGridView viewSRT, DataGridView viewMatrix) { if (viewSRT != null) { Vector3[] srt = FbxUtility.MatrixToSRT(matrix); DataTable tableSRT = (DataTable)viewSRT.DataSource; for (int i = 0; i < 3; i++) { tableSRT.Rows[0][i + 1] = srt[2][i]; tableSRT.Rows[1][i + 1] = srt[1][i]; tableSRT.Rows[2][i + 1] = srt[0][i]; } } if (viewMatrix != null) { DataTable tableMatrix = (DataTable)viewMatrix.DataSource; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { tableMatrix.Rows[i][j] = matrix[i, j]; } } } }
public void SetBoneSRT(int meshId, int boneId, double sX, double sY, double sZ, double rX, double rY, double rZ, double tX, double tY, double tZ) { xxBone bone = Meshes[meshId].Mesh.BoneList[boneId]; bone.Matrix = FbxUtility.SRTToMatrix(new Vector3((float)sX, (float)sY, (float)sZ), new Vector3((float)rX, (float)rY, (float)rZ), new Vector3((float)tX, (float)tY, (float)tZ)); Changed = true; }
public static void dataGridViewSRT_CellValueChanged(object sender, DataGridViewCellEventArgs e) { DataGridView viewSRT = (DataGridView)sender; Vector3[] srt = GetSRT(viewSRT); Matrix mat = FbxUtility.SRTToMatrix(srt[0], srt[1], srt[2]); LoadMatrix(mat, null, (DataGridView)viewSRT.Tag); }
public static void GetSQT(DataGridView viewSRT, out Vector3 localScale, out Quaternion localRotation, out Vector3 localTranslation) { DataTable table = (DataTable)viewSRT.DataSource; Vector3[] srt = new Vector3[3]; for (int i = 0; i < 3; i++) { srt[0][i] = (float)table.Rows[2][i + 1]; srt[1][i] = (float)table.Rows[1][i + 1]; srt[2][i] = (float)table.Rows[0][i + 1]; } localTranslation = srt[2]; localRotation = FbxUtility.EulerToQuaternion(srt[1]); localScale = srt[0]; }
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 static void ReplaceAnimation(ReplaceAnimationMethod replaceMethod, int insertPos, List <KeyValuePair <string, ImportedAnimationKeyframe[]> > newTrackList, ImportedAnimation iAnim, Dictionary <string, ImportedAnimationTrack> animationNodeDic, bool negateQuaternionFlips) { if (replaceMethod == ReplaceAnimationMethod.Replace) { foreach (var newTrack in newTrackList) { ImportedAnimationTrack iTrack = new ImportedAnimationTrack(); iAnim.TrackList.Add(iTrack); iTrack.Name = newTrack.Key; iTrack.Keyframes = newTrack.Value; } } else if (replaceMethod == ReplaceAnimationMethod.Merge) { foreach (var newTrack in newTrackList) { ImportedAnimationTrack 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) { ImportedAnimationTrack 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) { ImportedAnimationTrack 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) { Quaternion lastQ = Quaternion.Identity; for (int i = 0, lastUsed_keyIndex = -1; i < newTrack.Keyframes.Length; i++) { ImportedAnimationKeyframe iKeyframe = newTrack.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; } } } }
public void SetFrameSRT(int id, double sX, double sY, double sZ, double rX, double rY, double rZ, double tX, double tY, double tZ) { Frames[id].Matrix = FbxUtility.SRTToMatrix(new Vector3((float)sX, (float)sY, (float)sZ), new Vector3((float)rX, (float)rY, (float)rZ), new Vector3((float)tX, (float)tY, (float)tZ)); }
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; } } } }