Exemple #1
0
        public static Dictionary <string, List <VertexWeight> > GetVertexGroups(SkeletonAsset skeleton, MeshLodSection section)
        {
            var VertexGroups = new Dictionary <string, List <VertexWeight> >();

            GetVertexGroups(skeleton, section, 0, ref VertexGroups);
            return(VertexGroups);
        }
Exemple #2
0
        private static int GetVertexGroups(SkeletonAsset skeleton, MeshLodSection section, int offset, ref Dictionary <string, List <VertexWeight> > VertexGroupDict)
        {
            int VertexCount = offset;

            for (int i = 0; i < section.vertices.Count; i++)
            {
                for (int x = 0; x < 4; x++)
                {
                    float Weight = section.vertices[i].boneWeights[x];

                    // added condition to only add meaningful weights
                    if (Weight != 0.0f)
                    {
                        int BoneIndex          = section.vertices[i].boneIndices[x];
                        int SubObjectBoneIndex = section.boneIndices[BoneIndex];

                        string bn = skeleton.Bones[SubObjectBoneIndex].Name;

                        if (!VertexGroupDict.ContainsKey(bn))
                        {
                            VertexGroupDict.Add(bn, new List <VertexWeight>());
                        }
                        VertexGroupDict[bn].Add(new VertexWeight(offset + i, Weight));
                    }
                }
                VertexCount++;
            }
            return(VertexCount);
        }
Exemple #3
0
        private void StoreRestPose(FBXScene pScene, FBXNode pSkeletonRoot, SkeletonAsset Skeleton)
        {
            Dictionary <String, FBBone> pose = Skeleton.ModelBones;
            FBXAMatrix lTransformMatrix = new FBXAMatrix();
            FBXVector4 lT, lR, lS;

            lS = new FBXVector4(1.0, 1.0, 1.0, 0);
            FBXPose lPose = FBXPose.Create(pScene, "A Bind Pose");

            lT = new FBXVector4();
            lR = new FBXVector4();
            lTransformMatrix.SetTRS(lT, lR, lS);
            FBXNode lKFbxNode = pSkeletonRoot;

            lPose.Add(lKFbxNode, lTransformMatrix);
            foreach (string key in pose.Keys)
            {
                FBBone     bonePose      = pose[key];
                FBXNode    fbxBone       = pSkeletonRoot.FindChild(key);
                FBXVector4 Forward       = new FBXVector4(bonePose.Forward.members[0], bonePose.Forward.members[1], bonePose.Forward.members[2], 0);
                FBXVector4 Right         = new FBXVector4(bonePose.Right.members[0], bonePose.Right.members[1], bonePose.Right.members[2], 0);
                FBXVector4 Up            = new FBXVector4(bonePose.Up.members[0], bonePose.Up.members[1], bonePose.Up.members[2], 0);
                FBXVector4 Trans         = new FBXVector4(bonePose.Location.members[0] * exportScale, bonePose.Location.members[1] * exportScale, bonePose.Location.members[2] * exportScale, 1);
                FBXAMatrix boneTransform = new FBXAMatrix();
                boneTransform.SetRow(0, Right);
                boneTransform.SetRow(1, Up);
                boneTransform.SetRow(2, Forward);
                boneTransform.SetRow(3, Trans);
                lPose.Add(fbxBone, boneTransform);
            }
            lPose.SetIsBindPose(true);
            pScene.AddPose(lPose);
        }
