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); }
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); }
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); }
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)); }
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); }
public void Apply(MeshAsset mesh, SkeletonAsset skeleton) { if (mesh != null) { ApplyMorphToMesh(mesh); } if (skeleton != null) { ApplyMorphToSkeleton(skeleton); } }
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; } }
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; } }
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); }
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); } }
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()); }
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)); }
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); }
private bool ExportMeshWithMorph(SkeletonAsset Skeleton, MeshAsset mesh, int lodIndex, List <Vector> morphBones, String targetdir) { return(ExportMeshWithMorph(Skeleton, mesh, lodIndex, null, morphBones, targetdir)); }
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); }
protected ASkinnedMeshExporter(SkeletonAsset _skel) { Skeleton = _skel; }
// 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()); }
public bool ExportSkinnedMeshToFBX(SkeletonAsset skeleton, MeshAsset mesh, int lodIndex, String targetdir) { return(ExportSkinnedMeshToFBX(skeleton, mesh, lodIndex, targetdir, false)); }
public PSKExporter(SkeletonAsset skel) : base(skel) { }
// 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()); }
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); }
public FBXExporter(SkeletonAsset skel) : base(skel) { }