public void FromTransform(Matrix4 transform)
 {
     Scale         = transform.ExtractScale();
     Position      = transform.ExtractTranslation();
     rotation      = transform.ExtractRotation();
     eulerRotation = STMath.ToEulerAngles(rotation);
 }
Example #2
0
        //jakeroo123's animation adding code.
        public static void ExportAnimation(string FileName, Toolbox.Library.Animations.Animation anim = null, STSkeleton skeleton = null, List <int> NodeArray = null)
        {
            //Always use the same settings
            ExportSettings settings = new ExportSettings();

            settings.SuppressConfirmDialog = true;
            settings.UseMatrixTransform    = false;

            List <string> failedTextureExport = new List <string>();

            STProgressBar progressBar = new STProgressBar();

            progressBar.Task          = "Exporting Animation \"" + anim.Text + "\"...";
            progressBar.Value         = 0;
            progressBar.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            progressBar.Show();
            progressBar.Refresh();

            /* I don't see any way to use this
             * if (settings.UseOldExporter)
             * {
             *  AssimpSaver saver = new AssimpSaver();
             *  STGenericModel model = new STGenericModel();
             *  model.Objects = Meshes;
             *  model.Materials = Materials;
             *  saver.SaveFromModel(model, FileName, Textures, skeleton, NodeArray);
             *  return;
             * }
             */

            string TexturePath = System.IO.Path.GetDirectoryName(FileName);

            using (ColladaWriter writer = new ColladaWriter(FileName, settings))
            {
                writer.WriteAsset();

                //This is where the magic happens - Iterate through bones, and add animations.
                if (anim != null && skeleton != null)
                {
                    writer.StartLibraryAnimations();

                    float[] frames = new float[anim.FrameCount + 1];

                    for (int i = 0; i <= anim.FrameCount; i++)
                    {
                        frames[i] = i / 30f; //DAE appears to save frame times - This is saving the animation as 30 FPS, regardless of anything else.
                    }

                    string[] interp = new string[anim.FrameCount + 1];

                    for (int i = 0; i <= anim.FrameCount; i++)
                    {
                        interp[i] = "LINEAR"; //Just use linear.
                    }

                    foreach (STBone bone in skeleton.bones)
                    {
                        skeleton.reset();

                        string aid = anim.Text + "_" + bone.Text; //The prefix for animation

                        string bid = "Armature_" + bone.Text;

                        Vector3 defaultRotation = bone.EulerRotation;

                        //Three arrays, for
                        float[]   rotateX   = new float[anim.FrameCount + 1];
                        float[]   rotateY   = new float[anim.FrameCount + 1];
                        float[]   rotateZ   = new float[anim.FrameCount + 1];
                        Vector3[] scale     = new Vector3[anim.FrameCount + 1];
                        Vector3[] translate = new Vector3[anim.FrameCount + 1];

                        anim.SetFrame(0);
                        for (int i = 0; i <= anim.FrameCount; i++)
                        {
                            anim.NextFrame(skeleton, false, true, bone.Text);

                            //Rotation
                            Vector3 eul = STMath.ToEulerAngles(bone.rot);
                            rotateX[i] = eul.X * Rad2Deg; //- defaultRotation.X;
                            rotateY[i] = eul.Y * Rad2Deg; //- defaultRotation.Y;
                            rotateZ[i] = eul.Z * Rad2Deg; //- defaultRotation.Z;

                            //Scaling and translation
                            scale[i]     = bone.GetScale();
                            translate[i] = bone.GetPosition();
                        }

                        writer.WriteAnimationVector(aid + "_translate", frames, interp, translate, bid + "/location");

                        writer.WriteAnimationAngle(aid + "_rotateX", frames, interp, rotateX, bid + "/rotationX.ANGLE");

                        writer.WriteAnimationAngle(aid + "_rotateY", frames, interp, rotateY, bid + "/rotationY.ANGLE");

                        writer.WriteAnimationAngle(aid + "_rotateZ", frames, interp, rotateZ, bid + "/rotationZ.ANGLE");

                        writer.WriteAnimationVector(aid + "_scale", frames, interp, scale, bid + "/scale");
                    }

                    writer.EndLibraryAnimations();
                }

                skeleton.reset();

                //Don't bother exporting any textures - It's not really necessary, at this point.
                writer.WriteLibraryImages();

                if (skeleton != null)
                {
                    //Don't bother searching for rigging, because the mesh will simply be empty.

                    foreach (var bone in skeleton.bones)
                    {
                        //Set the inverse matrix
                        var inverse   = skeleton.GetBoneTransform(bone).Inverted();
                        var transform = bone.GetTransform();

                        float[] Transform = new float[] {
                            transform.M11, transform.M21, transform.M31, transform.M41,
                            transform.M12, transform.M22, transform.M32, transform.M42,
                            transform.M13, transform.M23, transform.M33, transform.M43,
                            transform.M14, transform.M24, transform.M34, transform.M44
                        };

                        float[] InvTransform = new float[] {
                            inverse.M11, inverse.M21, inverse.M31, inverse.M41,
                            inverse.M12, inverse.M22, inverse.M32, inverse.M42,
                            inverse.M13, inverse.M23, inverse.M33, inverse.M43,
                            inverse.M14, inverse.M24, inverse.M34, inverse.M44
                        };

                        writer.AddJoint(bone.Text, bone.parentIndex == -1 ? "" :
                                        skeleton.bones[bone.parentIndex].Text, Transform, InvTransform,
                                        new float[3] {
                            bone.Position.X, bone.Position.Y, bone.Position.Z
                        },
                                        new float[3] {
                            bone.EulerRotation.X *Rad2Deg, bone.EulerRotation.Y *Rad2Deg, bone.EulerRotation.Z *Rad2Deg
                        },
                                        new float[3] {
                            bone.Scale.X, bone.Scale.Y, bone.Scale.Z
                        });
                    }
                }


                writer.StartLibraryGeometries();
                //Try to not write meshes? Let's hope this works.
                writer.EndGeometrySection();
            }

            progressBar?.Close();
        }