Exemple #4
0
        public bool ExportSkinnedMeshToFBX(SkeletonAsset skeleton, MeshAsset mesh, int lodIndex, String targetdir, bool asOne)
        {
            FBXManager lSdkManager = new FBXManager();
            FBXScene   lScene      = new FBXScene();

            FBXHelper.InitializeSdkObjects(lSdkManager, lScene);
            FBXNode SceneRoot     = lScene.GetRootNode();
            FBXNode lSkeletonRoot = CreateFbxSkeleton(skeleton, lScene);

            SceneRoot.AddChild(lSkeletonRoot);
            if (asOne)
            {
                FBXNode fbxMesh = CreateFbxMesh(mesh.lods[lodIndex], lScene);
                CreateMeshSkinning(skeleton, mesh.lods[lodIndex], fbxMesh, lSkeletonRoot, lScene);
                SceneRoot.AddChild(fbxMesh);
                StoreRestPose(lScene, lSkeletonRoot, skeleton);
            }
            else
            {
                for (int i = 0; i < mesh.lods[lodIndex].sections.Count; i++)
                {
                    FBXNode CurrentSectionMesh = CreateFbxMesh(mesh.lods[lodIndex].sections[i], lScene);
                    CreateMeshSkinning(skeleton, mesh.lods[lodIndex].sections[i], CurrentSectionMesh, lSkeletonRoot, lScene);
                    SceneRoot.AddChild(CurrentSectionMesh);
                    StoreBindPose(lScene, CurrentSectionMesh);
                }
            }
            return(SaveScene(targetdir, lSdkManager, lScene));
        }
Exemple #5
0
        public static Dictionary <string, List <VertexWeight> > GetVertexGroups(SkeletonAsset skeleton, MeshLOD lod)
        {
            var VertexGroupDict = new Dictionary <string, List <VertexWeight> >();
            int VertCount       = 0;

            foreach (var section in lod.sections)
            {
                VertCount = GetVertexGroups(skeleton, section, VertCount, ref VertexGroupDict);
            }
            return(VertexGroupDict);
        }
Exemple #6
0
 public void Apply(MeshAsset mesh, SkeletonAsset skeleton)
 {
     if (mesh != null)
     {
         ApplyMorphToMesh(mesh);
     }
     if (skeleton != null)
     {
         ApplyMorphToSkeleton(skeleton);
     }
 }
Exemple #7
0
 public void ApplyMorphToSkeleton(SkeletonAsset skeleton)
 {
     for (int i = 0; i < skeleton.Bones.Count; i++)
     {
         FBBone fbbone     = skeleton.Bones[i];
         Vector boneOffset = BonesMorph[i];
         //var tmp = fbbone.Location.members;
         fbbone.Location.members[0] += boneOffset.members[0];
         fbbone.Location.members[1] += boneOffset.members[1];
         fbbone.Location.members[2] += boneOffset.members[2];
         //fbbone.Location.members = tmp;
     }
 }
Exemple #8
0
 private void UpdateSkeletonWithMorph(SkeletonAsset Skeleton, FBXNode pSkeletonNode, List <Vector> morphBones)
 {
     for (int i = 0; i < Skeleton.Bones.Count; i++)
     {
         FBBone        fbbone     = Skeleton.Bones[i];
         FBXNode       fbxBone    = pSkeletonNode.FindChild(fbbone.Name);
         Vector        boneOffset = morphBones[i];
         List <double> tmp        = fbxBone.LclTranslation;
         tmp[0] += boneOffset.members[0] * exportScale;
         tmp[1] += boneOffset.members[1] * exportScale;
         tmp[2] += boneOffset.members[2] * exportScale;
         fbxBone.LclTranslation = tmp;
     }
 }
Exemple #9
0
        private FBXNode CreateFbxSkeleton(SkeletonAsset Skeleton, FBXScene pScene)
        {
            FBXSkeleton lSkeletonRootAttribute = FBXSkeleton.Create(pScene, "Skeleton");

            lSkeletonRootAttribute.SetSkeletonType(FBXWrapper.SkelType.eRoot);
            FBXNode lSkeletonRoot = FBXNode.Create(pScene, "Skeleton");

            lSkeletonRoot.SetNodeAttribute(lSkeletonRootAttribute);
            lSkeletonRoot.LclTranslation = new FBXVector4().ToList();
            FBXNode FbxSkeletonRootNode = CreateFbxBone(Skeleton.RootBone, pScene, lSkeletonRoot);

            lSkeletonRoot.AddChild(FbxSkeletonRootNode);
            SetBoneTransform(Skeleton, lSkeletonRoot);
            return(lSkeletonRoot);
        }
