Пример #1
0
        /// <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);
            }
        }
Пример #2
0
        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;
        }
Пример #3
0
        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;
        }
Пример #4
0
        /// <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;
        }
Пример #5
0
        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;
        }