Example #3
0
        public static Animations.Animation CreateGenericAnimation(Assimp.Animation animation)
        {
            Animations.Animation STanim = new Animations.Animation();
            STanim.Text = animation.Name;
            float TicksPerSecond = animation.TicksPerSecond != 0 ? (float)animation.TicksPerSecond : 25.0f;
            float Duriation      = (float)animation.DurationInTicks;

            STanim.FrameCount = (int)(Duriation * 30);


            //Load node animations
            if (animation.HasNodeAnimations)
            {
                var _channels = new NodeAnimationChannel[animation.NodeAnimationChannelCount];
                for (int i = 0; i < _channels.Length; i++)
                {
                    _channels[i] = new NodeAnimationChannel();
                    var boneAnim = new Animations.Animation.KeyNode(_channels[i].NodeName);
                    boneAnim.RotType = Animations.Animation.RotationType.EULER;
                    STanim.Bones.Add(boneAnim);

                    STConsole.WriteLine($"Creating Bone Anims {boneAnim.Text} ");

                    for (int frame = 0; frame < STanim.FrameCount; i++)
                    {
                        if (_channels[i].HasPositionKeys)
                        {
                            for (int key = 0; key < _channels[i].PositionKeyCount; key++)
                            {
                                if (frame == _channels[i].PositionKeys[key].Time)
                                {
                                    boneAnim.XPOS.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].PositionKeys[key].Value.X,
                                        Frame = frame,
                                    });
                                    boneAnim.YPOS.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].PositionKeys[key].Value.Y,
                                        Frame = frame,
                                    });
                                    boneAnim.ZPOS.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].PositionKeys[key].Value.Z,
                                        Frame = frame,
                                    });
                                }
                            }
                        }
                        if (_channels[i].HasRotationKeys)
                        {
                            for (int key = 0; key < _channels[i].RotationKeyCount; key++)
                            {
                                if (frame == _channels[i].RotationKeys[key].Time)
                                {
                                    var quat  = _channels[i].RotationKeys[key].Value;
                                    var euler = STMath.ToEulerAngles(quat.X, quat.Y, quat.Z, quat.W);

                                    boneAnim.XROT.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = euler.X,
                                        Frame = frame,
                                    });
                                    boneAnim.YROT.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = euler.Y,
                                        Frame = frame,
                                    });
                                    boneAnim.ZROT.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = euler.Z,
                                        Frame = frame,
                                    });
                                    boneAnim.WROT.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = 1,
                                        Frame = frame,
                                    });
                                }
                            }
                        }
                        if (_channels[i].HasScalingKeys)
                        {
                            for (int key = 0; key < _channels[i].ScalingKeyCount; key++)
                            {
                                if (frame == _channels[i].ScalingKeys[key].Time)
                                {
                                    boneAnim.XSCA.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].ScalingKeys[key].Value.X,
                                        Frame = frame,
                                    });
                                    boneAnim.YSCA.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].ScalingKeys[key].Value.Y,
                                        Frame = frame,
                                    });
                                    boneAnim.ZSCA.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].ScalingKeys[key].Value.Z,
                                        Frame = frame,
                                    });
                                }
                            }
                        }
                    }
                }
            }

            //Load mesh animations
            if (animation.HasMeshAnimations)
            {
                var _meshChannels = new MeshAnimationChannel[animation.MeshAnimationChannelCount];
                for (int i = 0; i < _meshChannels.Length; i++)
                {
                    _meshChannels[i] = new MeshAnimationChannel();
                }
            }

            return(STanim);
        }