Exemple #10
0
        private void SetBoneTransform(SkeletonAsset Skeleton, FBXNode pSkeletonRoot)
        {
            Dictionary <String, FBBone> pose = Skeleton.ModelBones;

            foreach (string key in pose.Keys)
            {
                FBBone     bonePose      = pose[key];
                FBXNode    fbxBone       = pSkeletonRoot.FindChild(key);
                FBXVector4 ForwardM      = new FBXVector4(bonePose.Forward.members[0], bonePose.Forward.members[1], bonePose.Forward.members[2], 0);
                FBXVector4 RightM        = new FBXVector4(bonePose.Right.members[0], bonePose.Right.members[1], bonePose.Right.members[2], 0);
                FBXVector4 UpM           = new FBXVector4(bonePose.Up.members[0], bonePose.Up.members[1], bonePose.Up.members[2], 0);
                FBXVector4 TransM        = new FBXVector4(bonePose.Location.members[0] * exportScale, bonePose.Location.members[1] * exportScale, bonePose.Location.members[2] * exportScale, 1);
                FBXAMatrix transfoMatrix = new FBXAMatrix();
                transfoMatrix.SetRow(0, RightM);
                transfoMatrix.SetRow(1, UpM);
                transfoMatrix.SetRow(2, ForwardM);
                transfoMatrix.SetRow(3, TransM);
                FBXHelper.SetGlobalDefaultPosition(fbxBone, transfoMatrix);
            }
        }
Exemple #11
0
        private byte[] ExportPoseToPsa(SkeletonAsset Skeleton, List <Vector> bonesOffset, float OverrideScale = 1.0f)
        {
            if (Skeleton == null)
            {
                throw new ArgumentNullException("Provided skeleton was null, cannot proceed with PSA export!");
            }

            PSAFile psaFile = new PSAFile();

            psaFile.data.Bones = CreatePskSkeleton(Skeleton, OverrideScale);
            psaFile.data.Infos = new List <PSAFile.PSAAnimInfo>();
            psaFile.data.Keys  = new List <PSAFile.PSAAnimKeys>();

            PSAFile.PSAAnimInfo MorphPoseAnimInfo = new PSAFile.PSAAnimInfo();
            MorphPoseAnimInfo.name         = "FaceMorph";
            MorphPoseAnimInfo.group        = "GroupFaceMorph";
            MorphPoseAnimInfo.TotalBones   = Skeleton.Bones.Count;
            MorphPoseAnimInfo.RootInclude  = 1;
            MorphPoseAnimInfo.NumRawFrames = 1;
            MorphPoseAnimInfo.AnimRate     = 30.0f;

            psaFile.data.Infos.Add(MorphPoseAnimInfo);

            for (int i = 0; i < bonesOffset.Count; i++)
            {
                PSAFile.PSAAnimKeys boneKey = new PSAFile.PSAAnimKeys();
                boneKey.rotation = psaFile.data.Bones[i].rotation;

                Vector nBoneLocation = new Vector(new float [3]);
                nBoneLocation.members[0] = Skeleton.Bones[i].Location.members[0] + (bonesOffset[i].members[0] * OverrideScale);
                nBoneLocation.members[2] = Skeleton.Bones[i].Location.members[1] + (bonesOffset[i].members[1] * OverrideScale);
                nBoneLocation.members[1] = Skeleton.Bones[i].Location.members[2] + (bonesOffset[i].members[2] * OverrideScale);
                PSKFile.PSKPoint boneKeyLocation = new PSKFile.PSKPoint(ConvertVector3ToPsk(nBoneLocation));
                boneKey.location = boneKeyLocation;

                boneKey.time = 1;

                psaFile.data.Keys.Add(boneKey);
            }
            return(psaFile.SaveToMemory().ToArray());
        }
