Пример #1
0
        public static string ToStringTrimed(this Assimp.Quaternion q)
        {
            string d    = "+0.000;-0.000"; // "0.00";
            int    pamt = 8;

            return(q.X.ToString(d).PadRight(pamt) + ", " + q.Y.ToString(d).PadRight(pamt) + ", " + q.Z.ToString(d).PadRight(pamt) + "w " + q.W.ToString(d).PadRight(pamt));
        }
Пример #2
0
        private Matrix4 CalcInterpolatedRotation(float animationTime, NodeAnimation channel)
        {
            Matrix4x4 matrix;

            if (channel.ScalingKeysCount == 1)
            {
                matrix = channel.RotationKeys[0].Value.GetMatrix();
            }

            var rotateIndex     = FindRotation(animationTime, channel);
            var nextRotateIndex = rotateIndex + 1;

            if (nextRotateIndex < channel.RotationKeysCount)
            {
                var rotateKey     = channel.RotationKeys[rotateIndex];
                var nextRotateKey = channel.RotationKeys[nextRotateIndex];
                var deltaTime     = nextRotateKey.Time - rotateKey.Time;
                var factor        = (animationTime - rotateKey.Time) / deltaTime;
                matrix = Quaternion.Slerp(rotateKey.Value, nextRotateKey.Value, factor).GetMatrix();
            }
            else
            {
                matrix = channel.RotationKeys[0].Value.GetMatrix();
            }
            return(FromMatrix(matrix));
        }
Пример #3
0
        static System.Numerics.Quaternion ConvertQuat(Assimp.Quaternion Q)
        {
            NumMatrix4x4.Decompose(ConvertMatrix(new AssMatrix4x4(Q.GetMatrix())), out Vector3 _S, out System.Numerics.Quaternion Quat, out Vector3 _T);
            return(Quat);

            // return new System.Numerics.Quaternion(Q.X, Q.Y, Q.Z, Q.W);
        }
Пример #4
0
        Assimp.Quaternion nlerp(Assimp.Quaternion a, Assimp.Quaternion b, float blend)
        {
            //cout << a.w + a.x + a.y + a.z << endl;
            a.Normalize();
            b.Normalize();

            Assimp.Quaternion result;
            float             dot_product     = a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W;
            float             one_minus_blend = 1.0f - blend;

            if (dot_product < 0.0f)
            {
                result.X = a.X * one_minus_blend + blend * -b.X;
                result.Y = a.Y * one_minus_blend + blend * -b.Y;
                result.Z = a.Z * one_minus_blend + blend * -b.Z;
                result.W = a.W * one_minus_blend + blend * -b.W;
            }
            else
            {
                result.X = a.X * one_minus_blend + blend * b.X;
                result.Y = a.Y * one_minus_blend + blend * b.Y;
                result.Z = a.Z * one_minus_blend + blend * b.Z;
                result.W = a.W * one_minus_blend + blend * b.W;
            }
            result.Normalize();
            return(result);
        }
        private static Vector3 ToEulerAngles(Assimp.Quaternion q)
        {
            Vector3 angles;

            double sinr_cosp = 2 * (q.W * q.X + q.Y * q.Z);
            double cosr_cosp = 1 - 2 * (q.X * q.X + q.Y * q.Y);

            angles.X = (float)Math.Atan2(sinr_cosp, cosr_cosp);

            double sinp = 2 * (q.W * q.Y - q.Z * q.X);

            if (Math.Abs(sinp) >= 1)
            {
                angles.Y = (float)(Math.Sign(sinp) * Math.PI / 2);
            }
            else
            {
                angles.Y = (float)Math.Asin(sinp);
            }

            double siny_cosp = 2 * (q.W * q.Z + q.X * q.Y);
            double cosy_cosp = 1 - 2 * (q.Y * q.Y + q.Z * q.Z);

            angles.Z = (float)Math.Atan2(siny_cosp, cosy_cosp);

            return(angles);
        }
        private aiMatrix4x4 InterpolateRotation(double time, NodeAnimationChannel channel)
        {
            aiQuaternion rotation;

            if (channel.RotationKeyCount == 1)
            {
                rotation = channel.RotationKeys[0].Value;
            }
            else
            {
                uint frameIndex = 0;
                for (uint i = 0; i < channel.RotationKeyCount - 1; i++)
                {
                    if (time < (float)channel.RotationKeys[(int)(i + 1)].Time)
                    {
                        frameIndex = i;
                        break;
                    }
                }

                QuaternionKey currentFrame = channel.RotationKeys[(int)frameIndex];
                QuaternionKey nextFrame    = channel.RotationKeys[(int)((frameIndex + 1) % channel.RotationKeyCount)];

                double delta = (time - (float)currentFrame.Time) / (float)(nextFrame.Time - currentFrame.Time);

                aiQuaternion start = currentFrame.Value;
                aiQuaternion end   = nextFrame.Value;
                rotation = aiQuaternion.Slerp(start, end, (float)delta);
                rotation.Normalize();
            }

            return(rotation.GetMatrix());
        }
Пример #7
0
        public static Vector3D FromQ2(Assimp.Quaternion q1)
        {
            float    sqw  = q1.W * q1.W;
            float    sqx  = q1.X * q1.X;
            float    sqy  = q1.Y * q1.Y;
            float    sqz  = q1.Z * q1.Z;
            float    unit = sqx + sqy + sqz + sqw;          // if normalised is one, otherwise is correction factor
            float    test = q1.X * q1.W - q1.Y * q1.Z;
            Vector3D v;

            if (test > 0.4995f * unit)
            {             // singularity at north pole
                v.Y = 2f * (float)Math.Atan2(q1.Y, q1.X);
                v.X = (float)Math.PI / 2;
                v.Z = 0;
                return(NormalizeAngles(v * (float)(180 / Math.PI)));
            }
            if (test < -0.4995f * unit)
            {             // singularity at south pole
                v.Y = -2f * (float)Math.Atan2(q1.Y, q1.X);
                v.X = -(float)Math.PI / 2;
                v.Z = 0;
                return(NormalizeAngles(v * (float)(180 / Math.PI)));
            }
            Quaternion q = new Assimp.Quaternion(q1.W, q1.Z, q1.X, q1.Y);

            v.Y = (float)Math.Atan2(2f * q.X * q.W + 2f * q.Y * q.Z, 1 - 2f * (q.Z * q.Z + q.W * q.W));   // Yaw
            v.X = (float)Math.Asin(2f * (q.X * q.Z - q.W * q.Y));                                         // Pitch
            v.Z = (float)Math.Atan2(2f * q.X * q.Y + 2f * q.Z * q.W, 1 - 2f * (q.Y * q.Y + q.Z * q.Z));   // Roll
            return(NormalizeAngles(v * (float)(180 / Math.PI)));
        }
