/// <summary> /// Converts the animations from the given imported data and creates /// them in the scene. /// </summary> /// <param name="scene">The scene to hold to converted animations</param> /// <param name="data">The data to read the animations from</param> protected void CreateAnimations(AssimpSharp.Scene scene, AssimpSharp.XFile.Scene data) { var newAnims = new List<AssimpSharp.Animation>(); for (int a = 0; a < data.Anims.Count; a++) { var anim = data.Anims[a]; if (anim.Anims.Count == 0) { continue; } var nanim = new AssimpSharp.Animation(); newAnims.Add(nanim); nanim.Name = anim.Name; nanim.Duration = 0; nanim.TicksPreSecond = data.AnimTicksPerSecond; nanim.Channels = new AssimpSharp.NodeAnim[anim.Anims.Count]; for (int b = 0; b < anim.Anims.Count; b++) { var bone = anim.Anims[b]; var nbone = new AssimpSharp.NodeAnim(); nbone.NodeName = bone.BoneName; nanim.Channels[b] = nbone; if (bone.TrafoKeys.Count > 0) { nbone.PositionKeys = new VectorKey[bone.TrafoKeys.Count]; nbone.RotationKeys = new QuatKey[bone.TrafoKeys.Count]; nbone.ScalingKeys = new VectorKey[bone.TrafoKeys.Count]; for (int c = 0; c < bone.TrafoKeys.Count; c++) { var time = bone.TrafoKeys[c].Key; var trafo = bone.TrafoKeys[c].Value; var pos = trafo.TranslationVector; nbone.PositionKeys[c].Time = time; nbone.PositionKeys[c].Value = pos; Vector3 scale; scale.X = new Vector3(trafo[0, 0], trafo[0, 1], trafo[0, 2]).Length(); scale.Y = new Vector3(trafo[1, 0], trafo[1, 1], trafo[1, 2]).Length(); scale.Z = new Vector3(trafo[2, 0], trafo[2, 1], trafo[2, 2]).Length(); nbone.ScalingKeys[c].Time = time; nbone.ScalingKeys[c].Value = scale; var rotmat = new Matrix3x3( trafo[0, 0] / scale.X, trafo[0, 1] / scale.Y, trafo[0, 2] / scale.Z, trafo[1, 0] / scale.X, trafo[1, 1] / scale.Y, trafo[1, 2] / scale.Z, trafo[2, 0] / scale.X, trafo[2, 1] / scale.Y, trafo[2, 2] / scale.Z); nbone.RotationKeys[c].Time = time; throw (new NotImplementedException()); //nbone.RotationKeys[c].Value = ; } nanim.Duration = Math.Max(nanim.Duration, bone.TrafoKeys[bone.TrafoKeys.Count].Key); } else { // separate key sequences for position, rotation, scaling nbone.PositionKeys = new VectorKey[bone.PosKeys.Count]; for (int c = 0; c < nbone.PositionKeys.Length; c++) { var pos = bone.PosKeys[c].Value; nbone.PositionKeys[c].Time = bone.PosKeys[c].Time; nbone.PositionKeys[c].Value = pos; } // rotation nbone.RotationKeys = new QuatKey[bone.RotKeys.Count]; for (int c = 0; c < nbone.RotationKeys.Length; c++) { var rotmat = Matrix3x3.RotationQuaternion(bone.RotKeys[c].Value); nbone.RotationKeys[c].Time = bone.RotKeys[c].Time; Quaternion.RotationMatrix(ref rotmat, out nbone.RotationKeys[c].Value); nbone.RotationKeys[c].Value.W *= -1.0f; } // longest lasting key sequence determines duration nbone.ScalingKeys = new VectorKey[bone.ScaleKeys.Count]; for (int c = 0; c < nbone.ScalingKeys.Length; c++) { nbone.ScalingKeys[c] = bone.ScaleKeys[c]; } // longest lasting key sequence determines duration if (bone.PosKeys.Count > 0) { nanim.Duration = Math.Max(nanim.Duration, bone.PosKeys[bone.PosKeys.Count - 1].Time); } if (bone.RotKeys.Count > 0) { nanim.Duration = Math.Max(nanim.Duration, bone.RotKeys[bone.RotKeys.Count - 1].Time); } if (bone.ScaleKeys.Count > 0) { nanim.Duration = Math.Max(nanim.Duration, bone.ScaleKeys[bone.ScaleKeys.Count - 1].Time); } } } } // store all converted animations in the scene if (newAnims.Count > 0) { scene.Animations.Clear(); scene.Animations.AddRange(newAnims); } }
private AssimpSharp.NodeAnim GenerateTranslationNodeAnim(string name, Model target, List<AnimationCurveNode> curves, LayerMap layerMap, long start, long stop, double maxTime, double minTime, bool inverse = false) { var na = new AssimpSharp.NodeAnim(); na.NodeName = name; ConvertRotationKeys(na, curves, layerMap, start, stop, ref maxTime, ref minTime, target.RotationOrder.Value); if (inverse) { for (int i = 0; i < na.PositionKeys.Length; i++) { na.PositionKeys[i].Value *= -1.0f; } } // dummy scaling key na.ScalingKeys = new AssimpSharp.VectorKey[1]; na.ScalingKeys[0].Time = 0; na.ScalingKeys[0].Value = new Vector3(1, 1, 1); // dummy rotation key na.RotationKeys = new AssimpSharp.QuatKey[1]; na.RotationKeys[0].Time = 0; na.RotationKeys[0].Value = Quaternion.Identity; return na; }
private AssimpSharp.NodeAnim GenerateScalingNodeAnim(string name, Model target, List<AnimationCurveNode> curves, LayerMap layerMap, long start, long stop, double maxTime, double minTime) { var na = new AssimpSharp.NodeAnim(); na.NodeName = name; ConvertScaleKeys(na, curves, layerMap, start, stop, ref maxTime, ref minTime); // dummy rotation key na.RotationKeys = new AssimpSharp.QuatKey[1]; na.RotationKeys[0] = new AssimpSharp.QuatKey(0, new Quaternion()); // dummy position key na.PositionKeys = new AssimpSharp.VectorKey[1]; na.PositionKeys[0] = new AssimpSharp.VectorKey(0, new Vector3()); return na; }
/// <summary> /// generate node anim, extracting only Rotation, Scaling and Translation from the given chain /// </summary> private AssimpSharp.NodeAnim GenerateSimpleNodeAnim(string name, Model target, List<AnimationCurveNode>[] chain, LayerMap layerMap, long start, long stop, ref double maxTime, ref double minTime, bool reverseOrder = false) { var na = new AssimpSharp.NodeAnim(); na.NodeName = name; var props = target.Props; // need to convert from TRS order to SRT? if (reverseOrder) { var defScale = Vector3.Zero; var defTranslate = Vector3.Zero; var defRot = Quaternion.Identity; var scaling = new KeyFrameListList(); var translation = new KeyFrameListList(); var rotation = new KeyFrameListList(); if (chain[(int)TransformationComp.Scaling] != null) { scaling = GetKeyframeList(chain[(int)TransformationComp.Scaling], start, stop); } else { defScale = PropertyHelper.PropertyGet(props, "Lcl Scaling", new Vector3(1, 1, 1)); } if (chain[(int)TransformationComp.Translation] != null) { translation = GetKeyframeList(chain[(int)TransformationComp.Translation], start, stop); } else { defTranslate = PropertyHelper.PropertyGet(props, "Lcl Translation", new Vector3(0, 0, 0)); } if (chain[(int)TransformationComp.Rotation] != null) { rotation = GetKeyframeList(chain[(int)TransformationComp.Rotation], start, stop); } else { defRot = EulerToQuaternion(PropertyHelper.PropertyGet(props, "Lcl Rotation", new Vector3(0, 0, 0)), target.RotationOrder.Value); } var joined = new KeyFrameListList(); joined.AddRange(scaling); joined.AddRange(translation); joined.AddRange(rotation); var times = GetKeyTimeList(joined); var outQuat = new AssimpSharp.QuatKey[times.Count]; var outScale = new AssimpSharp.VectorKey[times.Count]; var outTranslation = new AssimpSharp.VectorKey[times.Count]; if (times.Count > 0) { ConvertTransformOrder_TRStoSRT(outQuat, outScale, outTranslation, scaling, translation, rotation, times, ref maxTime, ref minTime, target.RotationOrder.Value, defScale, defTranslate, defRot); } // XXX remove duplicates / redundant keys which this operation did // likely produce if not all three channels were equally dense. na.ScalingKeys = outScale; na.RotationKeys = outQuat; na.PositionKeys = outTranslation; } else { // if a particular transformation is not given, grab it from // the corresponding node to meet the semantics of aiNodeAnim, // which requires all of rotation, scaling and translation // to be set. if (chain[(int)TransformationComp.Scaling] != null) { ConvertScaleKeys(na, chain[(int)TransformationComp.Scaling], layerMap, start, stop, ref maxTime, ref minTime); } else { na.ScalingKeys = new AssimpSharp.VectorKey[1]; na.ScalingKeys[0].Time = 0; na.ScalingKeys[0].Value = PropertyHelper.PropertyGet(props, "Lcl Scaling", new Vector3(1, 1, 1)); } if (chain[(int)TransformationComp.Rotation] != null) { ConvertRotationKeys(na, chain[(int)TransformationComp.Rotation], layerMap, start, stop, ref maxTime, ref minTime, target.RotationOrder.Value); } else { na.RotationKeys = new AssimpSharp.QuatKey[1]; na.RotationKeys[0].Time = 0; na.RotationKeys[0].Value = EulerToQuaternion(PropertyHelper.PropertyGet(props, "Lcl Rotation", new Vector3(0, 0, 0)), target.RotationOrder.Value); } if (chain[(int)TransformationComp.Translation] != null) { ConvertTranslationKeys(na, chain[(int)TransformationComp.Translation], layerMap, start, stop, ref maxTime, ref minTime); } else { na.PositionKeys = new AssimpSharp.VectorKey[1]; na.PositionKeys[0].Time = 0; na.PositionKeys[0].Value = PropertyHelper.PropertyGet(props, "Lcl Translation", new Vector3(0, 0, 0)); } } return na; }
private AssimpSharp.NodeAnim GenerateRotationNodeAnim(string name, Model target, List<AnimationCurveNode> curves, LayerMap layerMap, long start, long stop, ref double maxTime, ref double minTime) { var na = new AssimpSharp.NodeAnim(); na.NodeName = name; ConvertRotationKeys(na, curves, layerMap, start, stop, ref maxTime, ref minTime, target.RotationOrder.Value); // dummy scaling key na.ScalingKeys = new AssimpSharp.VectorKey[1]; na.ScalingKeys[0].Time = 0; na.ScalingKeys[0].Value = new Vector3(1.0f, 1.0f, 1.0f); // dummy position key na.PositionKeys = new AssimpSharp.VectorKey[1]; na.PositionKeys[0].Time = 0; na.PositionKeys[0].Value = new Vector3(); return na; }