Exemple #12
0
        public bool ExportMeshWithMorph(SkeletonAsset Skeleton, MeshAsset mesh, int lodIndex, List <Vector> morphVertex, List <Vector> morphBones, String targetdir)
        {
            FBXManager lSdkManager = new FBXManager();
            FBXScene   lScene      = new FBXScene();

            FBXHelper.InitializeSdkObjects(lSdkManager, lScene);
            FBXNode SceneRoot = lScene.GetRootNode();
            FBXNode fbxMesh   = CreateFbxMesh(mesh.lods[lodIndex], lScene);

            AddMorphToMesh(lScene, fbxMesh, morphVertex);
            SceneRoot.AddChild(fbxMesh);
            if (Skeleton != null)
            {
                FBXNode lSkeletonRoot = CreateFbxSkeleton(Skeleton, lScene);
                CreateMeshSkinning(Skeleton, mesh.lods[lodIndex], fbxMesh, lSkeletonRoot, lScene);
                UpdateSkeletonWithMorph(Skeleton, lSkeletonRoot, morphBones);
                SceneRoot.AddChild(lSkeletonRoot);
                StoreBindPose(lScene, fbxMesh);
            }
            return(SaveScene(targetdir, lSdkManager, lScene));
        }
Exemple #13
0
        public static IMeshExporter GetExporterByExtension(string extension, SkeletonAsset skeleton = null)
        {
            IMeshExporter exporter;

            switch (extension)
            {
            case ".obj":
                exporter = new OBJExporter();
                break;

            case ".psk":
                exporter = new PSKExporter(skeleton);
                break;

            case ".fbx":
                exporter = new FBXExporter(skeleton);
                break;

            default:
                exporter = null;
                break;
            }
            return(exporter);
        }
Exemple #14
0
 private bool ExportMeshWithMorph(SkeletonAsset Skeleton, MeshAsset mesh, int lodIndex, List <Vector> morphBones, String targetdir)
 {
     return(ExportMeshWithMorph(Skeleton, mesh, lodIndex, null, morphBones, targetdir));
 }