Пример #8
0
        // quat4 -> (roll, pitch, yaw)
        private static void QuatToEulerXyz(ref Quaternion q1, out Vector3 outVector)
        {
            // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
            double sqw  = q1.W * q1.W;
            double sqx  = q1.X * q1.X;
            double sqy  = q1.Y * q1.Y;
            double sqz  = q1.Z * q1.Z;
            double unit = sqx + sqy + sqz + sqw;     // if normalised is one, otherwise is correction factor
            double test = q1.X * q1.Y + q1.Z * q1.W;

            if (test > 0.499 * unit)     // singularity at north pole
            {
                outVector.Z = (float)(2 * Math.Atan2(q1.X, q1.W));
                outVector.Y = (float)(Math.PI / 2);
                outVector.X = 0;
                return;
            }
            if (test < -0.499 * unit)     // singularity at south pole
            {
                outVector.Z = (float)(-2 * Math.Atan2(q1.X, q1.W));
                outVector.Y = (float)(-Math.PI / 2);
                outVector.X = 0;
                return;
            }
            outVector.Z = (float)Math.Atan2(2 * q1.Y * q1.W - 2 * q1.X * q1.Z, sqx - sqy - sqz + sqw);
            outVector.Y = (float)Math.Asin(2 * test / unit);
            outVector.X = (float)Math.Atan2(2 * q1.X * q1.W - 2 * q1.Y * q1.Z, -sqx + sqy - sqz + sqw);
        }
Пример #9
0
        // T O   M G  (convert for use with MonoGame) - QUATERNION
        public static XNA.Quaternion ToMg(this Assimp.Quaternion aq)
        {
            var m = aq.GetMatrix();
            var n = m.ToMgTransposed();
            var q = XNA.Quaternion.CreateFromRotationMatrix(n);

            return(q);
        }
Пример #10
0
 private OpenTK.Quaternion TKQuaternion(Assimp.Quaternion rot)
 {
     OpenTK.Quaternion quat = new OpenTK.Quaternion();
     quat.X = rot.X;
     quat.Y = rot.Y;
     quat.Z = rot.Z;
     quat.W = rot.W;
     return quat;
 }
Пример #11
0
 public static OpenTK.Quaternion TKQuaternion(Assimp.Quaternion rot)
 {
     OpenTK.Quaternion quat = new OpenTK.Quaternion();
     quat.X = rot.X;
     quat.Y = rot.Y;
     quat.Z = rot.Z;
     quat.W = rot.W;
     return(quat);
 }
Пример #12
0
 public static Assimp.Quaternion ToQuaternion(this SlimDX.Quaternion q)
 {
     Assimp.Quaternion ret = new Assimp.Quaternion();
     ret.W = q.W;
     ret.X = q.X;
     ret.Y = q.Y;
     ret.Z = q.Z;
     return(ret);
 }
Пример #13
0
 public static Assimp.Quaternion convertQuaternion(OpenTK.Quaternion localQuat)
 {
     Assimp.Quaternion q = new Assimp.Quaternion();
     q.X = localQuat.X;
     q.Y = localQuat.Y;
     q.Z = localQuat.Z;
     q.W = localQuat.W;
     return(q);
 }
Пример #14
0
        Matrix GetMatrix(Vector3D pscale, Vector3D pPosition, Assimp.Quaternion pRot)
        {
            // create the combined transformation matrix
            var mat = new Matrix4x4(pRot.GetMatrix());

            mat.A1 *= pscale.X; mat.B1 *= pscale.X; mat.C1 *= pscale.X;
            mat.A2 *= pscale.Y; mat.B2 *= pscale.Y; mat.C2 *= pscale.Y;
            mat.A3 *= pscale.Z; mat.B3 *= pscale.Z; mat.C3 *= pscale.Z;
            mat.A4  = pPosition.X; mat.B4 = pPosition.Y; mat.C4 = pPosition.Z;
            return(mat.ToMatrix());
        }
Пример #15
0
        IEnumerable <Frame> GetFrames(NodeAnimationChannel nch)
        {
            var m = new[] { nch.PositionKeyCount, nch.RotationKeyCount, nch.ScalingKeyCount }.Max();

            for (int i = 0; i < m; i++)
            {
                var pos   = new Vector3D();
                var scale = new Vector3D(1);
                var rot   = new Assimp.Quaternion(1, 0, 0, 0);
                if (nch.HasPositionKeys)
                {
                    if (i < nch.PositionKeyCount)
                    {
                        pos = nch.PositionKeys[i].Value;
                    }
                    else
                    {
                        pos = nch.PositionKeys.Last().Value;
                    }
                }
                if (nch.HasRotationKeys)
                {
                    if (i < nch.RotationKeyCount)
                    {
                        rot = nch.RotationKeys[i].Value;
                    }
                    else
                    {
                        rot = nch.RotationKeys.Last().Value;
                    }
                }
                if (nch.HasScalingKeys)
                {
                    if (i < nch.ScalingKeyCount)
                    {
                        scale = nch.ScalingKeys[i].Value;
                    }
                    else
                    {
                        scale = nch.ScalingKeys.Last().Value;
                    }
                }

                yield return(new Frame()
                {
                    pos = pos,
                    rot = rot,
                    scal = scale
                });
            }
            yield break;
        }
Пример #16
0
        public Assimp.Vector3D GetAssimpPoint()
        {
            Matrix4x4 pos = converter.Matrix3DToAssimpMatrix4x4(Matrix[Session.CurrentSession.CurrentProject.CurrentModel3D.Animation.Tick]);

            Assimp.Vector3D translation = new Assimp.Vector3D();
            Assimp.Quaternion rot = new Assimp.Quaternion();

            // Get the Absolute positions

            pos.DecomposeNoScaling(out rot, out translation);

            // TODO : Get back to relative position
            
            return translation / delta[Session.CurrentSession.CurrentProject.CurrentModel3D.Animation.Tick];
        }
Пример #17
0
        /// <summary>
        /// Build a transformation matrix from rotation, scaling and translation components.
        /// The transformation order is scaling, rotation, translation (left to right).
        /// </summary>
        /// <param name="presentRotation"></param>
        /// <param name="presentScaling"></param>
        /// <param name="presentPosition"></param>
        /// <param name="outMatrix"></param>
        private static void BuildTransform(ref Quaternion presentRotation, ref Vector3D presentScaling,
                                           ref Vector3D presentPosition, out Matrix outMatrix)
        {
            // build a transformation matrix from it
            var mat = new Matrix4x4(presentRotation.GetMatrix());

            mat.A1 *= presentScaling.X;
            mat.B1 *= presentScaling.X;
            mat.C1 *= presentScaling.X;
            mat.A2 *= presentScaling.Y;
            mat.B2 *= presentScaling.Y;
            mat.C2 *= presentScaling.Y;
            mat.A3 *= presentScaling.Z;
            mat.B3 *= presentScaling.Z;
            mat.C3 *= presentScaling.Z;
            mat.A4  = presentPosition.X;
            mat.B4  = presentPosition.Y;
            mat.C4  = presentPosition.Z;

            outMatrix = AssimpConv.ConvertTransform(mat);
        }
