More exporting fixes
This commit is contained in:
parent
48814b4643
commit
fc7f208af6
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -618,12 +618,7 @@ namespace Bfres.Structs
|
|||||||
public void Export(object sender, EventArgs args)
|
public void Export(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
SaveFileDialog sfd = new SaveFileDialog();
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
sfd.Filter = "Supported Formats|*.bfobj;*.fbx;*.dae; *.obj;|" +
|
sfd.Filter = FileFilters.FSHP;
|
||||||
"Bfres Object (shape/vertices) |*.bfobj|" +
|
|
||||||
"FBX |*.fbx|" +
|
|
||||||
"DAE |*.dae|" +
|
|
||||||
"OBJ |*.obj|" +
|
|
||||||
"All files(*.*)|*.*";
|
|
||||||
sfd.DefaultExt = ".bfobj";
|
sfd.DefaultExt = ".bfobj";
|
||||||
sfd.FileName = Text;
|
sfd.FileName = Text;
|
||||||
|
|
||||||
@ -637,9 +632,12 @@ namespace Bfres.Structs
|
|||||||
case ".bfobj":
|
case ".bfobj":
|
||||||
ExportBinaryObject(sfd.FileName);
|
ExportBinaryObject(sfd.FileName);
|
||||||
break;
|
break;
|
||||||
|
case ".obj":
|
||||||
|
OBJ.ExportMesh(sfd.FileName, this);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
AssimpSaver assimp = new AssimpSaver();
|
AssimpSaver assimp = new AssimpSaver();
|
||||||
assimp.SaveFromObject(vertices, lodMeshes[DisplayLODIndex].faces, Text, sfd.FileName);
|
assimp.SaveFromObject(this, sfd.FileName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -21,7 +21,11 @@ namespace Switch_Toolbox.Library
|
|||||||
SaveSkeleton(skeleton, scene.RootNode);
|
SaveSkeleton(skeleton, scene.RootNode);
|
||||||
SaveMaterials(scene, model, FileName, Textures);
|
SaveMaterials(scene, model, FileName, Textures);
|
||||||
SaveMeshes(scene, model, skeleton, FileName, NodeArray);
|
SaveMeshes(scene, model, skeleton, FileName, NodeArray);
|
||||||
|
SaveScene(FileName, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveScene(string FileName, Scene scene)
|
||||||
|
{
|
||||||
using (var v = new AssimpContext())
|
using (var v = new AssimpContext())
|
||||||
{
|
{
|
||||||
string ext = System.IO.Path.GetExtension(FileName);
|
string ext = System.IO.Path.GetExtension(FileName);
|
||||||
@ -40,8 +44,6 @@ namespace Switch_Toolbox.Library
|
|||||||
MessageBox.Show($"Exported {FileName} Successfuly!");
|
MessageBox.Show($"Exported {FileName} Successfuly!");
|
||||||
else
|
else
|
||||||
MessageBox.Show($"Failed to export {FileName}!");
|
MessageBox.Show($"Failed to export {FileName}!");
|
||||||
|
|
||||||
Scene newScene = v.ImportFile(FileName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,80 +52,8 @@ namespace Switch_Toolbox.Library
|
|||||||
int MeshIndex = 0;
|
int MeshIndex = 0;
|
||||||
foreach (var obj in model.Nodes[0].Nodes)
|
foreach (var obj in model.Nodes[0].Nodes)
|
||||||
{
|
{
|
||||||
var genericObj = (STGenericObject)obj;
|
var mesh = SaveMesh((STGenericObject)obj, skeleton, NodeArray);
|
||||||
|
|
||||||
Mesh mesh = new Mesh(genericObj.Text, PrimitiveType.Triangle);
|
|
||||||
mesh.MaterialIndex = genericObj.MaterialIndex;
|
|
||||||
|
|
||||||
List<Vector3D> textureCoords0 = new List<Vector3D>();
|
|
||||||
List<Vector3D> textureCoords1 = new List<Vector3D>();
|
|
||||||
List<Vector3D> textureCoords2 = new List<Vector3D>();
|
|
||||||
List<Color4D> vertexColors = new List<Color4D>();
|
|
||||||
|
|
||||||
int vertexID = 0;
|
|
||||||
foreach (Vertex v in genericObj.vertices)
|
|
||||||
{
|
|
||||||
mesh.Vertices.Add(new Vector3D(v.pos.X, v.pos.Y, v.pos.Z));
|
|
||||||
mesh.Normals.Add(new Vector3D(v.nrm.X, v.nrm.Y, v.nrm.Z));
|
|
||||||
textureCoords0.Add(new Vector3D(v.uv0.X, v.uv0.Y, 0));
|
|
||||||
textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0));
|
|
||||||
textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0));
|
|
||||||
vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W));
|
|
||||||
mesh.TextureCoordinateChannels[0] = textureCoords0;
|
|
||||||
mesh.TextureCoordinateChannels[1] = textureCoords1;
|
|
||||||
mesh.TextureCoordinateChannels[2] = textureCoords2;
|
|
||||||
mesh.VertexColorChannels[0] = vertexColors;
|
|
||||||
|
|
||||||
for (int j = 0; j < v.boneIds.Count; j++)
|
|
||||||
{
|
|
||||||
if (j < genericObj.VertexSkinCount)
|
|
||||||
{
|
|
||||||
//Get the bone via the node array and bone index from the vertex
|
|
||||||
STBone STbone = skeleton.bones[NodeArray[v.boneIds[j]]];
|
|
||||||
|
|
||||||
//Find the index of a bone. If it doesn't exist then we add it
|
|
||||||
int boneInd = mesh.Bones.FindIndex(x => x.Name == STbone.Text);
|
|
||||||
|
|
||||||
if (boneInd == -1)
|
|
||||||
{
|
|
||||||
var matrices = Switch_Toolbox.Library.IO.MatrixExenstion.CalculateInverseMatrix(STbone);
|
|
||||||
|
|
||||||
//Set the inverse matrix
|
|
||||||
Matrix4x4 transform = matrices.inverse.FromNumerics();
|
|
||||||
|
|
||||||
//Create a new assimp bone
|
|
||||||
Bone bone = new Bone();
|
|
||||||
bone.Name = STbone.Text;
|
|
||||||
bone.OffsetMatrix = transform;
|
|
||||||
|
|
||||||
mesh.Bones.Add(bone);
|
|
||||||
BoneNames.Add(bone.Name);
|
|
||||||
|
|
||||||
boneInd = mesh.Bones.IndexOf(bone); //Set the index of the bone for the vertex weight
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check if the max amount of weights is higher than the current bone id
|
|
||||||
if (v.boneWeights.Count > j && v.boneWeights[j] > 0)
|
|
||||||
{
|
|
||||||
if (v.boneWeights[j] <= 1)
|
|
||||||
mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, v.boneWeights[j]));
|
|
||||||
else
|
|
||||||
mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, 1));
|
|
||||||
}
|
|
||||||
else if (v.boneWeights.Count == 0 || v.boneWeights[j] > 0)
|
|
||||||
mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vertexID++;
|
|
||||||
}
|
|
||||||
List<int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces;
|
|
||||||
for (int f = 0; f < faces.Count; f++)
|
|
||||||
mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] }));
|
|
||||||
|
|
||||||
mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0);
|
|
||||||
|
|
||||||
scene.Meshes.Add(mesh);
|
scene.Meshes.Add(mesh);
|
||||||
|
|
||||||
MeshIndex++;
|
MeshIndex++;
|
||||||
}
|
}
|
||||||
Node geomNode = new Node(Path.GetFileNameWithoutExtension(FileName), scene.RootNode);
|
Node geomNode = new Node(Path.GetFileNameWithoutExtension(FileName), scene.RootNode);
|
||||||
@ -135,6 +65,81 @@ namespace Switch_Toolbox.Library
|
|||||||
scene.RootNode.Children.Add(geomNode);
|
scene.RootNode.Children.Add(geomNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Mesh SaveMesh(STGenericObject genericObj, STSkeleton skeleton, List<int> NodeArray)
|
||||||
|
{
|
||||||
|
Mesh mesh = new Mesh(genericObj.Text, PrimitiveType.Triangle);
|
||||||
|
mesh.MaterialIndex = genericObj.MaterialIndex;
|
||||||
|
|
||||||
|
List<Vector3D> textureCoords0 = new List<Vector3D>();
|
||||||
|
List<Vector3D> textureCoords1 = new List<Vector3D>();
|
||||||
|
List<Vector3D> textureCoords2 = new List<Vector3D>();
|
||||||
|
List<Color4D> vertexColors = new List<Color4D>();
|
||||||
|
|
||||||
|
int vertexID = 0;
|
||||||
|
foreach (Vertex v in genericObj.vertices)
|
||||||
|
{
|
||||||
|
mesh.Vertices.Add(new Vector3D(v.pos.X, v.pos.Y, v.pos.Z));
|
||||||
|
mesh.Normals.Add(new Vector3D(v.nrm.X, v.nrm.Y, v.nrm.Z));
|
||||||
|
textureCoords0.Add(new Vector3D(v.uv0.X, v.uv0.Y, 0));
|
||||||
|
textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0));
|
||||||
|
textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0));
|
||||||
|
vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W));
|
||||||
|
mesh.TextureCoordinateChannels[0] = textureCoords0;
|
||||||
|
mesh.TextureCoordinateChannels[1] = textureCoords1;
|
||||||
|
mesh.TextureCoordinateChannels[2] = textureCoords2;
|
||||||
|
mesh.VertexColorChannels[0] = vertexColors;
|
||||||
|
|
||||||
|
for (int j = 0; j < v.boneIds.Count; j++)
|
||||||
|
{
|
||||||
|
if (j < genericObj.VertexSkinCount)
|
||||||
|
{
|
||||||
|
//Get the bone via the node array and bone index from the vertex
|
||||||
|
STBone STbone = skeleton.bones[NodeArray[v.boneIds[j]]];
|
||||||
|
|
||||||
|
//Find the index of a bone. If it doesn't exist then we add it
|
||||||
|
int boneInd = mesh.Bones.FindIndex(x => x.Name == STbone.Text);
|
||||||
|
|
||||||
|
if (boneInd == -1)
|
||||||
|
{
|
||||||
|
var matrices = Switch_Toolbox.Library.IO.MatrixExenstion.CalculateInverseMatrix(STbone);
|
||||||
|
|
||||||
|
//Set the inverse matrix
|
||||||
|
Matrix4x4 transform = matrices.inverse.FromNumerics();
|
||||||
|
|
||||||
|
//Create a new assimp bone
|
||||||
|
Bone bone = new Bone();
|
||||||
|
bone.Name = STbone.Text;
|
||||||
|
bone.OffsetMatrix = transform;
|
||||||
|
|
||||||
|
mesh.Bones.Add(bone);
|
||||||
|
BoneNames.Add(bone.Name);
|
||||||
|
|
||||||
|
boneInd = mesh.Bones.IndexOf(bone); //Set the index of the bone for the vertex weight
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if the max amount of weights is higher than the current bone id
|
||||||
|
if (v.boneWeights.Count > j && v.boneWeights[j] > 0)
|
||||||
|
{
|
||||||
|
if (v.boneWeights[j] <= 1)
|
||||||
|
mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, v.boneWeights[j]));
|
||||||
|
else
|
||||||
|
mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, 1));
|
||||||
|
}
|
||||||
|
else if (v.boneWeights.Count == 0 || v.boneWeights[j] > 0)
|
||||||
|
mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vertexID++;
|
||||||
|
}
|
||||||
|
List<int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces;
|
||||||
|
for (int f = 0; f < faces.Count; f++)
|
||||||
|
mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] }));
|
||||||
|
|
||||||
|
mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0);
|
||||||
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
private void SaveMaterials(Scene scene, STGenericModel model, string FileName, List<STGenericTexture> Textures)
|
private void SaveMaterials(Scene scene, STGenericModel model, string FileName, List<STGenericTexture> Textures)
|
||||||
{
|
{
|
||||||
string TextureExtension = ".png";
|
string TextureExtension = ".png";
|
||||||
@ -222,48 +227,20 @@ namespace Switch_Toolbox.Library
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveFromObject(List<Vertex> vertices, List<int> faces, string MeshName, string FileName)
|
public void SaveFromObject(STGenericObject genericObject, string FileName)
|
||||||
{
|
{
|
||||||
Scene scene = new Scene();
|
Scene scene = new Scene();
|
||||||
scene.RootNode = new Node("Root");
|
scene.RootNode = new Node("Root");
|
||||||
|
|
||||||
Mesh mesh = new Mesh(MeshName, PrimitiveType.Triangle);
|
var mesh = SaveMesh(genericObject, null, null);
|
||||||
|
|
||||||
List<Vector3D> textureCoords0 = new List<Vector3D>();
|
|
||||||
List<Vector3D> textureCoords1 = new List<Vector3D>();
|
|
||||||
List<Vector3D> textureCoords2 = new List<Vector3D>();
|
|
||||||
List<Color4D> vertexColors = new List<Color4D>();
|
|
||||||
|
|
||||||
foreach (Vertex v in vertices)
|
|
||||||
{
|
|
||||||
mesh.Vertices.Add(new Vector3D(v.pos.X, v.pos.Y, v.pos.Z));
|
|
||||||
mesh.Normals.Add(new Vector3D(v.nrm.X, v.nrm.Y, v.nrm.Z));
|
|
||||||
textureCoords0.Add(new Vector3D(v.uv0.X, v.uv0.Y, 0));
|
|
||||||
textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0));
|
|
||||||
textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0));
|
|
||||||
vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W));
|
|
||||||
mesh.TextureCoordinateChannels[0] = textureCoords0;
|
|
||||||
mesh.TextureCoordinateChannels[1] = textureCoords1;
|
|
||||||
mesh.TextureCoordinateChannels[2] = textureCoords2;
|
|
||||||
mesh.VertexColorChannels[0] = vertexColors;
|
|
||||||
}
|
|
||||||
for (int f = 0; f < faces.Count; f++)
|
|
||||||
{
|
|
||||||
mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] }));
|
|
||||||
}
|
|
||||||
mesh.MaterialIndex = 0;
|
mesh.MaterialIndex = 0;
|
||||||
|
|
||||||
mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0);
|
|
||||||
scene.Meshes.Add(mesh);
|
scene.Meshes.Add(mesh);
|
||||||
|
|
||||||
Material material = new Material();
|
Material material = new Material();
|
||||||
material.Name = "NewMaterial";
|
material.Name = "NewMaterial";
|
||||||
scene.Materials.Add(material);
|
scene.Materials.Add(material);
|
||||||
|
|
||||||
using (var v = new AssimpContext())
|
SaveScene(FileName, scene);
|
||||||
{
|
|
||||||
v.ExportFile(scene, FileName, "obj");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveSkeleton(STSkeleton skeleton, Node parentNode)
|
private void SaveSkeleton(STSkeleton skeleton, Node parentNode)
|
||||||
|
@ -24,6 +24,17 @@ namespace Switch_Toolbox.Library
|
|||||||
File.WriteAllText(fileMtlPath, writerMtl.ToString());
|
File.WriteAllText(fileMtlPath, writerMtl.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ExportMesh(string FileName, STGenericObject genericMesh)
|
||||||
|
{
|
||||||
|
string fileNoExt = Path.GetFileNameWithoutExtension(FileName);
|
||||||
|
string fileMtlPath = FileName.Replace("obj", "mtl");
|
||||||
|
|
||||||
|
//Write mesh
|
||||||
|
StringBuilder writer = new StringBuilder();
|
||||||
|
SaveMesh(writer, genericMesh, null, 0);
|
||||||
|
File.WriteAllText(FileName, writer.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
private static void SaveMeshes(StringBuilder writer, STGenericModel Model, string MtlName)
|
private static void SaveMeshes(StringBuilder writer, STGenericModel Model, string MtlName)
|
||||||
{
|
{
|
||||||
writer.AppendLine($"mtllib {MtlName}");
|
writer.AppendLine($"mtllib {MtlName}");
|
||||||
@ -31,36 +42,41 @@ namespace Switch_Toolbox.Library
|
|||||||
int VertexCount = 1;
|
int VertexCount = 1;
|
||||||
foreach (STGenericObject mesh in Model.Nodes[0].Nodes)
|
foreach (STGenericObject mesh in Model.Nodes[0].Nodes)
|
||||||
{
|
{
|
||||||
writer.AppendLine($"o {mesh.Text}");
|
|
||||||
writer.AppendLine($"g {mesh.Text}");
|
|
||||||
|
|
||||||
foreach (var v in mesh.vertices)
|
|
||||||
{
|
|
||||||
writer.AppendLine($"v {v.pos.X} {v.pos.Y} {v.pos.Z}");
|
|
||||||
writer.AppendLine($"vn {v.nrm.X} {v.nrm.Y} {v.nrm.Z}");
|
|
||||||
writer.AppendLine($"vt {v.uv0.X} {v.uv0.Y}");
|
|
||||||
}
|
|
||||||
var mat = GetMaterial(mesh.MaterialIndex, Model);
|
var mat = GetMaterial(mesh.MaterialIndex, Model);
|
||||||
|
SaveMesh(writer, mesh, mat, VertexCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mat != null)
|
private static void SaveMesh(StringBuilder writer, STGenericObject mesh, STGenericMaterial mat, int VertexCount)
|
||||||
writer.AppendLine($"usemtl {mat.Text}");
|
{
|
||||||
|
writer.AppendLine($"o {mesh.Text}");
|
||||||
|
writer.AppendLine($"g {mesh.Text}");
|
||||||
|
|
||||||
for (int i = 0; i < mesh.faces.Count; i++)
|
foreach (var v in mesh.vertices)
|
||||||
|
{
|
||||||
|
writer.AppendLine($"v {v.pos.X} {v.pos.Y} {v.pos.Z}");
|
||||||
|
writer.AppendLine($"vn {v.nrm.X} {v.nrm.Y} {v.nrm.Z}");
|
||||||
|
writer.AppendLine($"vt {v.uv0.X} {v.uv0.Y}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mat != null)
|
||||||
|
writer.AppendLine($"usemtl {mat.Text}");
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh.faces.Count; i++)
|
||||||
|
{
|
||||||
|
int[] indices = new int[3]
|
||||||
{
|
{
|
||||||
int[] indices = new int[3]
|
|
||||||
{
|
|
||||||
mesh.faces[i++],
|
mesh.faces[i++],
|
||||||
mesh.faces[i++],
|
mesh.faces[i++],
|
||||||
mesh.faces[i]
|
mesh.faces[i]
|
||||||
};
|
};
|
||||||
|
|
||||||
writer.AppendLine($"f {indices[0] + VertexCount}/{indices[0] + VertexCount}/{indices[0] + VertexCount}" +
|
writer.AppendLine($"f {indices[0] + VertexCount}/{indices[0] + VertexCount}/{indices[0] + VertexCount}" +
|
||||||
$" {indices[1] + VertexCount}/{indices[1] + VertexCount}/{indices[1] + VertexCount}" +
|
$" {indices[1] + VertexCount}/{indices[1] + VertexCount}/{indices[1] + VertexCount}" +
|
||||||
$" {indices[2] + VertexCount}/{indices[2] + VertexCount}/{indices[2] + VertexCount}");
|
$" {indices[2] + VertexCount}/{indices[2] + VertexCount}/{indices[2] + VertexCount}");
|
||||||
}
|
|
||||||
|
|
||||||
VertexCount += mesh.vertices.Count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VertexCount += mesh.vertices.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static STGenericMaterial GetMaterial(int MaterialIndex, STGenericModel Model)
|
private static STGenericMaterial GetMaterial(int MaterialIndex, STGenericModel Model)
|
||||||
|
Loading…
Reference in New Issue
Block a user