Exemple #15
0
        private List <PSKFile.PSKBone> CreatePskSkeleton(SkeletonAsset skeleton, float OverrideScale = 1.0f)
        {
            var PskBones = new List <PSKFile.PSKBone>();

            if (skeleton != null)
            {
                for (int i = 0; i < skeleton.Bones.Count; i++)
                {
                    PSKFile.PSKBone Bone = new PSKFile.PSKBone();
                    Bone.name     = skeleton.Bones[i].Name;
                    Bone.childs   = skeleton.Bones[i].Children.Count;
                    Bone.parent   = (skeleton.Bones[i].ParentIndex == -1) ? 0 : skeleton.Bones[i].ParentIndex;
                    Bone.index    = i;
                    Bone.location = new PSKFile.PSKPoint(ConvertVector3ToPsk(skeleton.Bones[i].Location) * OverrideScale);
                    Bone.rotation = new PSKFile.PSKQuad(0, 0, 0, 0);

                    float[][] RotMatrix = new float[4][];
                    RotMatrix[0] = new float[4];
                    RotMatrix[1] = new float[4];
                    RotMatrix[2] = new float[4];
                    RotMatrix[3] = new float[4];

                    RotMatrix[0][0] = skeleton.Bones[i].Right.members[0]; RotMatrix[0][1] = skeleton.Bones[i].Right.members[1]; RotMatrix[0][2] = skeleton.Bones[i].Right.members[2]; RotMatrix[0][3] = 0.0f;
                    RotMatrix[1][0] = skeleton.Bones[i].Up.members[0]; RotMatrix[1][1] = skeleton.Bones[i].Up.members[1]; RotMatrix[1][2] = skeleton.Bones[i].Up.members[2]; RotMatrix[1][3] = 0.0f;
                    RotMatrix[2][0] = skeleton.Bones[i].Forward.members[0]; RotMatrix[2][1] = skeleton.Bones[i].Forward.members[1]; RotMatrix[2][2] = skeleton.Bones[i].Forward.members[2]; RotMatrix[2][3] = 0.0f;
                    RotMatrix[3][0] = 0.0f; RotMatrix[3][1] = 0.0f; RotMatrix[3][2] = 0.0f; RotMatrix[3][3] = 1.0f;

                    Vector Quat = new Vector(new float[4]);
                    float  tr   = RotMatrix[0][0] + RotMatrix[1][1] + RotMatrix[2][2];
                    float  s;

                    if (tr > 0.0f)
                    {
                        float InvS = 1.0f / (float)Math.Sqrt(tr + 1.0f);
                        Quat.members[3] = 0.5f * (1.0f / InvS);
                        s = 0.5f * InvS;

                        Quat.members[0] = (RotMatrix[1][2] - RotMatrix[2][1]) * s;
                        Quat.members[1] = (RotMatrix[2][0] - RotMatrix[0][2]) * s;
                        Quat.members[2] = (RotMatrix[0][1] - RotMatrix[1][0]) * s;
                    }
                    else
                    {
                        int m = 0;
                        if (RotMatrix[1][1] > RotMatrix[0][0])
                        {
                            m = 1;
                        }

                        if (RotMatrix[2][2] > RotMatrix[m][m])
                        {
                            m = 2;
                        }

                        int[] nxt = new int[] { 1, 2, 0 };
                        int   j   = nxt[m];
                        int   k   = nxt[j];

                        s = RotMatrix[m][m] - RotMatrix[j][j] - RotMatrix[k][k] + 1.0f;
                        float InvS = 1.0f / (float)Math.Sqrt(s);

                        float[] qt = new float[4];
                        qt[m] = 0.5f * (1.0f / InvS);
                        s     = 0.5f * InvS;

                        qt[3] = (RotMatrix[j][k] - RotMatrix[k][j]) * s;
                        qt[j] = (RotMatrix[m][j] + RotMatrix[j][m]) * s;
                        qt[k] = (RotMatrix[m][k] + RotMatrix[k][m]) * s;

                        Quat.members[0] = qt[0];
                        Quat.members[1] = qt[1];
                        Quat.members[2] = qt[2];
                        Quat.members[3] = qt[3];
                    }

                    Bone.rotation = new PSKFile.PSKQuad(ConvertVector4ToPsk(Quat));
                    PskBones.Add(Bone);
                }
            }
            return(PskBones);
        }
Exemple #16
0
 protected ASkinnedMeshExporter(SkeletonAsset _skel)
 {
     Skeleton = _skel;
 }