Пример #18
0
        public static Vector3 ToEulerAngles(Assimp.Quaternion q)
        {
            float PI = (float)Math.PI;
            // Store the Euler angles in radians
            Vector3 pitchYawRoll = new Vector3();

            double sqw = q.W * q.W;
            double sqx = q.X * q.X;
            double sqy = q.Y * q.Y;
            double sqz = q.Z * q.Z;

            // If quaternion is normalised the unit is one, otherwise it is the correction factor
            double unit = sqx + sqy + sqz + sqw;
            double test = q.X * q.Y + q.Z * q.W;

            if (test > 0.499f * unit)
            {
                // Singularity at north pole
                pitchYawRoll.Y = 2f * (float)Math.Atan2(q.X, q.W);  // Yaw
                pitchYawRoll.X = PI * 0.5f;                         // Pitch
                pitchYawRoll.Z = 0f;                                // Roll
                return(pitchYawRoll);
            }
            else if (test < -0.499f * unit)
            {
                // Singularity at south pole
                pitchYawRoll.Y = -2f * (float)Math.Atan2(q.X, q.W); // Yaw
                pitchYawRoll.X = -PI * 0.5f;                        // Pitch
                pitchYawRoll.Z = 0f;                                // Roll
                return(pitchYawRoll);
            }
            pitchYawRoll.Y = (float)Math.Atan2(2 * q.Y * q.W - 2 * q.X * q.Z, sqx - sqy - sqz + sqw);       // Yaw
            pitchYawRoll.X = (float)Math.Asin(2 * test / unit);                                             // Pitch
            pitchYawRoll.Z = (float)Math.Atan2(2 * q.X * q.W - 2 * q.Y * q.Z, -sqx + sqy - sqz + sqw);      // Roll
            return(pitchYawRoll);
        }
Пример #19
0
 public static Quaternion ToXna(Assimp.Quaternion quaternion)
 {
     return(new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W));
 }
