예제 #1
0
        private List <BoneMapping> GetBoneMappings()
        {
            var bones     = new List <BoneMapping>();
            var boneNames = SceneToImport.Meshes.SelectMany(x => x.Bones).Select(x => x.Name).Distinct().ToList();

            if (!boneNames.Any())
            {
                return(bones);
            }

            var boneNodes = Assimp.AssimpHelper.GetNodeHierarchy(SceneToImport.RootNode)
                            .Where(x => boneNames.Contains(x.Name)) /*.OrderBy(x => x.GetLevel())*/.ToList();

            //include last bone if no weight
            if (boneNodes.LastOrDefault()?.ChildCount > 0)
            {
                var lastBone = boneNodes.Last();
                if (lastBone.MeshCount == 0)
                {
                    boneNodes.Add(lastBone.Children[0]);
                }
            }

            boneNames = boneNodes.Select(x => x.Name).ToList();//names in order

            foreach (var boneNode in boneNodes)
            {
                //var meshBone = SceneToImport.Meshes.SelectMany(x => x.Bones).FirstOrDefault(x => x.Name == boneNode.Name);
                //var pos1 = ItemTransform.FromMatrix(meshBone.OffsetMatrix.ToLDD());

                string parentName = boneNode.Parent?.Name;
                if (!boneNames.Contains(parentName))
                {
                    parentName = null;
                }

                var boneTransform = boneNode.GetFinalTransform().ToLDD();
                //var yAxis = boneTransform.TransformNormal(Simple3D.Vector3.UnitY);
                //boneTransform = Simple3D.Matrix4.FromAngleAxis((float)Math.PI * -0.5f, yAxis) * boneTransform;

                var mapping = new BoneMapping()
                {
                    Name       = boneNode.Name,
                    ParentName = parentName,
                    Transform  = ItemTransform.FromMatrix(boneTransform),
                    AssimpID   = boneNames.IndexOf(boneNode.Name)
                };
                bones.Add(mapping);
            }

            //Adjust bone rotation for LDD
            foreach (var bone in bones)
            {
                var target = bones.FirstOrDefault(x => x.ParentName == bone.Name);
                if (target != null)
                {
                    var dir   = (target.Transform.Position - bone.Transform.Position).Normalized();
                    var angle = Simple3D.Vector3d.AngleBetween(Simple3D.Vector3d.UnitX, dir);
                    var yAxis = Simple3D.Vector3d.Cross(Simple3D.Vector3d.UnitX, dir);
                    var rot   = Simple3D.Matrix4d.FromAngleAxis(angle, yAxis);
                    bone.Transform.Rotation = Quaterniond.ToEuler(rot.ExtractRotation()) * (180d / Math.PI);
                }
                else if (bone.ParentName != null)
                {
                    var parent = bones.FirstOrDefault(x => x.Name == bone.ParentName);
                    bone.Transform.Rotation = parent.Transform.Rotation;
                }
            }

            return(bones);
        }