Exemple #17
0
        // export given LOD to psk
        private byte[] ExportSkinnedMeshToPsk(SkeletonAsset skeleton, MeshLOD LOD, float OverrideScale = 1.0f)
        {
            PSKFile Psk = new PSKFile();

            Psk.points    = new List <PSKFile.PSKPoint>();
            Psk.edges     = new List <PSKFile.PSKEdge>();
            Psk.materials = new List <PSKFile.PSKMaterial>();
            Psk.bones     = new List <PSKFile.PSKBone>();
            Psk.faces     = new List <PSKFile.PSKFace>();
            Psk.weights   = new List <PSKFile.PSKWeight>();

            // create skeleton (only if mesh is skinned mesh)
            if (LOD.type == MeshType.MeshType_Skinned)
            {
                Psk.bones = CreatePskSkeleton(skeleton, OverrideScale);
            }

            // create mesh
            int offset = 0;
            int matIdx = 0;

            for (int bufIdx = 0; bufIdx < LOD.sections.Count; bufIdx++)
            {
                MeshLodSection MeshBuffer = LOD.sections[bufIdx];
                for (int i = 0; i < MeshBuffer.vertices.Count; i++)
                {
                    // vertex position
                    if (MeshBuffer.vertices[i].position.members.Length != 3)
                    {
                        MeshBuffer.vertices[i].position.members = new float[3];
                    }
                    Vector p = new Vector(MeshBuffer.vertices[i].position.members[0] * OverrideScale, MeshBuffer.vertices[i].position.members[1] * OverrideScale, MeshBuffer.vertices[i].position.members[2] * OverrideScale);
                    Psk.points.Add(new PSKFile.PSKPoint(ConvertVector3ToPsk(p)));

                    // vertex uv
                    // supports only first uv for the time being
                    // TODO support for multiple UVs
                    if (MeshBuffer.vertices[i].texCoords[0] == null)
                    {
                        MeshBuffer.vertices[i].texCoords[0] = new Vector(new float[2]);
                    }
                    if (MeshBuffer.vertices[i].texCoords[0].members.Length != 2)
                    {
                        MeshBuffer.vertices[i].texCoords[0].members = new float[2];
                    }
                    Vector tc = new Vector(MeshBuffer.vertices[i].texCoords[0].members[0], MeshBuffer.vertices[i].texCoords[0].members[1]);
                    Psk.edges.Add(new PSKFile.PSKEdge((ushort)(offset + i), ConvertVector2ToPsk(tc), (byte)matIdx));

                    // bones weights
                    if (MeshBuffer.vertices[i].boneWeights != null)
                    {
                        for (int x = 0; x < 4; x++)
                        {
                            float Weight = MeshBuffer.vertices[i].boneWeights[x];

                            // only add meaningful weights
                            if (Weight != 0.0f)
                            {
                                int BoneIndex = MeshBuffer.vertices[i].boneIndices[x];

                                int SubObjectBoneIndex = MeshBuffer.boneIndices[BoneIndex];
                                Psk.weights.Add(new PSKFile.PSKWeight(
                                                    Weight,
                                                    (int)(offset + i),
                                                    SubObjectBoneIndex
                                                    ));
                            }
                        }
                    }
                }

                // reverse indices order before building faces: necessary for correct normal building since all points have been mirrored along z-axis.
                // if this is not done, all normals are flipped inside.
                if (Reverse)
                {
                    MeshBuffer.indicies.Reverse();
                }
                for (int fi = 0; fi < MeshBuffer.indicies.Count; fi++)
                {
                    if (fi % 3 == 0)
                    {
                        Psk.faces.Add(new PSKFile.PSKFace(
                                          (int)(offset + MeshBuffer.indicies[fi]),
                                          (int)(offset + MeshBuffer.indicies[fi + 1]),
                                          (int)(offset + MeshBuffer.indicies[fi + 2]),
                                          (byte)matIdx)
                                      );
                    }
                }
                Psk.materials.Add(new PSKFile.PSKMaterial(LOD.sections[bufIdx].matName, matIdx));

                offset += (int)LOD.sections[bufIdx].vertCount;
                matIdx++;
            }
            return(Psk.SaveToMemory().ToArray());
        }
Exemple #18
0
 public bool ExportSkinnedMeshToFBX(SkeletonAsset skeleton, MeshAsset mesh, int lodIndex, String targetdir)
 {
     return(ExportSkinnedMeshToFBX(skeleton, mesh, lodIndex, targetdir, false));
 }
Exemple #19
0
 public PSKExporter(SkeletonAsset skel)
     : base(skel)
 {
 }