Пример #20
0
        private void UpdateUi(Matrix4x4 mat, bool diffAgainstBaseMatrix)
        {
            // use assimp math data structures because they have Decompose()
   
            // the decomposition algorithm is not very sophisticated - it basically extracts translation
            // and row scaling factors and then converts the rest to a quaternion. 
            // question: what if the matrix is non-invertible? the algorithm then yields
            // at least one scaling factor as zero, further results are undefined. We
            // therefore catch this case by checking the determinant and inform the user
            // that the results may be wrong.
            checkBoxNonStandard.Checked = Math.Abs(mat.Determinant()) < 1e-5;

            Vector3D scale;
            Quaternion rot;
            Vector3D trans;

            mat.Decompose(out scale, out rot, out trans);

            // translation
            textBoxTransX.Text = trans.X.ToString(Format);
            textBoxTransY.Text = trans.Y.ToString(Format);
            textBoxTransZ.Text = trans.Z.ToString(Format);

            // scaling - simpler view mode for uniform scalings
            var isUniform = Math.Abs(scale.X - scale.Y) < 1e-5 && Math.Abs(scale.X - scale.Z) < 1e-5;
            textBoxScaleX.Text = scale.X.ToString(Format);
            textBoxScaleY.Text = scale.Y.ToString(Format);
            textBoxScaleZ.Text = scale.Z.ToString(Format);

            textBoxScaleY.Visible = !isUniform;
            textBoxScaleZ.Visible = !isUniform;
            labelScalingX.Visible = !isUniform;
            labelScalingY.Visible = !isUniform;
            labelScalingZ.Visible = !isUniform;

            if (diffAgainstBaseMatrix)
            {
                const double epsilon = 1e-5f;
                if (Math.Abs(scale.X-_scale.X) > epsilon)
                {
                    labelScalingX.ForeColor = ColorIsAnimated;
                    textBoxScaleX.ForeColor = ColorIsAnimated;
                }

                if (Math.Abs(scale.Y - _scale.Y) > epsilon)
                {
                    labelScalingY.ForeColor = ColorIsAnimated;
                    textBoxScaleY.ForeColor = ColorIsAnimated;
                }

                if (Math.Abs(scale.Z - _scale.Z) > epsilon)
                {
                    labelScalingZ.ForeColor = ColorIsAnimated;
                    textBoxScaleZ.ForeColor = ColorIsAnimated;
                }

                if (Math.Abs(trans.X - _trans.X) > epsilon)
                {
                    labelTranslationX.ForeColor = ColorIsAnimated;
                    textBoxTransX.ForeColor = ColorIsAnimated;
                }

                if (Math.Abs(trans.Y - _trans.Y) > epsilon)
                {
                    labelTranslationY.ForeColor = ColorIsAnimated;
                    textBoxTransY.ForeColor = ColorIsAnimated;
                }

                if (Math.Abs(trans.Z - _trans.Z) > epsilon)
                {
                    labelTranslationZ.ForeColor = ColorIsAnimated;
                    textBoxTransZ.ForeColor = ColorIsAnimated;
                }
            }
            else
            {
                labelScalingX.ForeColor = ColorNotAnimated;
                textBoxScaleX.ForeColor = ColorNotAnimated;

                labelScalingY.ForeColor = ColorNotAnimated;
                textBoxScaleY.ForeColor = ColorNotAnimated;

                labelScalingZ.ForeColor = ColorNotAnimated;
                textBoxScaleZ.ForeColor = ColorNotAnimated;

                labelTranslationX.ForeColor = ColorNotAnimated;
                textBoxTransX.ForeColor = ColorNotAnimated;

                labelTranslationY.ForeColor = ColorNotAnimated;
                textBoxTransY.ForeColor = ColorNotAnimated;

                labelTranslationZ.ForeColor = ColorNotAnimated;
                textBoxTransZ.ForeColor = ColorNotAnimated;

                _scale = scale;
                _trans = trans;
                _rot = rot;
            }

            // rotation - more complicated because the display mode can be changed 
            _rotCurrent = rot;
            SetRotation(diffAgainstBaseMatrix);
        }
        public void Evaluate(float dt, Dictionary<string, Bone> bones) {
            dt *= TicksPerSecond;
            var time = 0.0f;
            if (Duration > 0.0f) {
                time = dt % Duration;
            }
            for (int i = 0; i < Channels.Count; i++) {
                var channel = Channels[i];
                if (!bones.ContainsKey(channel.Name)) {
                    Console.WriteLine("Did not find the bone node " + channel.Name);
                    continue;
                }
                // interpolate position keyframes
                var pPosition = new Vector3D();
                if (channel.PositionKeys.Count > 0) {
                    var frame = (time >= LastTime) ? LastPositions[i].Item1 : 0;
                    while (frame < channel.PositionKeys.Count - 1) {
                        if (time < channel.PositionKeys[frame + 1].Time) {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.PositionKeys.Count) {
                        frame = 0;
                    }

                    var nextFrame = (frame + 1) % channel.PositionKeys.Count;

                    var key = channel.PositionKeys[frame];
                    var nextKey = channel.PositionKeys[nextFrame];
                    var diffTime = nextKey.Time - key.Time;
                    if (diffTime < 0.0) {
                        diffTime += Duration;
                    }
                    if (diffTime > 0.0) {
                        var factor = (float)((time - key.Time) / diffTime);
                        pPosition = key.Value + (nextKey.Value - key.Value) * factor;
                    } else {
                        pPosition = key.Value;
                    }
                    LastPositions[i].Item1 = frame;

                }
                // interpolate rotation keyframes
                var pRot = new Assimp.Quaternion(1, 0, 0, 0);
                if (channel.RotationKeys.Count > 0) {
                    var frame = (time >= LastTime) ? LastPositions[i].Item2 : 0;
                    while (frame < channel.RotationKeys.Count - 1) {
                        if (time < channel.RotationKeys[frame + 1].Time) {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.RotationKeys.Count) {
                        frame = 0;
                    }
                    var nextFrame = (frame + 1) % channel.RotationKeys.Count;

                    var key = channel.RotationKeys[frame];
                    var nextKey = channel.RotationKeys[nextFrame];
                    key.Value.Normalize();
                    nextKey.Value.Normalize();
                    var diffTime = nextKey.Time - key.Time;
                    if (diffTime < 0.0) {
                        diffTime += Duration;
                    }
                    if (diffTime > 0) {
                        var factor = (float)((time - key.Time) / diffTime);
                        pRot = Assimp.Quaternion.Slerp(key.Value, nextKey.Value, factor);
                    } else {
                        pRot = key.Value;
                    }
                    LastPositions[i].Item1= frame;

                }
                // interpolate scale keyframes
                var pscale = new Vector3D(1);
                if (channel.ScalingKeys.Count > 0) {
                    var frame = (time >= LastTime) ? LastPositions[i].Item3 : 0;
                    while (frame < channel.ScalingKeys.Count - 1) {
                        if (time < channel.ScalingKeys[frame + 1].Time) {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.ScalingKeys.Count) {
                        frame = 0;
                    }
                    LastPositions[i].Item3 = frame;
                }

                // create the combined transformation matrix
                var mat = new Matrix4x4(pRot.GetMatrix());
                mat.A1 *= pscale.X; mat.B1 *= pscale.X; mat.C1 *= pscale.X;
                mat.A2 *= pscale.Y; mat.B2 *= pscale.Y; mat.C2 *= pscale.Y;
                mat.A3 *= pscale.Z; mat.B3 *= pscale.Z; mat.C3 *= pscale.Z;
                mat.A4 = pPosition.X; mat.B4 = pPosition.Y; mat.C4 = pPosition.Z;

                // transpose to get DirectX style matrix
                mat.Transpose();
                bones[channel.Name].LocalTransform = mat.ToMatrix();
            }
            LastTime = time;
        }
Пример #22
0
 private static Quaternion ConvertQuaternion(Assimp.Quaternion value)
 {
     // Assimp quaternions are stored in wxyz order
     return(new Quaternion(value.X, value.Y, value.Z, value.W));
 }
Пример #23
0
        private void UpdateUi(Matrix4x4 mat, bool diffAgainstBaseMatrix)
        {
            // use assimp math data structures because they have Decompose()

            // the decomposition algorithm is not very sophisticated - it basically extracts translation
            // and row scaling factors and then converts the rest to a quaternion.
            // question: what if the matrix is non-invertible? the algorithm then yields
            // at least one scaling factor as zero, further results are undefined. We
            // therefore catch this case by checking the determinant and inform the user
            // that the results may be wrong.
            checkBoxNonStandard.Checked = Math.Abs(mat.Determinant()) < 1e-5;

            Vector3D   scale;
            Quaternion rot;
            Vector3D   trans;

            mat.Decompose(out scale, out rot, out trans);

            // translation
            textBoxTransX.Text = trans.X.ToString(Format);
            textBoxTransY.Text = trans.Y.ToString(Format);
            textBoxTransZ.Text = trans.Z.ToString(Format);

            // scaling - simpler view mode for uniform scalings
            var isUniform = Math.Abs(scale.X - scale.Y) < 1e-5 && Math.Abs(scale.X - scale.Z) < 1e-5;

            textBoxScaleX.Text = scale.X.ToString(Format);
            textBoxScaleY.Text = scale.Y.ToString(Format);
            textBoxScaleZ.Text = scale.Z.ToString(Format);

            textBoxScaleY.Visible = !isUniform;
            textBoxScaleZ.Visible = !isUniform;
            labelScalingX.Visible = !isUniform;
            labelScalingY.Visible = !isUniform;
            labelScalingZ.Visible = !isUniform;

            if (diffAgainstBaseMatrix)
            {
                const double epsilon = 1e-5f;
                if (Math.Abs(scale.X - _scale.X) > epsilon)
                {
                    labelScalingX.ForeColor = ColorIsAnimated;
                    textBoxScaleX.ForeColor = ColorIsAnimated;
                }

                if (Math.Abs(scale.Y - _scale.Y) > epsilon)
                {
                    labelScalingY.ForeColor = ColorIsAnimated;
                    textBoxScaleY.ForeColor = ColorIsAnimated;
                }

                if (Math.Abs(scale.Z - _scale.Z) > epsilon)
                {
                    labelScalingZ.ForeColor = ColorIsAnimated;
                    textBoxScaleZ.ForeColor = ColorIsAnimated;
                }

                if (Math.Abs(trans.X - _trans.X) > epsilon)
                {
                    labelTranslationX.ForeColor = ColorIsAnimated;
                    textBoxTransX.ForeColor     = ColorIsAnimated;
                }

                if (Math.Abs(trans.Y - _trans.Y) > epsilon)
                {
                    labelTranslationY.ForeColor = ColorIsAnimated;
                    textBoxTransY.ForeColor     = ColorIsAnimated;
                }

                if (Math.Abs(trans.Z - _trans.Z) > epsilon)
                {
                    labelTranslationZ.ForeColor = ColorIsAnimated;
                    textBoxTransZ.ForeColor     = ColorIsAnimated;
                }
            }
            else
            {
                labelScalingX.ForeColor = ColorNotAnimated;
                textBoxScaleX.ForeColor = ColorNotAnimated;

                labelScalingY.ForeColor = ColorNotAnimated;
                textBoxScaleY.ForeColor = ColorNotAnimated;

                labelScalingZ.ForeColor = ColorNotAnimated;
                textBoxScaleZ.ForeColor = ColorNotAnimated;

                labelTranslationX.ForeColor = ColorNotAnimated;
                textBoxTransX.ForeColor     = ColorNotAnimated;

                labelTranslationY.ForeColor = ColorNotAnimated;
                textBoxTransY.ForeColor     = ColorNotAnimated;

                labelTranslationZ.ForeColor = ColorNotAnimated;
                textBoxTransZ.ForeColor     = ColorNotAnimated;

                _scale = scale;
                _trans = trans;
                _rot   = rot;
            }

            // rotation - more complicated because the display mode can be changed
            _rotCurrent = rot;
            SetRotation(diffAgainstBaseMatrix);
        }
Пример #24
0
        private static void AddRotationAtKeyframe(List <QuaternionKey> Keys, int keyframe, Assimp.Quaternion value, double framerate = 30.0)
        {
            double frametick    = 1.0 / framerate;
            double keyframeTime = frametick * keyframe;

            Keys.Add(new QuaternionKey(keyframeTime, value));
        }
Пример #25
0
        /// <summary>
        /// Build a transformation matrix from rotation, scaling and translation components.
        /// The transformation order is scaling, rotation, translation (left to right).
        /// </summary>
        /// <param name="presentRotation"></param>
        /// <param name="presentScaling"></param>
        /// <param name="presentPosition"></param>
        /// <param name="outMatrix"></param>
        private static void BuildTransform(ref Quaternion presentRotation, ref Vector3D presentScaling, 
            ref Vector3D presentPosition, out Matrix4 outMatrix)
        {
            // build a transformation matrix from it
            var mat = new Matrix4x4(presentRotation.GetMatrix());
            mat.A1 *= presentScaling.X;
            mat.B1 *= presentScaling.X;
            mat.C1 *= presentScaling.X;
            mat.A2 *= presentScaling.Y;
            mat.B2 *= presentScaling.Y;
            mat.C2 *= presentScaling.Y;
            mat.A3 *= presentScaling.Z;
            mat.B3 *= presentScaling.Z;
            mat.C3 *= presentScaling.Z;
            mat.A4 = presentPosition.X;
            mat.B4 = presentPosition.Y;
            mat.C4 = presentPosition.Z;

            outMatrix = AssimpToOpenTk.FromMatrix(ref mat);
        }
Пример #26
0
        /// <summary>
        /// Evaluate animation channels at a given time
        /// </summary>
        /// <param name="pTime">Time, in seconds. If the time exceeds the animation's
        /// duration value, it will be looped.</param>
        /// <param name="isInEndPosition">A problem with automatic looping (and the
        /// way how assimp handles animation duration) is that evaluating the
        /// animation at a time that is exactly the animation duration might wrap
        /// over to the first key frame (i.e. due to numerical inaccuracies). Setting
        /// this parameter to true causes the pTime value to be ignored and the
        /// last set of key frames to be taken.</param>
        public void Evaluate(double pTime, bool isInEndPosition)
        {
            // extract ticks per second. Assume default value if not given
            // every following time calculation happens in ticks
            pTime *= _ticksPerSecond;

            // map into anim's duration
            double time = 0.0f;

            if (_animation.DurationInTicks > 0.0)
            {
                time = pTime % _animation.DurationInTicks;
            }

            // calculate the transformations for each animation channel
            for (int a = 0; a < _animation.NodeAnimationChannelCount; a++)
            {
                var channel = _animation.NodeAnimationChannels[a];

                var presentPosition = new Vector3D(0, 0, 0);
                var presentRotation = new Quaternion(1, 0, 0, 0);
                var presentScaling  = new Vector3D(1, 1, 1);

                if (isInEndPosition)
                {
                    if (channel.PositionKeyCount > 0)
                    {
                        presentPosition         = channel.PositionKeys.Last().Value;
                        _lastPositions[a].Item1 = channel.PositionKeyCount - 1;
                    }
                    if (channel.RotationKeyCount > 0)
                    {
                        presentRotation         = channel.RotationKeys.Last().Value;
                        _lastPositions[a].Item2 = channel.RotationKeyCount - 1;
                    }
                    if (channel.ScalingKeyCount > 0)
                    {
                        presentScaling          = channel.ScalingKeys.Last().Value;
                        _lastPositions[a].Item3 = channel.ScalingKeyCount - 1;
                    }
                    BuildTransform(ref presentRotation, ref presentScaling, ref presentPosition, out _currentTransforms[a]);
                    continue;
                }

                // ******** Position *****
                if (channel.PositionKeyCount > 0)
                {
                    // Look for present frame number. Search from last position if time is after the last time, else from beginning
                    // Should be much quicker than always looking from start for the average use case.
                    var frame = (time >= _lastTime) ? _lastPositions[a].Item1 : 0;
                    while (frame < channel.PositionKeyCount - 1)
                    {
                        if (time < channel.PositionKeys[frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }

                    // interpolate between this frame's value and next frame's value
                    var nextFrame = (frame + 1) % channel.PositionKeyCount;
                    var key       = channel.PositionKeys[frame];
                    var nextKey   = channel.PositionKeys[nextFrame];
                    var diffTime  = nextKey.Time - key.Time;
                    if (diffTime < 0.0)
                    {
                        diffTime += _animation.DurationInTicks;
                    }

                    if (diffTime > 0)
                    {
                        var factor = (float)((time - key.Time) / diffTime);
                        presentPosition = key.Value + (nextKey.Value - key.Value) * factor;
                    }
                    else
                    {
                        presentPosition = key.Value;
                    }

                    _lastPositions[a].Item1 = frame;
                }

                // ******** Rotation *********
                if (channel.RotationKeyCount > 0)
                {
                    var frame = (time >= _lastTime) ? _lastPositions[a].Item2 : 0;
                    while (frame < channel.RotationKeyCount - 1)
                    {
                        if (time < channel.RotationKeys[frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }

                    // interpolate between this frame's value and next frame's value
                    var    nextFrame = (frame + 1) % channel.RotationKeyCount;
                    var    key       = channel.RotationKeys[frame];
                    var    nextKey   = channel.RotationKeys[nextFrame];
                    double diffTime  = nextKey.Time - key.Time;
                    if (diffTime < 0.0)
                    {
                        diffTime += _animation.DurationInTicks;
                    }
                    if (diffTime > 0)
                    {
                        var factor = (float)((time - key.Time) / diffTime);
                        presentRotation = Quaternion.Slerp(key.Value, nextKey.Value, factor);
                    }
                    else
                    {
                        presentRotation = key.Value;
                    }

                    _lastPositions[a].Item2 = frame;
                }

                // ******** Scaling **********
                if (channel.ScalingKeyCount > 0)
                {
                    var frame = (time >= _lastTime) ? _lastPositions[a].Item3 : 0;
                    while (frame < channel.ScalingKeyCount - 1)
                    {
                        if (time < channel.ScalingKeys[frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }

                    // TODO: (thom) interpolation maybe? This time maybe even logarithmic, not linear
                    presentScaling          = channel.ScalingKeys[frame].Value;
                    _lastPositions[a].Item3 = frame;
                }

                BuildTransform(ref presentRotation, ref presentScaling, ref presentPosition, out _currentTransforms[a]);
            }

            _lastTime = time;
        }
Пример #27
0
        /// <summary>
        /// Evaluate animation channels at a given time
        /// </summary>
        /// <param name="pTime">Time, in seconds. If the time exceeds the animation's
        /// duration value, it will be looped.</param>
        /// <param name="isInEndPosition">A problem with automatic looping (and the
        /// way how assimp handles animation duration) is that evaluating the
        /// animation at a time that is exactly the animation duration might wrap
        /// over to the first key frame (i.e. due to numerical inaccuracies). Setting
        /// this parameter to true causes the pTime value to be ignored and the
        /// last set of key frames to be taken.</param>
        public void Evaluate(double pTime, bool isInEndPosition)
        {
            // extract ticks per second. Assume default value if not given
            // every following time calculation happens in ticks
            pTime *= _ticksPerSecond;

            // map into anim's duration
            double time = 0.0f;
            if (_animation.DurationInTicks > 0.0)
            {
                time = pTime % _animation.DurationInTicks;
            }

            // calculate the transformations for each animation channel
            for (int a = 0; a < _animation.NodeAnimationChannelCount; a++)
            {
                var channel = _animation.NodeAnimationChannels[a];

                var presentPosition = new Vector3D(0, 0, 0);
                var presentRotation = new Quaternion(1, 0, 0, 0);
                var presentScaling = new Vector3D(1, 1, 1);

                if (isInEndPosition)
                {
                    if (channel.PositionKeyCount > 0)
                    {
                        presentPosition = channel.PositionKeys.Last().Value;
                        _lastPositions[a].Item1 = channel.PositionKeyCount - 1;
                    }
                    if (channel.RotationKeyCount > 0)
                    {
                        presentRotation = channel.RotationKeys.Last().Value;
                        _lastPositions[a].Item2 = channel.RotationKeyCount - 1;
                    }
                    if (channel.ScalingKeyCount > 0)
                    {
                        presentScaling = channel.ScalingKeys.Last().Value;
                        _lastPositions[a].Item3 = channel.ScalingKeyCount - 1;
                    }
                    BuildTransform(ref presentRotation, ref presentScaling, ref presentPosition, out _currentTransforms[a]);
                    continue;
                }

                // ******** Position *****
                if (channel.PositionKeyCount > 0)
                {
                    // Look for present frame number. Search from last position if time is after the last time, else from beginning
                    // Should be much quicker than always looking from start for the average use case.
                    var frame = (time >= _lastTime) ? _lastPositions[a].Item1 : 0;
                    while (frame < channel.PositionKeyCount - 1)
                    {
                        if (time < channel.PositionKeys[frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }

                    // interpolate between this frame's value and next frame's value
                    var nextFrame = (frame + 1) % channel.PositionKeyCount;
                    var key = channel.PositionKeys[frame];
                    var nextKey = channel.PositionKeys[nextFrame];
                    var diffTime = nextKey.Time - key.Time;
                    if (diffTime < 0.0)
                    {
                        diffTime += _animation.DurationInTicks;
                    }

                    if (diffTime > 0)
                    {
                        var factor = (float)((time - key.Time) / diffTime);
                        presentPosition = key.Value + (nextKey.Value - key.Value) * factor;
                    }
                    else
                    {
                        presentPosition = key.Value;
                    }

                    _lastPositions[a].Item1 = frame;
                }

                // ******** Rotation *********
                if (channel.RotationKeyCount > 0)
                {
                    var frame = (time >= _lastTime) ? _lastPositions[a].Item2 : 0;
                    while (frame < channel.RotationKeyCount - 1)
                    {
                        if (time < channel.RotationKeys[frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }

                    // interpolate between this frame's value and next frame's value
                    var nextFrame = (frame + 1) % channel.RotationKeyCount;
                    var key = channel.RotationKeys[frame];
                    var nextKey = channel.RotationKeys[nextFrame];
                    double diffTime = nextKey.Time - key.Time;
                    if (diffTime < 0.0)
                    {
                        diffTime += _animation.DurationInTicks;
                    }
                    if (diffTime > 0)
                    {
                        var factor = (float)((time - key.Time) / diffTime);
                        presentRotation = Quaternion.Slerp(key.Value, nextKey.Value, factor);
                    }
                    else
                    {
                        presentRotation = key.Value;
                    }

                    _lastPositions[a].Item2 = frame;
                }

                // ******** Scaling **********                
                if (channel.ScalingKeyCount > 0)
                {
                    var frame = (time >= _lastTime) ? _lastPositions[a].Item3 : 0;
                    while (frame < channel.ScalingKeyCount - 1)
                    {
                        if (time < channel.ScalingKeys[frame + 1].Time)
                        {
                            break;
                        }
                        frame++;
                    }

                    // TODO: (thom) interpolation maybe? This time maybe even logarithmic, not linear
                    presentScaling = channel.ScalingKeys[frame].Value;
                    _lastPositions[a].Item3 = frame;
                }

                BuildTransform(ref presentRotation, ref presentScaling, ref presentPosition, out _currentTransforms[a]);
            }

            _lastTime = time;
        }
Пример #28
0
        public static GameObject Load(string meshPath, float scaleX = 1, float scaleY = 1, float scaleZ = 1)
        {
            if (!File.Exists(meshPath))
            {
                return(null);
            }

            AssimpContext importer = new AssimpContext();
            Scene         scene    = importer.ImportFile(meshPath);

            if (scene == null)
            {
                return(null);
            }

            string parentDir = Directory.GetParent(meshPath).FullName;

            // Materials
            List <UnityEngine.Material> uMaterials = new List <Material>();

            if (scene.HasMaterials)
            {
                foreach (var m in scene.Materials)
                {
                    UnityEngine.Material uMaterial = new UnityEngine.Material(Shader.Find("Standard"));

                    // Albedo
                    if (m.HasColorDiffuse)
                    {
                        Color color = new Color(
                            m.ColorDiffuse.R,
                            m.ColorDiffuse.G,
                            m.ColorDiffuse.B,
                            m.ColorDiffuse.A
                            );
                        uMaterial.color = color;
                    }

                    // Emission
                    if (m.HasColorEmissive)
                    {
                        Color color = new Color(
                            m.ColorEmissive.R,
                            m.ColorEmissive.G,
                            m.ColorEmissive.B,
                            m.ColorEmissive.A
                            );
                        uMaterial.SetColor("_EmissionColor", color);
                        uMaterial.EnableKeyword("_EMISSION");
                    }

                    // Reflectivity
                    if (m.HasReflectivity)
                    {
                        uMaterial.SetFloat("_Glossiness", m.Reflectivity);
                    }

                    // Texture
                    if (false && m.HasTextureDiffuse)
                    {
                        Texture2D uTexture    = new Texture2D(2, 2);
                        string    texturePath = Path.Combine(parentDir, m.TextureDiffuse.FilePath);

                        byte[] byteArray = File.ReadAllBytes(texturePath);
                        bool   isLoaded  = uTexture.LoadImage(byteArray);
                        if (!isLoaded)
                        {
                            throw new Exception("Cannot find texture file: " + texturePath);
                        }

                        uMaterial.SetTexture("_MainTex", uTexture);
                    }

                    uMaterials.Add(uMaterial);
                }
            }

            // Mesh
            List <MeshMaterialBinding> uMeshAndMats = new List <MeshMaterialBinding>();

            if (scene.HasMeshes)
            {
                foreach (var m in scene.Meshes)
                {
                    List <Vector3> uVertices = new List <Vector3>();
                    List <Vector3> uNormals  = new List <Vector3>();
                    List <Vector2> uUv       = new List <Vector2>();
                    List <int>     uIndices  = new List <int>();

                    // Vertices
                    if (m.HasVertices)
                    {
                        foreach (var v in m.Vertices)
                        {
                            uVertices.Add(new Vector3(-v.X, v.Y, v.Z));
                        }
                    }

                    // Normals
                    if (m.HasNormals)
                    {
                        foreach (var n in m.Normals)
                        {
                            uNormals.Add(new Vector3(-n.X, n.Y, n.Z));
                        }
                    }

                    // Triangles
                    if (m.HasFaces)
                    {
                        foreach (var f in m.Faces)
                        {
                            // Ignore degenerate faces
                            if (f.IndexCount == 1 || f.IndexCount == 2)
                            {
                                continue;
                            }

                            for (int i = 0; i < (f.IndexCount - 2); i++)
                            {
                                uIndices.Add(f.Indices[i + 2]);
                                uIndices.Add(f.Indices[i + 1]);
                                uIndices.Add(f.Indices[0]);
                            }
                        }
                    }

                    // Uv (texture coordinate)
                    if (m.HasTextureCoords(0))
                    {
                        foreach (var uv in m.TextureCoordinateChannels[0])
                        {
                            uUv.Add(new Vector2(uv.X, uv.Y));
                        }
                    }

                    UnityEngine.Mesh uMesh = new UnityEngine.Mesh();
                    uMesh.vertices  = uVertices.ToArray();
                    uMesh.normals   = uNormals.ToArray();
                    uMesh.triangles = uIndices.ToArray();
                    uMesh.uv        = uUv.ToArray();

                    uMeshAndMats.Add(new MeshMaterialBinding(m.Name, uMesh, uMaterials[m.MaterialIndex]));
                }
            }

            // Create GameObjects from nodes
            GameObject NodeToGameObject(Node node)
            {
                GameObject uOb = new GameObject(node.Name);

                // Set Mesh
                if (node.HasMeshes)
                {
                    foreach (var mIdx in node.MeshIndices)
                    {
                        var uMeshAndMat = uMeshAndMats[mIdx];

                        GameObject uSubOb = new GameObject(uMeshAndMat.MeshName);
                        uSubOb.AddComponent <MeshFilter>();
                        uSubOb.AddComponent <MeshRenderer>();
                        uSubOb.AddComponent <MeshCollider>();

                        uSubOb.GetComponent <MeshFilter>().mesh       = uMeshAndMat.Mesh;
                        uSubOb.GetComponent <MeshRenderer>().material = uMeshAndMat.Material;
                        uSubOb.transform.SetParent(uOb.transform, true);
                        uSubOb.transform.localScale = new Vector3(scaleX, scaleY, scaleZ);
                    }
                }

                // Transform
                // Decompose Assimp transform into scale, rot and translaction
                Assimp.Vector3D   aScale       = new Assimp.Vector3D();
                Assimp.Quaternion aQuat        = new Assimp.Quaternion();
                Assimp.Vector3D   aTranslation = new Assimp.Vector3D();
                node.Transform.Decompose(out aScale, out aQuat, out aTranslation);

                // Convert Assimp transfrom into Unity transform and set transformation of game object
                UnityEngine.Quaternion uQuat = new UnityEngine.Quaternion(aQuat.X, aQuat.Y, aQuat.Z, aQuat.W);
                var euler = uQuat.eulerAngles;

                uOb.transform.localScale    = new UnityEngine.Vector3(aScale.X, aScale.Y, aScale.Z);
                uOb.transform.localPosition = new UnityEngine.Vector3(aTranslation.X, aTranslation.Y, aTranslation.Z);
                uOb.transform.localRotation = UnityEngine.Quaternion.Euler(euler.x, -euler.y, euler.z);

                if (node.HasChildren)
                {
                    foreach (var cn in node.Children)
                    {
                        var uObChild = NodeToGameObject(cn);
                        uObChild.transform.SetParent(uOb.transform, false);
                    }
                }

                return(uOb);
            }

            return(NodeToGameObject(scene.RootNode));;
        }
Пример #29
0
        static void recurseNode(Assimp.Scene scn, Node node, StringBuilder scenesb, Matrix4x4 matrix)
        {
            Console.WriteLine("Scanning node " + node.Name);
            foreach (var mindex in node.MeshIndices)
            {
                var    m    = scn.Meshes[mindex];
                string name = usednames.Contains(m.Name) ? (m.Name + (unnamed++).ToString()) : m.Name;
                var    sb   = new StringBuilder();
                if (!File.Exists(outfile + "/" + name + ".mesh3d"))
                {
                    var vertexinfos = new List <VertexInfo>();
                    var indices     = m.GetIndices();

                    for (int i = 0; i < indices.Length; i++)
                    {
                        int f  = indices[i];
                        var vp = m.Vertices[f];
                        var vn = m.Normals[f];
                        var vt = (m.TextureCoordinateChannels.Length == 0 || m.TextureCoordinateChannels[0].Count <= f) ? new Assimp.Vector3D(0) : m.TextureCoordinateChannels[0][f];
                        var vi = new VertexInfo()
                        {
                            Position = new Vector3(vp.X, vp.Y, vp.Z),
                            Normal   = new Vector3(vn.X, vn.Y, vn.Z),
                            UV       = new Vector2(vt.X, vt.Y)
                        };
                        vertexinfos.Add(vi);
                    }
                    if (doublefaced)
                    {
                        for (int i = indices.Length - 1; i >= 0; i--)
                        {
                            int f  = indices[i];
                            var vp = m.Vertices[f];
                            var vn = m.Normals[f];
                            var vt = (m.TextureCoordinateChannels.Length == 0 || m.TextureCoordinateChannels[0].Count <= f) ? new Assimp.Vector3D(0) : m.TextureCoordinateChannels[0][f];
                            var vi = new VertexInfo()
                            {
                                Position = new Vector3(vp.X, vp.Y, vp.Z),
                                Normal   = new Vector3(vn.X, vn.Y, vn.Z),
                                UV       = new Vector2(vt.X, vt.Y)
                            };
                            vertexinfos.Add(vi);
                        }
                    }
                    var element = new Object3dManager(vertexinfos);
                    Console.WriteLine("Saving " + outfile + "/" + name + ".raw");
                    element.SaveRawWithTangents(outfile + "/" + name + ".raw");

                    string matname = matdict[m.MaterialIndex];
                    scenesb.AppendLine("mesh3d " + outfile + "/" + name + ".mesh3d");
                    sb.AppendLine("lodlevel");
                    sb.AppendLine("start 0.0");
                    sb.AppendLine("end 99999.0");
                    sb.AppendLine("info3d " + outfile + "/" + name + ".raw");
                    sb.AppendLine("material " + matname);
                    sb.AppendLine();
                }
                sb.AppendLine("instance");
                Assimp.Vector3D   pvec, pscl;
                Assimp.Quaternion pquat;
                var a  = new Assimp.Quaternion(new Vector3D(1, 0, 0), MathHelper.DegreesToRadians(-90)).GetMatrix();
                var a2 = Matrix4x4.FromScaling(new Vector3D(0.01f));
                (matrix * node.Transform * new Assimp.Matrix4x4(a) * a2).Decompose(out pscl, out pquat, out pvec);
                var q1 = new OpenTK.Quaternion(pquat.X, pquat.Y, pquat.Z, pquat.W).Inverted();
                var m1 = Matrix4.CreateFromQuaternion(q1);
                m1[2, 0] = -m1[2, 0];
                m1[2, 1] = -m1[2, 1];
                m1[0, 2] = -m1[0, 2];
                m1[1, 2] = -m1[1, 2];
                var q2 = m1.ExtractRotation(true);

                sb.AppendLine(string.Format("translate {0} {1} {2}", ftos(pvec.X), ftos(pvec.Y), ftos(pvec.Z)));
                sb.AppendLine(string.Format("rotate {0} {1} {2} {3}", ftos(q1.X), ftos(q1.Y), ftos(q1.Z), ftos(q1.W)));
                sb.AppendLine(string.Format("scale {0} {1} {2}", ftos(pscl.X), ftos(pscl.Y), ftos(pscl.Z)));
                if (!File.Exists(outfile + "/" + name + ".mesh3d"))
                {
                    Console.WriteLine("Saving " + outfile + "/" + name + ".mesh3d");
                    File.WriteAllText(outfile + "/" + name + ".mesh3d", sb.ToString());
                }
                else
                {
                    Console.WriteLine("Extending " + outfile + "/" + name + ".mesh3d");
                    File.AppendAllText(outfile + "/" + name + ".mesh3d", sb.ToString());
                }
            }
            foreach (var c in node.Children)
            {
                if (c != node)
                {
                    recurseNode(scn, c, scenesb, matrix * node.Transform);
                }
            }
        }
Пример #30
0
 private static SharpDX.Mathematics.Quaternion ConvertQuaternion(Assimp.Quaternion value)
 {
     // Assimp quaternions are stored in wxyz order
     return(new SharpDX.Mathematics.Quaternion(value.X, value.Y, value.Z, value.W));
 }
Пример #31
0
        public Assimp.Quaternion GetAssimpRotation()
        {
            Matrix4x4 pos = converter.Matrix3DToAssimpMatrix4x4(Matrix[Session.CurrentSession.CurrentProject.CurrentModel3D.Animation.Tick]);

            Assimp.Vector3D posTranslation = new Assimp.Vector3D();
            Assimp.Quaternion posRot = new Assimp.Quaternion();

            pos.DecomposeNoScaling(out posRot, out posTranslation);
           
            return posRot;
        }
Пример #32
0
        // quat4 -> (roll, pitch, yaw)
        private static void QuatToEulerXyz(ref Quaternion q1, out Vector3 outVector)
        {
            // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
            double sqw = q1.W*q1.W;
            double sqx = q1.X*q1.X;
            double sqy = q1.Y*q1.Y;
            double sqz = q1.Z*q1.Z;
	        double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
	        double test = q1.X*q1.Y + q1.Z*q1.W;
	        if (test > 0.499*unit) { // singularity at north pole
                outVector.Z = (float)(2 * Math.Atan2(q1.X, q1.W));
                outVector.Y = (float)(Math.PI / 2);
                outVector.X = 0;
		        return;
	        }
	        if (test < -0.499*unit) { // singularity at south pole
                outVector.Z = (float)(-2 * Math.Atan2(q1.X, q1.W));
                outVector.Y = (float)(-Math.PI / 2);
                outVector.X = 0;
		        return;
	        }
            outVector.Z = (float)Math.Atan2(2 * q1.Y * q1.W - 2 * q1.X * q1.Z, sqx - sqy - sqz + sqw);
            outVector.Y = (float)Math.Asin(2 * test / unit);
            outVector.X = (float)Math.Atan2(2 * q1.X * q1.W - 2 * q1.Y * q1.Z, -sqx + sqy - sqz + sqw);
        }
Пример #33
0
 public static System.Numerics.Quaternion ToNumerics(this Quaternion value)
 {
     return(new System.Numerics.Quaternion(value.X, value.Y, value.Z, value.W));
 }
Пример #34
0
 public static Quaternion ToQuaternion(Assimp.Quaternion q)
 {
     return(new Quaternion(q.X, q.Y, q.Z, q.W));
 }
Пример #35
0
 public static System.Numerics.Quaternion ToSystemQuaternion(this Assimp.Quaternion quat)
 {
     return(new System.Numerics.Quaternion(quat.X, quat.Y, quat.Z, quat.W));
 }
Пример #36
0
        public void Evaluate(float dt, Dictionary<string, Bone> bones) {
            dt *= TicksPerSecond;
            var time = 0.0f;
            if (Duration > 0.0f) {
                time = dt % Duration;
            }
            for (int i = 0; i < Channels.Count; i++) {
                var channel = Channels[i];
                if (!bones.ContainsKey(channel.Name)) {
                    Console.WriteLine("Did not find the bone node " + channel.Name);
                    continue;
                }
                // interpolate position keyframes
                var pPosition = new Vector3D();
                if (channel.PositionKeys.Count > 0) {
                    var frame = (time >= LastTime) ? LastPositions[i].Item1 : 0;
                    while (frame < channel.PositionKeys.Count - 1) {
                        if (time < channel.PositionKeys[frame + 1].Time) {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.PositionKeys.Count) {
                        frame = 0;
                    }

                    var nextFrame = (frame + 1) % channel.PositionKeys.Count;

                    var key = channel.PositionKeys[frame];
                    var nextKey = channel.PositionKeys[nextFrame];
                    var diffTime = nextKey.Time - key.Time;
                    if (diffTime < 0.0) {
                        diffTime += Duration;
                    }
                    if (diffTime > 0.0) {
                        var factor = (float)((time - key.Time) / diffTime);
                        pPosition = key.Value + (nextKey.Value - key.Value) * factor;
                    } else {
                        pPosition = key.Value;
                    }
                    LastPositions[i].Item1 = frame;

                }
                // interpolate rotation keyframes
                var pRot = new Assimp.Quaternion(1, 0, 0, 0);
                if (channel.RotationKeys.Count > 0) {
                    var frame = (time >= LastTime) ? LastPositions[i].Item2 : 0;
                    while (frame < channel.RotationKeys.Count - 1) {
                        if (time < channel.RotationKeys[frame + 1].Time) {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.RotationKeys.Count) {
                        frame = 0;
                    }
                    var nextFrame = (frame + 1) % channel.RotationKeys.Count;

                    var key = channel.RotationKeys[frame];
                    var nextKey = channel.RotationKeys[nextFrame];
                    key.Value.Normalize();
                    nextKey.Value.Normalize();
                    var diffTime = nextKey.Time - key.Time;
                    if (diffTime < 0.0) {
                        diffTime += Duration;
                    }
                    if (diffTime > 0) {
                        var factor = (float)((time - key.Time) / diffTime);
                        pRot = Assimp.Quaternion.Slerp(key.Value, nextKey.Value, factor);
                    } else {
                        pRot = key.Value;
                    }
                    LastPositions[i].Item1= frame;

                }
                // interpolate scale keyframes
                var pscale = new Vector3D(1);
                if (channel.ScalingKeys.Count > 0) {
                    var frame = (time >= LastTime) ? LastPositions[i].Item3 : 0;
                    while (frame < channel.ScalingKeys.Count - 1) {
                        if (time < channel.ScalingKeys[frame + 1].Time) {
                            break;
                        }
                        frame++;
                    }
                    if (frame >= channel.ScalingKeys.Count) {
                        frame = 0;
                    }
                    LastPositions[i].Item3 = frame;
                }

                // create the combined transformation matrix
                var mat = new Matrix4x4(pRot.GetMatrix());
                mat.A1 *= pscale.X; mat.B1 *= pscale.X; mat.C1 *= pscale.X;
                mat.A2 *= pscale.Y; mat.B2 *= pscale.Y; mat.C2 *= pscale.Y;
                mat.A3 *= pscale.Z; mat.B3 *= pscale.Z; mat.C3 *= pscale.Z;
                mat.A4 = pPosition.X; mat.B4 = pPosition.Y; mat.C4 = pPosition.Z;

                // transpose to get DirectX style matrix
                mat.Transpose();
                bones[channel.Name].LocalTransform = mat.ToMatrix();
            }
            LastTime = time;
        }