Example #4
0
        private void CreateByNode(Node node, STSkeleton skeleton, string ParentArmatureName,
                                  short SmoothIndex, short RigidIndex, bool IsRoot, ref Assimp.Matrix4x4 rootTransform)
        {
            Matrix4x4 trafo        = node.Transform;
            Matrix4x4 world        = trafo;
            var       transformMat = AssimpHelper.TKMatrix(world);

            int matchedBoneIndex = skeleton.bones.FindIndex(item => item.Name == node.Name);

            if (matchedBoneIndex < 0)
            {
                tempBoneNodes.Add(node);

                STBone bone = new STBone();
                bone.skeletonParent = skeleton;
                bone.RotationType   = STBone.BoneRotationType.Euler;
                skeleton.bones.Add(bone);

                if (DaeHelper.IDMapToName.ContainsKey(node.Name))
                {
                    bone.Text = DaeHelper.IDMapToName[node.Name];
                }
                else
                {
                    bone.Text = node.Name;
                }

                bone.SmoothMatrixIndex = (short)skeleton.bones.IndexOf(bone);
                bone.RigidMatrixIndex  = -1; //Todo calculate these

                STConsole.WriteLine($"-".Repeat(30));
                STConsole.WriteLine($"Processing Bone {bone.Text}");
                STConsole.WriteLine($"SmoothMatrixIndex {bone.SmoothMatrixIndex}");
                STConsole.WriteLine($"RigidMatrixIndex {bone.RigidMatrixIndex}");
                STConsole.WriteLine($"Transform Matrix {transformMat}");
                STConsole.WriteLine($"-".Repeat(30));

                if (IsRoot)
                {
                    bone.parentIndex = -1;

                    if (RotateSkeleton)
                    {
                        transformMat = AssimpHelper.TKMatrix(world * Matrix4x4.FromRotationX(MathHelper.DegreesToRadians(RotateSkeletonAmount)));
                    }
                    else
                    {
                        transformMat = AssimpHelper.TKMatrix(world);
                    }
                }
                else
                {
                    if (tempBoneNodes.Contains(node.Parent))
                    {
                        bone.parentIndex = tempBoneNodes.IndexOf(node.Parent);
                    }
                }


                var scale    = transformMat.ExtractScale();
                var rotation = transformMat.ExtractRotation();
                var position = transformMat.ExtractTranslation();

                var rotEular = STMath.ToEulerAngles(rotation);

                bone.position = new float[] { position.X, position.Y, position.Z };
                bone.scale    = new float[] { scale.X, scale.Y, scale.Z };
                bone.rotation = new float[] { rotEular.X, rotEular.Y, rotEular.Z, 1 };
            }
            else
            {
                STConsole.WriteLine($"Duplicate node name found for bone {node.Name}!", Color.Red);
            }

            foreach (Node child in node.Children)
            {
                CreateByNode(child, skeleton, ParentArmatureName, SmoothIndex, RigidIndex, false, ref rootTransform);
            }
        }