Exemple #20
0
        // export given LOD to psk
        private byte[] ExportSkinnedMeshToPsk(SkeletonAsset skeleton, MeshLOD LOD, float OverrideScale = 1.0f)
        {
            PSKFile Psk = new PSKFile();

            Psk.points    = new List <PSKFile.PSKPoint>();
            Psk.edges     = new List <PSKFile.PSKEdge>();
            Psk.materials = new List <PSKFile.PSKMaterial>();
            Psk.bones     = new List <PSKFile.PSKBone>();
            Psk.faces     = new List <PSKFile.PSKFace>();
            Psk.weights   = new List <PSKFile.PSKWeight>();

            /* No skeleton defined still */
            if (skeleton != null)
            {
                for (int i = 0; i < skeleton.Bones.Count; i++)
                {
                    PSKFile.PSKBone Bone = new PSKFile.PSKBone();
                    Bone.name     = skeleton.Bones[i].Name;
                    Bone.childs   = skeleton.Bones[i].Children.Count;
                    Bone.parent   = (skeleton.Bones[i].ParentIndex == -1) ? 0 : skeleton.Bones[i].ParentIndex;
                    Bone.index    = i;
                    Bone.location = new PSKFile.PSKPoint(ConvertVector3ToPsk(skeleton.Bones[i].Location) * OverrideScale);
                    Bone.rotation = new PSKFile.PSKQuad(0, 0, 0, 0);

                    float[][] RotMatrix = new float[4][];
                    RotMatrix[0] = new float[4];
                    RotMatrix[1] = new float[4];
                    RotMatrix[2] = new float[4];
                    RotMatrix[3] = new float[4];

                    RotMatrix[0][0] = skeleton.Bones[i].Right.members[0];   RotMatrix[0][1] = skeleton.Bones[i].Right.members[1];   RotMatrix[0][2] = skeleton.Bones[i].Right.members[2];   RotMatrix[0][3] = 0.0f;
                    RotMatrix[1][0] = skeleton.Bones[i].Up.members[0];      RotMatrix[1][1] = skeleton.Bones[i].Up.members[1];      RotMatrix[1][2] = skeleton.Bones[i].Up.members[2];      RotMatrix[1][3] = 0.0f;
                    RotMatrix[2][0] = skeleton.Bones[i].Forward.members[0]; RotMatrix[2][1] = skeleton.Bones[i].Forward.members[1]; RotMatrix[2][2] = skeleton.Bones[i].Forward.members[2]; RotMatrix[2][3] = 0.0f;
                    RotMatrix[3][0] = 0.0f;                                 RotMatrix[3][1] = 0.0f;                                 RotMatrix[3][2] = 0.0f;                                 RotMatrix[3][3] = 1.0f;

                    Vector Quat = new Vector(new float[4]);
                    float  tr   = RotMatrix[0][0] + RotMatrix[1][1] + RotMatrix[2][2];
                    float  s;

                    if (tr > 0.0f)
                    {
                        float InvS = 1.0f / (float)Math.Sqrt(tr + 1.0f);
                        Quat.members[3] = 0.5f * (1.0f / InvS);
                        s = 0.5f * InvS;

                        Quat.members[0] = (RotMatrix[1][2] - RotMatrix[2][1]) * s;
                        Quat.members[1] = (RotMatrix[2][0] - RotMatrix[0][2]) * s;
                        Quat.members[2] = (RotMatrix[0][1] - RotMatrix[1][0]) * s;
                    }
                    else
                    {
                        int m = 0;
                        if (RotMatrix[1][1] > RotMatrix[0][0])
                        {
                            m = 1;
                        }

                        if (RotMatrix[2][2] > RotMatrix[m][m])
                        {
                            m = 2;
                        }

                        int[] nxt = new int[] { 1, 2, 0 };
                        int   j   = nxt[m];
                        int   k   = nxt[j];

                        s = RotMatrix[m][m] - RotMatrix[j][j] - RotMatrix[k][k] + 1.0f;
                        float InvS = 1.0f / (float)Math.Sqrt(s);

                        float[] qt = new float[4];
                        qt[m] = 0.5f * (1.0f / InvS);
                        s     = 0.5f * InvS;

                        qt[3] = (RotMatrix[j][k] - RotMatrix[k][j]) * s;
                        qt[j] = (RotMatrix[m][j] + RotMatrix[j][m]) * s;
                        qt[k] = (RotMatrix[m][k] + RotMatrix[k][m]) * s;

                        Quat.members[0] = qt[0];
                        Quat.members[1] = qt[1];
                        Quat.members[2] = qt[2];
                        Quat.members[3] = qt[3];
                    }

                    Bone.rotation = new PSKFile.PSKQuad(ConvertVector4ToPsk(Quat));
                    Psk.bones.Add(Bone);
                }
            }
            int offset = 0;
            int matIdx = 0;

            for (int bufIdx = 0; bufIdx < LOD.sections.Count; bufIdx++)
            {
                MeshLodSection MeshBuffer = LOD.sections[bufIdx];
                for (int i = 0; i < MeshBuffer.vertices.Count; i++)
                {
                    if (MeshBuffer.vertices[i].position.members.Length != 3)
                    {
                        MeshBuffer.vertices[i].position.members = new float[3];
                    }
                    if (MeshBuffer.vertices[i].texCoords.members.Length != 2)
                    {
                        MeshBuffer.vertices[i].texCoords.members = new float[2];
                    }
                    Vector p = new Vector(MeshBuffer.vertices[i].position.members[0], MeshBuffer.vertices[i].position.members[1], MeshBuffer.vertices[i].position.members[2]);
                    Psk.points.Add(new PSKFile.PSKPoint(ConvertVector3ToPsk(p)));
                    Vector tc = new Vector(MeshBuffer.vertices[i].texCoords.members[0], MeshBuffer.vertices[i].texCoords.members[1]);
                    Psk.edges.Add(new PSKFile.PSKEdge((ushort)(offset + i), ConvertVector2ToPsk(tc), (byte)matIdx));
                    if (MeshBuffer.vertices[i].boneWeights != null)
                    {
                        for (int x = 0; x < 4; x++)
                        {
                            float Weight = MeshBuffer.vertices[i].boneWeights[x];

                            // only add meaningful weights
                            if (Weight != 0.0f)
                            {
                                int BoneIndex = MeshBuffer.vertices[i].boneIndices[x];

                                int SubObjectBoneIndex = MeshBuffer.boneIndices[BoneIndex];
                                Psk.weights.Add(new PSKFile.PSKWeight(
                                                    Weight,
                                                    (int)(offset + i),
                                                    SubObjectBoneIndex
                                                    ));
                            }
                        }
                    }
                }

                // reverse indices order before building faces: necessary for correct normal building since all points have been mirrored along z-axis.
                // if this is not done, all normals are flipped inside.
                if (Reverse)
                {
                    MeshBuffer.indicies.Reverse();
                }
                for (int fi = 0; fi < MeshBuffer.indicies.Count; fi++)
                {
                    if (fi % 3 == 0)
                    {
                        Psk.faces.Add(new PSKFile.PSKFace(
                                          (int)(offset + MeshBuffer.indicies[fi]),
                                          (int)(offset + MeshBuffer.indicies[fi + 1]),
                                          (int)(offset + MeshBuffer.indicies[fi + 2]),
                                          (byte)matIdx)
                                      );
                    }
                }
                Psk.materials.Add(new PSKFile.PSKMaterial(LOD.sections[bufIdx].matName, matIdx));

                offset += (int)LOD.sections[bufIdx].vertCount;
                matIdx++;
            }
            return(Psk.SaveToMemory().ToArray());
        }
Exemple #21
0
        private void CreateMeshSkinning(SkeletonAsset Skeleton, MeshLodSection section, FBXNode pFbxMesh, FBXNode pSkeletonRoot, FBXScene pScene)
        {
            Dictionary <string, List <VertexGroup.VertexWeight> > vg = VertexGroup.GetVertexGroups(Skeleton, section);

            CreateMeshSkinning(vg, pFbxMesh, pSkeletonRoot, pScene);
        }
Exemple #22
0
 public FBXExporter(SkeletonAsset skel) : base(skel)
 {
 }